diff options
-rw-r--r-- | vnet/vnet/ipsec/esp.h | 126 | ||||
-rw-r--r-- | vnet/vnet/ipsec/esp_decrypt.c | 602 | ||||
-rw-r--r-- | vnet/vnet/ipsec/esp_encrypt.c | 572 | ||||
-rw-r--r-- | vnet/vnet/ipsec/ikev2.c | 2418 | ||||
-rw-r--r-- | vnet/vnet/ipsec/ikev2.h | 177 | ||||
-rw-r--r-- | vnet/vnet/ipsec/ikev2_cli.c | 354 | ||||
-rw-r--r-- | vnet/vnet/ipsec/ikev2_crypto.c | 1088 | ||||
-rw-r--r-- | vnet/vnet/ipsec/ikev2_format.c | 104 | ||||
-rw-r--r-- | vnet/vnet/ipsec/ikev2_payload.c | 615 | ||||
-rw-r--r-- | vnet/vnet/ipsec/ikev2_priv.h | 270 | ||||
-rw-r--r-- | vnet/vnet/ipsec/ipsec.c | 292 | ||||
-rw-r--r-- | vnet/vnet/ipsec/ipsec.h | 266 | ||||
-rw-r--r-- | vnet/vnet/ipsec/ipsec_cli.c | 551 | ||||
-rw-r--r-- | vnet/vnet/ipsec/ipsec_format.c | 54 | ||||
-rw-r--r-- | vnet/vnet/ipsec/ipsec_if.c | 188 | ||||
-rw-r--r-- | vnet/vnet/ipsec/ipsec_if_in.c | 128 | ||||
-rw-r--r-- | vnet/vnet/ipsec/ipsec_if_out.c | 105 | ||||
-rw-r--r-- | vnet/vnet/ipsec/ipsec_input.c | 472 | ||||
-rw-r--r-- | vnet/vnet/ipsec/ipsec_output.c | 481 |
19 files changed, 4694 insertions, 4169 deletions
diff --git a/vnet/vnet/ipsec/esp.h b/vnet/vnet/ipsec/esp.h index 2334dc48bc5..505d34ad859 100644 --- a/vnet/vnet/ipsec/esp.h +++ b/vnet/vnet/ipsec/esp.h @@ -20,137 +20,153 @@ #include <openssl/rand.h> #include <openssl/evp.h> -typedef struct { +typedef struct +{ u32 spi; u32 seq; u8 data[0]; } esp_header_t; -typedef struct { +typedef struct +{ u8 pad_length; u8 next_header; } esp_footer_t; +/* *INDENT-OFF* */ typedef CLIB_PACKED (struct { ip4_header_t ip4; esp_header_t esp; }) ip4_and_esp_header_t; +/* *INDENT-ON* */ +/* *INDENT-OFF* */ typedef CLIB_PACKED (struct { ip6_header_t ip6; esp_header_t esp; }) ip6_and_esp_header_t; +/* *INDENT-ON* */ -typedef struct { - const EVP_CIPHER * type; +typedef struct +{ + const EVP_CIPHER *type; } esp_crypto_alg_t; -typedef struct { - const EVP_MD * md; +typedef struct +{ + const EVP_MD *md; u8 trunc_size; } esp_integ_alg_t; -typedef struct { - CLIB_CACHE_LINE_ALIGN_MARK(cacheline0); +typedef struct +{ + CLIB_CACHE_LINE_ALIGN_MARK (cacheline0); EVP_CIPHER_CTX encrypt_ctx; - CLIB_CACHE_LINE_ALIGN_MARK(cacheline1); + CLIB_CACHE_LINE_ALIGN_MARK (cacheline1); EVP_CIPHER_CTX decrypt_ctx; - CLIB_CACHE_LINE_ALIGN_MARK(cacheline2); + CLIB_CACHE_LINE_ALIGN_MARK (cacheline2); HMAC_CTX hmac_ctx; ipsec_crypto_alg_t last_encrypt_alg; ipsec_crypto_alg_t last_decrypt_alg; ipsec_integ_alg_t last_integ_alg; } esp_main_per_thread_data_t; -typedef struct { - esp_crypto_alg_t * esp_crypto_algs; - esp_integ_alg_t * esp_integ_algs; - esp_main_per_thread_data_t * per_thread_data; +typedef struct +{ + esp_crypto_alg_t *esp_crypto_algs; + esp_integ_alg_t *esp_integ_algs; + esp_main_per_thread_data_t *per_thread_data; } esp_main_t; esp_main_t esp_main; always_inline void -esp_init() +esp_init () { - esp_main_t * em = &esp_main; - vlib_thread_main_t * tm = vlib_get_thread_main(); + esp_main_t *em = &esp_main; + vlib_thread_main_t *tm = vlib_get_thread_main (); memset (em, 0, sizeof (em[0])); - vec_validate(em->esp_crypto_algs, IPSEC_CRYPTO_N_ALG - 1); - em->esp_crypto_algs[IPSEC_CRYPTO_ALG_AES_CBC_128].type = EVP_aes_128_cbc(); - em->esp_crypto_algs[IPSEC_CRYPTO_ALG_AES_CBC_192].type = EVP_aes_192_cbc(); - em->esp_crypto_algs[IPSEC_CRYPTO_ALG_AES_CBC_256].type = EVP_aes_256_cbc(); + vec_validate (em->esp_crypto_algs, IPSEC_CRYPTO_N_ALG - 1); + em->esp_crypto_algs[IPSEC_CRYPTO_ALG_AES_CBC_128].type = EVP_aes_128_cbc (); + em->esp_crypto_algs[IPSEC_CRYPTO_ALG_AES_CBC_192].type = EVP_aes_192_cbc (); + em->esp_crypto_algs[IPSEC_CRYPTO_ALG_AES_CBC_256].type = EVP_aes_256_cbc (); - vec_validate(em->esp_integ_algs, IPSEC_INTEG_N_ALG - 1); - esp_integ_alg_t * i; + vec_validate (em->esp_integ_algs, IPSEC_INTEG_N_ALG - 1); + esp_integ_alg_t *i; i = &em->esp_integ_algs[IPSEC_INTEG_ALG_SHA1_96]; - i->md = EVP_sha1(); + i->md = EVP_sha1 (); i->trunc_size = 12; i = &em->esp_integ_algs[IPSEC_INTEG_ALG_SHA_256_96]; - i->md = EVP_sha256(); + i->md = EVP_sha256 (); i->trunc_size = 12; i = &em->esp_integ_algs[IPSEC_INTEG_ALG_SHA_256_128]; - i->md = EVP_sha256(); + i->md = EVP_sha256 (); i->trunc_size = 16; i = &em->esp_integ_algs[IPSEC_INTEG_ALG_SHA_384_192]; - i->md = EVP_sha384(); + i->md = EVP_sha384 (); i->trunc_size = 24; i = &em->esp_integ_algs[IPSEC_INTEG_ALG_SHA_512_256]; - i->md = EVP_sha512(); + i->md = EVP_sha512 (); i->trunc_size = 32; - vec_validate_aligned(em->per_thread_data, tm->n_vlib_mains-1, CLIB_CACHE_LINE_BYTES); + vec_validate_aligned (em->per_thread_data, tm->n_vlib_mains - 1, + CLIB_CACHE_LINE_BYTES); int thread_id; for (thread_id = 0; thread_id < tm->n_vlib_mains - 1; thread_id++) { - EVP_CIPHER_CTX_init(&(em->per_thread_data[thread_id].encrypt_ctx)); - EVP_CIPHER_CTX_init(&(em->per_thread_data[thread_id].decrypt_ctx)); - HMAC_CTX_init(&(em->per_thread_data[thread_id].hmac_ctx)); + EVP_CIPHER_CTX_init (&(em->per_thread_data[thread_id].encrypt_ctx)); + EVP_CIPHER_CTX_init (&(em->per_thread_data[thread_id].decrypt_ctx)); + HMAC_CTX_init (&(em->per_thread_data[thread_id].hmac_ctx)); } } always_inline unsigned int -hmac_calc(ipsec_integ_alg_t alg, - u8 * key, - int key_len, - u8 * data, - int data_len, - u8 * signature, - u8 use_esn, - u32 seq_hi) +hmac_calc (ipsec_integ_alg_t alg, + u8 * key, + int key_len, + u8 * data, int data_len, u8 * signature, u8 use_esn, u32 seq_hi) { - esp_main_t * em = &esp_main; - u32 cpu_index = os_get_cpu_number(); - HMAC_CTX * ctx = &(em->per_thread_data[cpu_index].hmac_ctx); - const EVP_MD * md = NULL; + esp_main_t *em = &esp_main; + u32 cpu_index = os_get_cpu_number (); + HMAC_CTX *ctx = &(em->per_thread_data[cpu_index].hmac_ctx); + const EVP_MD *md = NULL; unsigned int len; - ASSERT(alg < IPSEC_INTEG_N_ALG); + ASSERT (alg < IPSEC_INTEG_N_ALG); - if (PREDICT_FALSE(em->esp_integ_algs[alg].md == 0)) + if (PREDICT_FALSE (em->esp_integ_algs[alg].md == 0)) return 0; - if (PREDICT_FALSE(alg != em->per_thread_data[cpu_index].last_integ_alg)) { - md = em->esp_integ_algs[alg].md; - em->per_thread_data[cpu_index].last_integ_alg = alg; - } + if (PREDICT_FALSE (alg != em->per_thread_data[cpu_index].last_integ_alg)) + { + md = em->esp_integ_algs[alg].md; + em->per_thread_data[cpu_index].last_integ_alg = alg; + } - HMAC_Init(ctx, key, key_len, md); + HMAC_Init (ctx, key, key_len, md); - HMAC_Update(ctx, data, data_len); + HMAC_Update (ctx, data, data_len); - if (PREDICT_TRUE(use_esn)) - HMAC_Update(ctx, (u8 *) &seq_hi, sizeof(seq_hi)); - HMAC_Final(ctx, signature, &len); + if (PREDICT_TRUE (use_esn)) + HMAC_Update (ctx, (u8 *) & seq_hi, sizeof (seq_hi)); + HMAC_Final (ctx, signature, &len); return em->esp_integ_algs[alg].trunc_size; } + +/* + * fd.io coding-style-patch-verification: ON + * + * Local Variables: + * eval: (c-set-style "gnu") + * End: + */ diff --git a/vnet/vnet/ipsec/esp_decrypt.c b/vnet/vnet/ipsec/esp_decrypt.c index 2e1e0502db8..49b1dfe4735 100644 --- a/vnet/vnet/ipsec/esp_decrypt.c +++ b/vnet/vnet/ipsec/esp_decrypt.c @@ -30,10 +30,11 @@ _(IP4_INPUT, "ip4-input") \ _(IP6_INPUT, "ip6-input") #define _(v, s) ESP_DECRYPT_NEXT_##v, -typedef enum { +typedef enum +{ foreach_esp_decrypt_next #undef _ - ESP_DECRYPT_N_NEXT, + ESP_DECRYPT_N_NEXT, } esp_decrypt_next_t; @@ -46,65 +47,65 @@ typedef enum { _(NOT_IP, "Not IP packet (dropped)") -typedef enum { +typedef enum +{ #define _(sym,str) ESP_DECRYPT_ERROR_##sym, foreach_esp_decrypt_error #undef _ - ESP_DECRYPT_N_ERROR, + ESP_DECRYPT_N_ERROR, } esp_decrypt_error_t; -static char * esp_decrypt_error_strings[] = { +static char *esp_decrypt_error_strings[] = { #define _(sym,string) string, foreach_esp_decrypt_error #undef _ }; -typedef struct { +typedef struct +{ ipsec_crypto_alg_t crypto_alg; ipsec_integ_alg_t integ_alg; } esp_decrypt_trace_t; /* packet trace format function */ -static u8 * format_esp_decrypt_trace (u8 * s, va_list * args) +static u8 * +format_esp_decrypt_trace (u8 * s, va_list * args) { CLIB_UNUSED (vlib_main_t * vm) = va_arg (*args, vlib_main_t *); CLIB_UNUSED (vlib_node_t * node) = va_arg (*args, vlib_node_t *); - esp_decrypt_trace_t * t = va_arg (*args, esp_decrypt_trace_t *); + esp_decrypt_trace_t *t = va_arg (*args, esp_decrypt_trace_t *); s = format (s, "esp: crypto %U integrity %U", - format_ipsec_crypto_alg, t->crypto_alg, - format_ipsec_integ_alg, t->integ_alg); + format_ipsec_crypto_alg, t->crypto_alg, + format_ipsec_integ_alg, t->integ_alg); return s; } always_inline void -esp_decrypt_aes_cbc(ipsec_crypto_alg_t alg, - u8 * in, - u8 * out, - size_t in_len, - u8 * key, - u8 * iv) +esp_decrypt_aes_cbc (ipsec_crypto_alg_t alg, + u8 * in, u8 * out, size_t in_len, u8 * key, u8 * iv) { - esp_main_t * em = &esp_main; - u32 cpu_index = os_get_cpu_number(); - EVP_CIPHER_CTX * ctx = &(em->per_thread_data[cpu_index].decrypt_ctx); - const EVP_CIPHER * cipher = NULL; + esp_main_t *em = &esp_main; + u32 cpu_index = os_get_cpu_number (); + EVP_CIPHER_CTX *ctx = &(em->per_thread_data[cpu_index].decrypt_ctx); + const EVP_CIPHER *cipher = NULL; int out_len; - ASSERT(alg < IPSEC_CRYPTO_N_ALG); + ASSERT (alg < IPSEC_CRYPTO_N_ALG); - if (PREDICT_FALSE(em->esp_crypto_algs[alg].type == 0)) + if (PREDICT_FALSE (em->esp_crypto_algs[alg].type == 0)) return; - if (PREDICT_FALSE(alg != em->per_thread_data[cpu_index].last_decrypt_alg)) { - cipher = em->esp_crypto_algs[alg].type; - em->per_thread_data[cpu_index].last_decrypt_alg = alg; - } + if (PREDICT_FALSE (alg != em->per_thread_data[cpu_index].last_decrypt_alg)) + { + cipher = em->esp_crypto_algs[alg].type; + em->per_thread_data[cpu_index].last_decrypt_alg = alg; + } - EVP_DecryptInit_ex(ctx, cipher, NULL, key, iv); + EVP_DecryptInit_ex (ctx, cipher, NULL, key, iv); - EVP_DecryptUpdate(ctx, out, &out_len, in, in_len); - EVP_DecryptFinal_ex(ctx, out + out_len, &out_len); + EVP_DecryptUpdate (ctx, out, &out_len, in, in_len); + EVP_DecryptFinal_ex (ctx, out + out_len, &out_len); } always_inline int @@ -112,7 +113,7 @@ esp_replay_check (ipsec_sa_t * sa, u32 seq) { u32 diff; - if (PREDICT_TRUE(seq > sa->last_seq)) + if (PREDICT_TRUE (seq > sa->last_seq)) return 0; diff = sa->last_seq - seq; @@ -132,37 +133,37 @@ esp_replay_check_esn (ipsec_sa_t * sa, u32 seq) u32 th = sa->last_seq_hi; u32 diff = tl - seq; - if (PREDICT_TRUE(tl >= (ESP_WINDOW_SIZE - 1))) + if (PREDICT_TRUE (tl >= (ESP_WINDOW_SIZE - 1))) { if (seq >= (tl - ESP_WINDOW_SIZE + 1)) - { - sa->seq_hi = th; - if (seq <= tl) - return (sa->replay_window & (1ULL << diff)) ? 1 : 0; - else - return 0; - } + { + sa->seq_hi = th; + if (seq <= tl) + return (sa->replay_window & (1ULL << diff)) ? 1 : 0; + else + return 0; + } else - { - sa->seq_hi = th + 1; - return 0; - } + { + sa->seq_hi = th + 1; + return 0; + } } else { if (seq >= (tl - ESP_WINDOW_SIZE + 1)) - { - sa->seq_hi = th - 1; - return (sa->replay_window & (1ULL << diff)) ? 1 : 0; - } + { + sa->seq_hi = th - 1; + return (sa->replay_window & (1ULL << diff)) ? 1 : 0; + } else - { - sa->seq_hi = th; - if (seq <= tl) - return (sa->replay_window & (1ULL << diff)) ? 1 : 0; - else - return 0; - } + { + sa->seq_hi = th; + if (seq <= tl) + return (sa->replay_window & (1ULL << diff)) ? 1 : 0; + else + return 0; + } } return 0; @@ -177,9 +178,9 @@ esp_replay_advance (ipsec_sa_t * sa, u32 seq) { pos = seq - sa->last_seq; if (pos < ESP_WINDOW_SIZE) - sa->replay_window = ((sa->replay_window) << pos) | 1; + sa->replay_window = ((sa->replay_window) << pos) | 1; else - sa->replay_window = 1; + sa->replay_window = 1; sa->last_seq = seq; } else @@ -199,18 +200,18 @@ esp_replay_advance_esn (ipsec_sa_t * sa, u32 seq) { pos = seq - sa->last_seq; if (pos < ESP_WINDOW_SIZE) - sa->replay_window = ((sa->replay_window) << pos) | 1; + sa->replay_window = ((sa->replay_window) << pos) | 1; else - sa->replay_window = 1; + sa->replay_window = 1; sa->last_seq = seq; } else if (wrap > 0) { pos = ~seq + sa->last_seq + 1; if (pos < ESP_WINDOW_SIZE) - sa->replay_window = ((sa->replay_window) << pos) | 1; + sa->replay_window = ((sa->replay_window) << pos) | 1; else - sa->replay_window = 1; + sa->replay_window = 1; sa->last_seq = seq; sa->last_seq_hi = sa->seq_hi; } @@ -228,26 +229,26 @@ esp_replay_advance_esn (ipsec_sa_t * sa, u32 seq) static uword esp_decrypt_node_fn (vlib_main_t * vm, - vlib_node_runtime_t * node, - vlib_frame_t * from_frame) + vlib_node_runtime_t * node, vlib_frame_t * from_frame) { u32 n_left_from, *from, next_index, *to_next; ipsec_main_t *im = &ipsec_main; esp_main_t *em = &esp_main; - u32 * recycle = 0; + u32 *recycle = 0; from = vlib_frame_vector_args (from_frame); n_left_from = from_frame->n_vectors; - u32 cpu_index = os_get_cpu_number(); + u32 cpu_index = os_get_cpu_number (); - ipsec_alloc_empty_buffers(vm, im); + ipsec_alloc_empty_buffers (vm, im); - u32 * empty_buffers = im->empty_buffers[cpu_index]; + u32 *empty_buffers = im->empty_buffers[cpu_index]; - if (PREDICT_FALSE(vec_len (empty_buffers) < n_left_from)){ - vlib_node_increment_counter (vm, esp_decrypt_node.index, - ESP_DECRYPT_ERROR_NO_BUFFER, n_left_from); - goto free_buffers_and_exit; - } + if (PREDICT_FALSE (vec_len (empty_buffers) < n_left_from)) + { + vlib_node_increment_counter (vm, esp_decrypt_node.index, + ESP_DECRYPT_ERROR_NO_BUFFER, n_left_from); + goto free_buffers_and_exit; + } next_index = node->cached_next_index; @@ -258,231 +259,255 @@ esp_decrypt_node_fn (vlib_main_t * vm, vlib_get_next_frame (vm, node, next_index, to_next, n_left_to_next); while (n_left_from > 0 && n_left_to_next > 0) - { - u32 i_bi0, o_bi0 = (u32) ~0, next0; - vlib_buffer_t * i_b0; - vlib_buffer_t * o_b0 = 0; - esp_header_t * esp0; - ipsec_sa_t * sa0; - u32 sa_index0 = ~0; - u32 seq; - ip4_header_t *ih4 = 0, *oh4 = 0; - ip6_header_t *ih6 = 0, *oh6 = 0; - u8 tunnel_mode = 1; - u8 transport_ip6 = 0; - - - i_bi0 = from[0]; - from += 1; - n_left_from -= 1; - n_left_to_next -= 1; - - next0 = ESP_DECRYPT_NEXT_DROP; - - i_b0 = vlib_get_buffer (vm, i_bi0); - esp0 = vlib_buffer_get_current (i_b0); - - sa_index0 = vnet_buffer(i_b0)->output_features.ipsec_sad_index; - sa0 = pool_elt_at_index (im->sad, sa_index0); - - seq = clib_host_to_net_u32(esp0->seq); - - /* anti-replay check */ - if (sa0->use_anti_replay) - { - int rv = 0; - - if (PREDICT_TRUE(sa0->use_esn)) - rv = esp_replay_check_esn(sa0, seq); - else - rv = esp_replay_check(sa0, seq); - - if (PREDICT_FALSE(rv)) - { - clib_warning("anti-replay SPI %u seq %u", sa0->spi, seq); - vlib_node_increment_counter (vm, esp_decrypt_node.index, - ESP_DECRYPT_ERROR_REPLAY, 1); - o_bi0 = i_bi0; - goto trace; - } - } - - if (PREDICT_TRUE(sa0->integ_alg != IPSEC_INTEG_ALG_NONE)) - { - u8 sig[64]; - int icv_size = em->esp_integ_algs[sa0->integ_alg].trunc_size; - memset(sig, 0, sizeof(sig)); - u8 * icv = vlib_buffer_get_current (i_b0) + i_b0->current_length - icv_size; - i_b0->current_length -= icv_size; - - hmac_calc(sa0->integ_alg, sa0->integ_key, sa0->integ_key_len, - (u8 *) esp0, i_b0->current_length, sig, sa0->use_esn, - sa0->seq_hi); - - if (PREDICT_FALSE(memcmp(icv, sig, icv_size))) - { - vlib_node_increment_counter (vm, esp_decrypt_node.index, - ESP_DECRYPT_ERROR_INTEG_ERROR, 1); - o_bi0 = i_bi0; - goto trace; - } - } - - if (PREDICT_TRUE(sa0->use_anti_replay)) - { - if (PREDICT_TRUE(sa0->use_esn)) - esp_replay_advance_esn(sa0, seq); - else - esp_replay_advance(sa0, seq); - } - - /* grab free buffer */ - uword last_empty_buffer = vec_len (empty_buffers) - 1; - o_bi0 = empty_buffers[last_empty_buffer]; - o_b0 = vlib_get_buffer (vm, o_bi0); - vlib_prefetch_buffer_with_index (vm, empty_buffers[last_empty_buffer-1], STORE); - _vec_len (empty_buffers) = last_empty_buffer; - - /* add old buffer to the recycle list */ - vec_add1(recycle, i_bi0); - - if (sa0->crypto_alg >= IPSEC_CRYPTO_ALG_AES_CBC_128 && - sa0->crypto_alg <= IPSEC_CRYPTO_ALG_AES_CBC_256) { - const int BLOCK_SIZE = 16; - const int IV_SIZE = 16; - esp_footer_t * f0; - u8 ip_hdr_size = 0; - - int blocks = (i_b0->current_length - sizeof (esp_header_t) - IV_SIZE) / BLOCK_SIZE; - - o_b0->current_data = sizeof(ethernet_header_t); - - /* transport mode */ - if (PREDICT_FALSE(!sa0->is_tunnel && !sa0->is_tunnel_ip6)) - { - tunnel_mode = 0; - ih4 = (ip4_header_t *) (i_b0->data + sizeof(ethernet_header_t)); - if (PREDICT_TRUE((ih4->ip_version_and_header_length & 0xF0 ) != 0x40)) - { - if (PREDICT_TRUE((ih4->ip_version_and_header_length & 0xF0 ) == 0x60)) - { - transport_ip6 = 1; - ip_hdr_size = sizeof(ip6_header_t); - ih6 = (ip6_header_t *) (i_b0->data + sizeof(ethernet_header_t)); - oh6 = vlib_buffer_get_current (o_b0); - } - else - { - vlib_node_increment_counter (vm, esp_decrypt_node.index, - ESP_DECRYPT_ERROR_NOT_IP, - 1); - o_b0 = 0; - goto trace; - } - } - else - { - oh4 = vlib_buffer_get_current (o_b0); - ip_hdr_size = sizeof(ip4_header_t); - } - } - - esp_decrypt_aes_cbc(sa0->crypto_alg, - esp0->data + IV_SIZE, - (u8 *) vlib_buffer_get_current (o_b0) + ip_hdr_size, - BLOCK_SIZE * blocks, - sa0->crypto_key, - esp0->data); - - o_b0->current_length = (blocks * 16) - 2 + ip_hdr_size; - o_b0->flags = VLIB_BUFFER_TOTAL_LENGTH_VALID; - f0 = (esp_footer_t *) ((u8 *) vlib_buffer_get_current (o_b0) + o_b0->current_length); - o_b0->current_length -= f0->pad_length; - - /* tunnel mode */ - if (PREDICT_TRUE(tunnel_mode)) - { - if (PREDICT_TRUE(f0->next_header == IP_PROTOCOL_IP_IN_IP)) - next0 = ESP_DECRYPT_NEXT_IP4_INPUT; - else if (f0->next_header == IP_PROTOCOL_IPV6) - next0 = ESP_DECRYPT_NEXT_IP6_INPUT; - else - { - clib_warning("next header: 0x%x", f0->next_header); - vlib_node_increment_counter (vm, esp_decrypt_node.index, - ESP_DECRYPT_ERROR_DECRYPTION_FAILED, - 1); - o_b0 = 0; - goto trace; - } - } - /* transport mode */ - else - { - if (PREDICT_FALSE(transport_ip6)) - { - next0 = ESP_DECRYPT_NEXT_IP6_INPUT; - oh6->ip_version_traffic_class_and_flow_label = - ih6->ip_version_traffic_class_and_flow_label; - oh6->protocol = f0->next_header; - oh6->hop_limit = ih6->hop_limit; - oh6->src_address.as_u64[0] = ih6->src_address.as_u64[0]; - oh6->src_address.as_u64[1] = ih6->src_address.as_u64[1]; - oh6->dst_address.as_u64[0] = ih6->dst_address.as_u64[0]; - oh6->dst_address.as_u64[1] = ih6->dst_address.as_u64[1]; - oh6->payload_length = clib_host_to_net_u16 ( - vlib_buffer_length_in_chain (vm, o_b0) - sizeof(ip6_header_t)); - } - else - { - next0 = ESP_DECRYPT_NEXT_IP4_INPUT; - oh4->ip_version_and_header_length = 0x45; - oh4->tos = ih4->tos; - oh4->fragment_id = 0; - oh4->flags_and_fragment_offset = 0; - oh4->ttl = ih4->ttl; - oh4->protocol = f0->next_header; - oh4->src_address.as_u32 = ih4->src_address.as_u32; - oh4->dst_address.as_u32 = ih4->dst_address.as_u32; - oh4->length = clib_host_to_net_u16 ( - vlib_buffer_length_in_chain (vm, o_b0)); - oh4->checksum = ip4_header_checksum (oh4); - } - } - - to_next[0] = o_bi0; - to_next += 1; - - vnet_buffer (o_b0)->sw_if_index[VLIB_TX] = (u32)~0; - } - -trace: - if (PREDICT_FALSE(i_b0->flags & VLIB_BUFFER_IS_TRACED)) { - if (o_b0) { - o_b0->flags |= VLIB_BUFFER_IS_TRACED; - o_b0->trace_index = i_b0->trace_index; - } - esp_decrypt_trace_t *tr = vlib_add_trace (vm, node, o_b0, sizeof (*tr)); - tr->crypto_alg = sa0->crypto_alg; - tr->integ_alg = sa0->integ_alg; - } + { + u32 i_bi0, o_bi0 = (u32) ~ 0, next0; + vlib_buffer_t *i_b0; + vlib_buffer_t *o_b0 = 0; + esp_header_t *esp0; + ipsec_sa_t *sa0; + u32 sa_index0 = ~0; + u32 seq; + ip4_header_t *ih4 = 0, *oh4 = 0; + ip6_header_t *ih6 = 0, *oh6 = 0; + u8 tunnel_mode = 1; + u8 transport_ip6 = 0; + + + i_bi0 = from[0]; + from += 1; + n_left_from -= 1; + n_left_to_next -= 1; + + next0 = ESP_DECRYPT_NEXT_DROP; + + i_b0 = vlib_get_buffer (vm, i_bi0); + esp0 = vlib_buffer_get_current (i_b0); + + sa_index0 = vnet_buffer (i_b0)->output_features.ipsec_sad_index; + sa0 = pool_elt_at_index (im->sad, sa_index0); + + seq = clib_host_to_net_u32 (esp0->seq); + + /* anti-replay check */ + if (sa0->use_anti_replay) + { + int rv = 0; + + if (PREDICT_TRUE (sa0->use_esn)) + rv = esp_replay_check_esn (sa0, seq); + else + rv = esp_replay_check (sa0, seq); + + if (PREDICT_FALSE (rv)) + { + clib_warning ("anti-replay SPI %u seq %u", sa0->spi, seq); + vlib_node_increment_counter (vm, esp_decrypt_node.index, + ESP_DECRYPT_ERROR_REPLAY, 1); + o_bi0 = i_bi0; + goto trace; + } + } + + if (PREDICT_TRUE (sa0->integ_alg != IPSEC_INTEG_ALG_NONE)) + { + u8 sig[64]; + int icv_size = em->esp_integ_algs[sa0->integ_alg].trunc_size; + memset (sig, 0, sizeof (sig)); + u8 *icv = + vlib_buffer_get_current (i_b0) + i_b0->current_length - + icv_size; + i_b0->current_length -= icv_size; + + hmac_calc (sa0->integ_alg, sa0->integ_key, sa0->integ_key_len, + (u8 *) esp0, i_b0->current_length, sig, sa0->use_esn, + sa0->seq_hi); + + if (PREDICT_FALSE (memcmp (icv, sig, icv_size))) + { + vlib_node_increment_counter (vm, esp_decrypt_node.index, + ESP_DECRYPT_ERROR_INTEG_ERROR, + 1); + o_bi0 = i_bi0; + goto trace; + } + } + + if (PREDICT_TRUE (sa0->use_anti_replay)) + { + if (PREDICT_TRUE (sa0->use_esn)) + esp_replay_advance_esn (sa0, seq); + else + esp_replay_advance (sa0, seq); + } + + /* grab free buffer */ + uword last_empty_buffer = vec_len (empty_buffers) - 1; + o_bi0 = empty_buffers[last_empty_buffer]; + o_b0 = vlib_get_buffer (vm, o_bi0); + vlib_prefetch_buffer_with_index (vm, + empty_buffers[last_empty_buffer - + 1], STORE); + _vec_len (empty_buffers) = last_empty_buffer; + + /* add old buffer to the recycle list */ + vec_add1 (recycle, i_bi0); + + if (sa0->crypto_alg >= IPSEC_CRYPTO_ALG_AES_CBC_128 && + sa0->crypto_alg <= IPSEC_CRYPTO_ALG_AES_CBC_256) + { + const int BLOCK_SIZE = 16; + const int IV_SIZE = 16; + esp_footer_t *f0; + u8 ip_hdr_size = 0; + + int blocks = + (i_b0->current_length - sizeof (esp_header_t) - + IV_SIZE) / BLOCK_SIZE; + + o_b0->current_data = sizeof (ethernet_header_t); + + /* transport mode */ + if (PREDICT_FALSE (!sa0->is_tunnel && !sa0->is_tunnel_ip6)) + { + tunnel_mode = 0; + ih4 = + (ip4_header_t *) (i_b0->data + + sizeof (ethernet_header_t)); + if (PREDICT_TRUE + ((ih4->ip_version_and_header_length & 0xF0) != 0x40)) + { + if (PREDICT_TRUE + ((ih4->ip_version_and_header_length & 0xF0) == + 0x60)) + { + transport_ip6 = 1; + ip_hdr_size = sizeof (ip6_header_t); + ih6 = + (ip6_header_t *) (i_b0->data + + sizeof (ethernet_header_t)); + oh6 = vlib_buffer_get_current (o_b0); + } + else + { + vlib_node_increment_counter (vm, + esp_decrypt_node.index, + ESP_DECRYPT_ERROR_NOT_IP, + 1); + o_b0 = 0; + goto trace; + } + } + else + { + oh4 = vlib_buffer_get_current (o_b0); + ip_hdr_size = sizeof (ip4_header_t); + } + } + + esp_decrypt_aes_cbc (sa0->crypto_alg, + esp0->data + IV_SIZE, + (u8 *) vlib_buffer_get_current (o_b0) + + ip_hdr_size, BLOCK_SIZE * blocks, + sa0->crypto_key, esp0->data); + + o_b0->current_length = (blocks * 16) - 2 + ip_hdr_size; + o_b0->flags = VLIB_BUFFER_TOTAL_LENGTH_VALID; + f0 = + (esp_footer_t *) ((u8 *) vlib_buffer_get_current (o_b0) + + o_b0->current_length); + o_b0->current_length -= f0->pad_length; + + /* tunnel mode */ + if (PREDICT_TRUE (tunnel_mode)) + { + if (PREDICT_TRUE (f0->next_header == IP_PROTOCOL_IP_IN_IP)) + next0 = ESP_DECRYPT_NEXT_IP4_INPUT; + else if (f0->next_header == IP_PROTOCOL_IPV6) + next0 = ESP_DECRYPT_NEXT_IP6_INPUT; + else + { + clib_warning ("next header: 0x%x", f0->next_header); + vlib_node_increment_counter (vm, esp_decrypt_node.index, + ESP_DECRYPT_ERROR_DECRYPTION_FAILED, + 1); + o_b0 = 0; + goto trace; + } + } + /* transport mode */ + else + { + if (PREDICT_FALSE (transport_ip6)) + { + next0 = ESP_DECRYPT_NEXT_IP6_INPUT; + oh6->ip_version_traffic_class_and_flow_label = + ih6->ip_version_traffic_class_and_flow_label; + oh6->protocol = f0->next_header; + oh6->hop_limit = ih6->hop_limit; + oh6->src_address.as_u64[0] = ih6->src_address.as_u64[0]; + oh6->src_address.as_u64[1] = ih6->src_address.as_u64[1]; + oh6->dst_address.as_u64[0] = ih6->dst_address.as_u64[0]; + oh6->dst_address.as_u64[1] = ih6->dst_address.as_u64[1]; + oh6->payload_length = + clib_host_to_net_u16 (vlib_buffer_length_in_chain + (vm, + o_b0) - sizeof (ip6_header_t)); + } + else + { + next0 = ESP_DECRYPT_NEXT_IP4_INPUT; + oh4->ip_version_and_header_length = 0x45; + oh4->tos = ih4->tos; + oh4->fragment_id = 0; + oh4->flags_and_fragment_offset = 0; + oh4->ttl = ih4->ttl; + oh4->protocol = f0->next_header; + oh4->src_address.as_u32 = ih4->src_address.as_u32; + oh4->dst_address.as_u32 = ih4->dst_address.as_u32; + oh4->length = + clib_host_to_net_u16 (vlib_buffer_length_in_chain + (vm, o_b0)); + oh4->checksum = ip4_header_checksum (oh4); + } + } + + to_next[0] = o_bi0; + to_next += 1; + + vnet_buffer (o_b0)->sw_if_index[VLIB_TX] = (u32) ~ 0; + } + + trace: + if (PREDICT_FALSE (i_b0->flags & VLIB_BUFFER_IS_TRACED)) + { + if (o_b0) + { + o_b0->flags |= VLIB_BUFFER_IS_TRACED; + o_b0->trace_index = i_b0->trace_index; + } + esp_decrypt_trace_t *tr = + vlib_add_trace (vm, node, o_b0, sizeof (*tr)); + tr->crypto_alg = sa0->crypto_alg; + tr->integ_alg = sa0->integ_alg; + } vlib_validate_buffer_enqueue_x1 (vm, node, next_index, to_next, - n_left_to_next, o_bi0, next0); - } + n_left_to_next, o_bi0, next0); + } vlib_put_next_frame (vm, node, next_index, n_left_to_next); } vlib_node_increment_counter (vm, esp_decrypt_node.index, - ESP_DECRYPT_ERROR_RX_PKTS, - from_frame->n_vectors); + ESP_DECRYPT_ERROR_RX_PKTS, + from_frame->n_vectors); free_buffers_and_exit: - vlib_buffer_free (vm, recycle, vec_len(recycle)); - vec_free(recycle); + vlib_buffer_free (vm, recycle, vec_len (recycle)); + vec_free (recycle); return from_frame->n_vectors; } +/* *INDENT-OFF* */ VLIB_REGISTER_NODE (esp_decrypt_node) = { .function = esp_decrypt_node_fn, .name = "esp-decrypt", @@ -500,6 +525,13 @@ VLIB_REGISTER_NODE (esp_decrypt_node) = { #undef _ }, }; +/* *INDENT-ON* */ VLIB_NODE_FUNCTION_MULTIARCH (esp_decrypt_node, esp_decrypt_node_fn) - +/* + * fd.io coding-style-patch-verification: ON + * + * Local Variables: + * eval: (c-set-style "gnu") + * End: + */ diff --git a/vnet/vnet/ipsec/esp_encrypt.c b/vnet/vnet/ipsec/esp_encrypt.c index 596c3f41734..44999bd5beb 100644 --- a/vnet/vnet/ipsec/esp_encrypt.c +++ b/vnet/vnet/ipsec/esp_encrypt.c @@ -31,10 +31,11 @@ _(IP6_INPUT, "ip6-input") \ _(INTERFACE_OUTPUT, "interface-output") #define _(v, s) ESP_ENCRYPT_NEXT_##v, -typedef enum { +typedef enum +{ foreach_esp_encrypt_next #undef _ - ESP_ENCRYPT_N_NEXT, + ESP_ENCRYPT_N_NEXT, } esp_encrypt_next_t; #define foreach_esp_encrypt_error \ @@ -44,14 +45,15 @@ typedef enum { _(SEQ_CYCLED, "sequence number cycled") -typedef enum { +typedef enum +{ #define _(sym,str) ESP_ENCRYPT_ERROR_##sym, foreach_esp_encrypt_error #undef _ - ESP_ENCRYPT_N_ERROR, + ESP_ENCRYPT_N_ERROR, } esp_encrypt_error_t; -static char * esp_encrypt_error_strings[] = { +static char *esp_encrypt_error_strings[] = { #define _(sym,string) string, foreach_esp_encrypt_error #undef _ @@ -59,7 +61,8 @@ static char * esp_encrypt_error_strings[] = { vlib_node_registration_t esp_encrypt_node; -typedef struct { +typedef struct +{ u32 spi; u32 seq; ipsec_crypto_alg_t crypto_alg; @@ -67,66 +70,65 @@ typedef struct { } esp_encrypt_trace_t; /* packet trace format function */ -static u8 * format_esp_encrypt_trace (u8 * s, va_list * args) +static u8 * +format_esp_encrypt_trace (u8 * s, va_list * args) { CLIB_UNUSED (vlib_main_t * vm) = va_arg (*args, vlib_main_t *); CLIB_UNUSED (vlib_node_t * node) = va_arg (*args, vlib_node_t *); - esp_encrypt_trace_t * t = va_arg (*args, esp_encrypt_trace_t *); + esp_encrypt_trace_t *t = va_arg (*args, esp_encrypt_trace_t *); s = format (s, "esp: spi %u seq %u crypto %U integrity %U", - t->spi, t->seq, - format_ipsec_crypto_alg, t->crypto_alg, - format_ipsec_integ_alg, t->integ_alg); + t->spi, t->seq, + format_ipsec_crypto_alg, t->crypto_alg, + format_ipsec_integ_alg, t->integ_alg); return s; } always_inline void -esp_encrypt_aes_cbc(ipsec_crypto_alg_t alg, - u8 * in, - u8 * out, - size_t in_len, - u8 * key, - u8 * iv) +esp_encrypt_aes_cbc (ipsec_crypto_alg_t alg, + u8 * in, u8 * out, size_t in_len, u8 * key, u8 * iv) { - esp_main_t * em = &esp_main; - u32 cpu_index = os_get_cpu_number(); - EVP_CIPHER_CTX * ctx = &(em->per_thread_data[cpu_index].encrypt_ctx); - const EVP_CIPHER * cipher = NULL; + esp_main_t *em = &esp_main; + u32 cpu_index = os_get_cpu_number (); + EVP_CIPHER_CTX *ctx = &(em->per_thread_data[cpu_index].encrypt_ctx); + const EVP_CIPHER *cipher = NULL; int out_len; - ASSERT(alg < IPSEC_CRYPTO_N_ALG); + ASSERT (alg < IPSEC_CRYPTO_N_ALG); - if (PREDICT_FALSE(em->esp_crypto_algs[alg].type == IPSEC_CRYPTO_ALG_NONE)) + if (PREDICT_FALSE (em->esp_crypto_algs[alg].type == IPSEC_CRYPTO_ALG_NONE)) return; - if (PREDICT_FALSE(alg != em->per_thread_data[cpu_index].last_encrypt_alg)) { - cipher = em->esp_crypto_algs[alg].type; - em->per_thread_data[cpu_index].last_encrypt_alg = alg; - } + if (PREDICT_FALSE (alg != em->per_thread_data[cpu_index].last_encrypt_alg)) + { + cipher = em->esp_crypto_algs[alg].type; + em->per_thread_data[cpu_index].last_encrypt_alg = alg; + } - EVP_EncryptInit_ex(ctx, cipher, NULL, key, iv); + EVP_EncryptInit_ex (ctx, cipher, NULL, key, iv); - EVP_EncryptUpdate(ctx, out, &out_len, in, in_len); - EVP_EncryptFinal_ex(ctx, out + out_len, &out_len); + EVP_EncryptUpdate (ctx, out, &out_len, in, in_len); + EVP_EncryptFinal_ex (ctx, out + out_len, &out_len); } always_inline int esp_seq_advance (ipsec_sa_t * sa) { - if (PREDICT_TRUE(sa->use_esn)) + if (PREDICT_TRUE (sa->use_esn)) { - if (PREDICT_FALSE(sa->seq == ESP_SEQ_MAX)) - { - if (PREDICT_FALSE(sa->use_anti_replay && sa->seq_hi == ESP_SEQ_MAX)) - return 1; - sa->seq_hi++; - } + if (PREDICT_FALSE (sa->seq == ESP_SEQ_MAX)) + { + if (PREDICT_FALSE + (sa->use_anti_replay && sa->seq_hi == ESP_SEQ_MAX)) + return 1; + sa->seq_hi++; + } sa->seq++; } else { - if (PREDICT_FALSE(sa->use_anti_replay && sa->seq == ESP_SEQ_MAX)) - return 1; + if (PREDICT_FALSE (sa->use_anti_replay && sa->seq == ESP_SEQ_MAX)) + return 1; sa->seq++; } @@ -135,26 +137,26 @@ esp_seq_advance (ipsec_sa_t * sa) static uword esp_encrypt_node_fn (vlib_main_t * vm, - vlib_node_runtime_t * node, - vlib_frame_t * from_frame) + vlib_node_runtime_t * node, vlib_frame_t * from_frame) { - u32 n_left_from, *from, * to_next = 0, next_index; + u32 n_left_from, *from, *to_next = 0, next_index; from = vlib_frame_vector_args (from_frame); n_left_from = from_frame->n_vectors; ipsec_main_t *im = &ipsec_main; - u32 * recycle = 0; - u32 cpu_index = os_get_cpu_number(); + u32 *recycle = 0; + u32 cpu_index = os_get_cpu_number (); - ipsec_alloc_empty_buffers(vm, im); + ipsec_alloc_empty_buffers (vm, im); - u32 * empty_buffers = im->empty_buffers[cpu_index]; + u32 *empty_buffers = im->empty_buffers[cpu_index]; - if (PREDICT_FALSE(vec_len (empty_buffers) < n_left_from)){ - vlib_node_increment_counter (vm, esp_encrypt_node.index, - ESP_ENCRYPT_ERROR_NO_BUFFER, n_left_from); - clib_warning("no enough empty buffers. discarding frame"); - goto free_buffers_and_exit; - } + if (PREDICT_FALSE (vec_len (empty_buffers) < n_left_from)) + { + vlib_node_increment_counter (vm, esp_encrypt_node.index, + ESP_ENCRYPT_ERROR_NO_BUFFER, n_left_from); + clib_warning ("no enough empty buffers. discarding frame"); + goto free_buffers_and_exit; + } next_index = node->cached_next_index; @@ -165,234 +167,253 @@ esp_encrypt_node_fn (vlib_main_t * vm, vlib_get_next_frame (vm, node, next_index, to_next, n_left_to_next); while (n_left_from > 0 && n_left_to_next > 0) - { - u32 i_bi0, o_bi0, next0; - vlib_buffer_t * i_b0, *o_b0 = 0; - u32 sa_index0; - ipsec_sa_t * sa0; - ip4_and_esp_header_t * ih0, * oh0 = 0; - ip6_and_esp_header_t * ih6_0, * oh6_0 = 0; - uword last_empty_buffer; - esp_header_t * o_esp0; - esp_footer_t *f0; - u8 is_ipv6; - u8 ip_hdr_size; - u8 next_hdr_type; - u32 ip_proto = 0; - u8 transport_mode = 0; - - i_bi0 = from[0]; - from += 1; - n_left_from -= 1; - n_left_to_next -= 1; - - next0 = ESP_ENCRYPT_NEXT_DROP; - - i_b0 = vlib_get_buffer (vm, i_bi0); - sa_index0 = vnet_buffer(i_b0)->output_features.ipsec_sad_index; - sa0 = pool_elt_at_index(im->sad, sa_index0); - - if (PREDICT_FALSE(esp_seq_advance(sa0))) - { - clib_warning("sequence number counter has cycled SPI %u", sa0->spi); - vlib_node_increment_counter (vm, esp_encrypt_node.index, - ESP_ENCRYPT_ERROR_SEQ_CYCLED, 1); - //TODO: rekey SA - o_bi0 = i_bi0; - goto trace; - } - - /* grab free buffer */ - last_empty_buffer = vec_len (empty_buffers) - 1; - o_bi0 = empty_buffers[last_empty_buffer]; - o_b0 = vlib_get_buffer (vm, o_bi0); - o_b0->flags = VLIB_BUFFER_TOTAL_LENGTH_VALID; - o_b0->current_data = sizeof(ethernet_header_t); - ih0 = vlib_buffer_get_current (i_b0); - vlib_prefetch_buffer_with_index (vm, empty_buffers[last_empty_buffer-1], STORE); - _vec_len (empty_buffers) = last_empty_buffer; - to_next[0] = o_bi0; - to_next += 1; - - /* add old buffer to the recycle list */ - vec_add1(recycle, i_bi0); - - /* is ipv6 */ - if (PREDICT_FALSE((ih0->ip4.ip_version_and_header_length & 0xF0 ) == 0x60)) - { - is_ipv6 = 1; - ih6_0 = vlib_buffer_get_current (i_b0); - ip_hdr_size = sizeof(ip6_header_t); - next_hdr_type = IP_PROTOCOL_IPV6; - oh6_0 = vlib_buffer_get_current (o_b0); - o_esp0 = vlib_buffer_get_current (o_b0) + sizeof(ip6_header_t); - - oh6_0->ip6.ip_version_traffic_class_and_flow_label = - ih6_0->ip6.ip_version_traffic_class_and_flow_label; - oh6_0->ip6.protocol = IP_PROTOCOL_IPSEC_ESP; - oh6_0->ip6.hop_limit = 254; - oh6_0->ip6.src_address.as_u64[0] = ih6_0->ip6.src_address.as_u64[0]; - oh6_0->ip6.src_address.as_u64[1] = ih6_0->ip6.src_address.as_u64[1]; - oh6_0->ip6.dst_address.as_u64[0] = ih6_0->ip6.dst_address.as_u64[0]; - oh6_0->ip6.dst_address.as_u64[1] = ih6_0->ip6.dst_address.as_u64[1]; - oh6_0->esp.spi = clib_net_to_host_u32(sa0->spi); - oh6_0->esp.seq = clib_net_to_host_u32(sa0->seq); - ip_proto = ih6_0->ip6.protocol; - } - else - { - is_ipv6 = 0; - ip_hdr_size = sizeof(ip4_header_t); - next_hdr_type = IP_PROTOCOL_IP_IN_IP; - oh0 = vlib_buffer_get_current (o_b0); - o_esp0 = vlib_buffer_get_current (o_b0) + sizeof(ip4_header_t); - - oh0->ip4.ip_version_and_header_length = 0x45; - oh0->ip4.tos = ih0->ip4.tos; - oh0->ip4.fragment_id = 0; - oh0->ip4.flags_and_fragment_offset = 0; - oh0->ip4.ttl = 254; - oh0->ip4.protocol = IP_PROTOCOL_IPSEC_ESP; - oh0->ip4.src_address.as_u32 = ih0->ip4.src_address.as_u32; - oh0->ip4.dst_address.as_u32 = ih0->ip4.dst_address.as_u32; - oh0->esp.spi = clib_net_to_host_u32(sa0->spi); - oh0->esp.seq = clib_net_to_host_u32(sa0->seq); - ip_proto = ih0->ip4.protocol; - } - - if (PREDICT_TRUE(sa0->is_tunnel && !sa0->is_tunnel_ip6)) - { - oh0->ip4.src_address.as_u32 = sa0->tunnel_src_addr.ip4.as_u32; - oh0->ip4.dst_address.as_u32 = sa0->tunnel_dst_addr.ip4.as_u32; - - /* in tunnel mode send it back to FIB */ - next0 = ESP_ENCRYPT_NEXT_IP4_INPUT; - vnet_buffer (o_b0)->sw_if_index[VLIB_TX] = (u32)~0; - } - else if(sa0->is_tunnel && sa0->is_tunnel_ip6) - { - oh6_0->ip6.src_address.as_u64[0] = sa0->tunnel_src_addr.ip6.as_u64[0]; - oh6_0->ip6.src_address.as_u64[1] = sa0->tunnel_src_addr.ip6.as_u64[1]; - oh6_0->ip6.dst_address.as_u64[0] = sa0->tunnel_dst_addr.ip6.as_u64[0]; - oh6_0->ip6.dst_address.as_u64[1] = sa0->tunnel_dst_addr.ip6.as_u64[1]; - - /* in tunnel mode send it back to FIB */ - next0 = ESP_ENCRYPT_NEXT_IP6_INPUT; - vnet_buffer (o_b0)->sw_if_index[VLIB_TX] = (u32)~0; - } - else - { - transport_mode = 1; - ethernet_header_t *ieh0, *oeh0; - ieh0 = (ethernet_header_t *) i_b0->data; - oeh0 = (ethernet_header_t *) o_b0->data; - clib_memcpy (oeh0, ieh0, sizeof(ethernet_header_t)); - vlib_buffer_advance(i_b0, ip_hdr_size); - next_hdr_type = ip_proto; - next0 = ESP_ENCRYPT_NEXT_INTERFACE_OUTPUT; - o_b0->flags |= BUFFER_OUTPUT_FEAT_DONE; - vnet_buffer (o_b0)->sw_if_index[VLIB_TX] = - vnet_buffer (i_b0)->sw_if_index[VLIB_TX]; - vnet_buffer(o_b0)->output_features.bitmap = - vnet_buffer(i_b0)->output_features.bitmap; - } - - ASSERT(sa0->crypto_alg < IPSEC_CRYPTO_N_ALG); - - if (PREDICT_TRUE(sa0->crypto_alg != IPSEC_CRYPTO_ALG_NONE)) { - - const int BLOCK_SIZE = 16; - const int IV_SIZE = 16; - int blocks = 1 + (i_b0->current_length + 1) / BLOCK_SIZE; - - /* pad packet in input buffer */ - u8 pad_bytes = BLOCK_SIZE * blocks - 2 - i_b0->current_length; - u8 i; - u8 * padding = vlib_buffer_get_current (i_b0) + i_b0->current_length; - i_b0->current_length = BLOCK_SIZE * blocks; - for (i = 0; i < pad_bytes; ++i) - { - padding[i] = i + 1; - } - f0 = vlib_buffer_get_current (i_b0) + i_b0->current_length - 2; - f0->pad_length = pad_bytes; - f0->next_header = next_hdr_type; - - o_b0->current_length = ip_hdr_size + sizeof(esp_header_t) + - BLOCK_SIZE * blocks + IV_SIZE; - - vnet_buffer (o_b0)->sw_if_index[VLIB_RX] = - vnet_buffer (i_b0)->sw_if_index[VLIB_RX]; - - u8 iv[16]; - RAND_bytes(iv, sizeof(iv)); - - clib_memcpy((u8 *) vlib_buffer_get_current (o_b0) + ip_hdr_size + - sizeof(esp_header_t), iv, 16 ); - - esp_encrypt_aes_cbc(sa0->crypto_alg, - (u8 *) vlib_buffer_get_current (i_b0), - (u8 *) vlib_buffer_get_current (o_b0) + - ip_hdr_size + sizeof(esp_header_t) + IV_SIZE, - BLOCK_SIZE * blocks, - sa0->crypto_key, - iv); - } - - o_b0->current_length += hmac_calc(sa0->integ_alg, sa0->integ_key, - sa0->integ_key_len, - (u8 *) o_esp0, - o_b0->current_length - ip_hdr_size, - vlib_buffer_get_current (o_b0) + - o_b0->current_length, - sa0->use_esn, - sa0->seq_hi); - - - if (PREDICT_FALSE(is_ipv6)) - { - oh6_0->ip6.payload_length = clib_host_to_net_u16 ( - vlib_buffer_length_in_chain (vm, o_b0) - sizeof(ip6_header_t)); - } - else - { - oh0->ip4.length = clib_host_to_net_u16 ( - vlib_buffer_length_in_chain (vm, o_b0)); - oh0->ip4.checksum = ip4_header_checksum (&oh0->ip4); - } - - if (transport_mode) - vlib_buffer_reset (o_b0); - -trace: - if (PREDICT_FALSE(i_b0->flags & VLIB_BUFFER_IS_TRACED)) { - if (o_b0) { - o_b0->flags |= VLIB_BUFFER_IS_TRACED; - o_b0->trace_index = i_b0->trace_index; - } - esp_encrypt_trace_t *tr = vlib_add_trace (vm, node, o_b0, sizeof (*tr)); - tr->spi = sa0->spi; - tr->seq = sa0->seq - 1; - tr->crypto_alg = sa0->crypto_alg; - tr->integ_alg = sa0->integ_alg; - } - - vlib_validate_buffer_enqueue_x1 (vm, node, next_index, - to_next, n_left_to_next, o_bi0, next0); - } + { + u32 i_bi0, o_bi0, next0; + vlib_buffer_t *i_b0, *o_b0 = 0; + u32 sa_index0; + ipsec_sa_t *sa0; + ip4_and_esp_header_t *ih0, *oh0 = 0; + ip6_and_esp_header_t *ih6_0, *oh6_0 = 0; + uword last_empty_buffer; + esp_header_t *o_esp0; + esp_footer_t *f0; + u8 is_ipv6; + u8 ip_hdr_size; + u8 next_hdr_type; + u32 ip_proto = 0; + u8 transport_mode = 0; + + i_bi0 = from[0]; + from += 1; + n_left_from -= 1; + n_left_to_next -= 1; + + next0 = ESP_ENCRYPT_NEXT_DROP; + + i_b0 = vlib_get_buffer (vm, i_bi0); + sa_index0 = vnet_buffer (i_b0)->output_features.ipsec_sad_index; + sa0 = pool_elt_at_index (im->sad, sa_index0); + + if (PREDICT_FALSE (esp_seq_advance (sa0))) + { + clib_warning ("sequence number counter has cycled SPI %u", + sa0->spi); + vlib_node_increment_counter (vm, esp_encrypt_node.index, + ESP_ENCRYPT_ERROR_SEQ_CYCLED, 1); + //TODO: rekey SA + o_bi0 = i_bi0; + goto trace; + } + + /* grab free buffer */ + last_empty_buffer = vec_len (empty_buffers) - 1; + o_bi0 = empty_buffers[last_empty_buffer]; + o_b0 = vlib_get_buffer (vm, o_bi0); + o_b0->flags = VLIB_BUFFER_TOTAL_LENGTH_VALID; + o_b0->current_data = sizeof (ethernet_header_t); + ih0 = vlib_buffer_get_current (i_b0); + vlib_prefetch_buffer_with_index (vm, + empty_buffers[last_empty_buffer - + 1], STORE); + _vec_len (empty_buffers) = last_empty_buffer; + to_next[0] = o_bi0; + to_next += 1; + + /* add old buffer to the recycle list */ + vec_add1 (recycle, i_bi0); + + /* is ipv6 */ + if (PREDICT_FALSE + ((ih0->ip4.ip_version_and_header_length & 0xF0) == 0x60)) + { + is_ipv6 = 1; + ih6_0 = vlib_buffer_get_current (i_b0); + ip_hdr_size = sizeof (ip6_header_t); + next_hdr_type = IP_PROTOCOL_IPV6; + oh6_0 = vlib_buffer_get_current (o_b0); + o_esp0 = vlib_buffer_get_current (o_b0) + sizeof (ip6_header_t); + + oh6_0->ip6.ip_version_traffic_class_and_flow_label = + ih6_0->ip6.ip_version_traffic_class_and_flow_label; + oh6_0->ip6.protocol = IP_PROTOCOL_IPSEC_ESP; + oh6_0->ip6.hop_limit = 254; + oh6_0->ip6.src_address.as_u64[0] = + ih6_0->ip6.src_address.as_u64[0]; + oh6_0->ip6.src_address.as_u64[1] = + ih6_0->ip6.src_address.as_u64[1]; + oh6_0->ip6.dst_address.as_u64[0] = + ih6_0->ip6.dst_address.as_u64[0]; + oh6_0->ip6.dst_address.as_u64[1] = + ih6_0->ip6.dst_address.as_u64[1]; + oh6_0->esp.spi = clib_net_to_host_u32 (sa0->spi); + oh6_0->esp.seq = clib_net_to_host_u32 (sa0->seq); + ip_proto = ih6_0->ip6.protocol; + } + else + { + is_ipv6 = 0; + ip_hdr_size = sizeof (ip4_header_t); + next_hdr_type = IP_PROTOCOL_IP_IN_IP; + oh0 = vlib_buffer_get_current (o_b0); + o_esp0 = vlib_buffer_get_current (o_b0) + sizeof (ip4_header_t); + + oh0->ip4.ip_version_and_header_length = 0x45; + oh0->ip4.tos = ih0->ip4.tos; + oh0->ip4.fragment_id = 0; + oh0->ip4.flags_and_fragment_offset = 0; + oh0->ip4.ttl = 254; + oh0->ip4.protocol = IP_PROTOCOL_IPSEC_ESP; + oh0->ip4.src_address.as_u32 = ih0->ip4.src_address.as_u32; + oh0->ip4.dst_address.as_u32 = ih0->ip4.dst_address.as_u32; + oh0->esp.spi = clib_net_to_host_u32 (sa0->spi); + oh0->esp.seq = clib_net_to_host_u32 (sa0->seq); + ip_proto = ih0->ip4.protocol; + } + + if (PREDICT_TRUE (sa0->is_tunnel && !sa0->is_tunnel_ip6)) + { + oh0->ip4.src_address.as_u32 = sa0->tunnel_src_addr.ip4.as_u32; + oh0->ip4.dst_address.as_u32 = sa0->tunnel_dst_addr.ip4.as_u32; + + /* in tunnel mode send it back to FIB */ + next0 = ESP_ENCRYPT_NEXT_IP4_INPUT; + vnet_buffer (o_b0)->sw_if_index[VLIB_TX] = (u32) ~ 0; + } + else if (sa0->is_tunnel && sa0->is_tunnel_ip6) + { + oh6_0->ip6.src_address.as_u64[0] = + sa0->tunnel_src_addr.ip6.as_u64[0]; + oh6_0->ip6.src_address.as_u64[1] = + sa0->tunnel_src_addr.ip6.as_u64[1]; + oh6_0->ip6.dst_address.as_u64[0] = + sa0->tunnel_dst_addr.ip6.as_u64[0]; + oh6_0->ip6.dst_address.as_u64[1] = + sa0->tunnel_dst_addr.ip6.as_u64[1]; + + /* in tunnel mode send it back to FIB */ + next0 = ESP_ENCRYPT_NEXT_IP6_INPUT; + vnet_buffer (o_b0)->sw_if_index[VLIB_TX] = (u32) ~ 0; + } + else + { + transport_mode = 1; + ethernet_header_t *ieh0, *oeh0; + ieh0 = (ethernet_header_t *) i_b0->data; + oeh0 = (ethernet_header_t *) o_b0->data; + clib_memcpy (oeh0, ieh0, sizeof (ethernet_header_t)); + vlib_buffer_advance (i_b0, ip_hdr_size); + next_hdr_type = ip_proto; + next0 = ESP_ENCRYPT_NEXT_INTERFACE_OUTPUT; + o_b0->flags |= BUFFER_OUTPUT_FEAT_DONE; + vnet_buffer (o_b0)->sw_if_index[VLIB_TX] = + vnet_buffer (i_b0)->sw_if_index[VLIB_TX]; + vnet_buffer (o_b0)->output_features.bitmap = + vnet_buffer (i_b0)->output_features.bitmap; + } + + ASSERT (sa0->crypto_alg < IPSEC_CRYPTO_N_ALG); + + if (PREDICT_TRUE (sa0->crypto_alg != IPSEC_CRYPTO_ALG_NONE)) + { + + const int BLOCK_SIZE = 16; + const int IV_SIZE = 16; + int blocks = 1 + (i_b0->current_length + 1) / BLOCK_SIZE; + + /* pad packet in input buffer */ + u8 pad_bytes = BLOCK_SIZE * blocks - 2 - i_b0->current_length; + u8 i; + u8 *padding = + vlib_buffer_get_current (i_b0) + i_b0->current_length; + i_b0->current_length = BLOCK_SIZE * blocks; + for (i = 0; i < pad_bytes; ++i) + { + padding[i] = i + 1; + } + f0 = vlib_buffer_get_current (i_b0) + i_b0->current_length - 2; + f0->pad_length = pad_bytes; + f0->next_header = next_hdr_type; + + o_b0->current_length = ip_hdr_size + sizeof (esp_header_t) + + BLOCK_SIZE * blocks + IV_SIZE; + + vnet_buffer (o_b0)->sw_if_index[VLIB_RX] = + vnet_buffer (i_b0)->sw_if_index[VLIB_RX]; + + u8 iv[16]; + RAND_bytes (iv, sizeof (iv)); + + clib_memcpy ((u8 *) vlib_buffer_get_current (o_b0) + + ip_hdr_size + sizeof (esp_header_t), iv, 16); + + esp_encrypt_aes_cbc (sa0->crypto_alg, + (u8 *) vlib_buffer_get_current (i_b0), + (u8 *) vlib_buffer_get_current (o_b0) + + ip_hdr_size + sizeof (esp_header_t) + + IV_SIZE, BLOCK_SIZE * blocks, + sa0->crypto_key, iv); + } + + o_b0->current_length += hmac_calc (sa0->integ_alg, sa0->integ_key, + sa0->integ_key_len, + (u8 *) o_esp0, + o_b0->current_length - + ip_hdr_size, + vlib_buffer_get_current (o_b0) + + o_b0->current_length, + sa0->use_esn, sa0->seq_hi); + + + if (PREDICT_FALSE (is_ipv6)) + { + oh6_0->ip6.payload_length = + clib_host_to_net_u16 (vlib_buffer_length_in_chain (vm, o_b0) - + sizeof (ip6_header_t)); + } + else + { + oh0->ip4.length = + clib_host_to_net_u16 (vlib_buffer_length_in_chain (vm, o_b0)); + oh0->ip4.checksum = ip4_header_checksum (&oh0->ip4); + } + + if (transport_mode) + vlib_buffer_reset (o_b0); + + trace: + if (PREDICT_FALSE (i_b0->flags & VLIB_BUFFER_IS_TRACED)) + { + if (o_b0) + { + o_b0->flags |= VLIB_BUFFER_IS_TRACED; + o_b0->trace_index = i_b0->trace_index; + } + esp_encrypt_trace_t *tr = + vlib_add_trace (vm, node, o_b0, sizeof (*tr)); + tr->spi = sa0->spi; + tr->seq = sa0->seq - 1; + tr->crypto_alg = sa0->crypto_alg; + tr->integ_alg = sa0->integ_alg; + } + + vlib_validate_buffer_enqueue_x1 (vm, node, next_index, + to_next, n_left_to_next, o_bi0, + next0); + } vlib_put_next_frame (vm, node, next_index, n_left_to_next); } vlib_node_increment_counter (vm, esp_encrypt_node.index, - ESP_ENCRYPT_ERROR_RX_PKTS, - from_frame->n_vectors); + ESP_ENCRYPT_ERROR_RX_PKTS, + from_frame->n_vectors); free_buffers_and_exit: - vlib_buffer_free (vm, recycle, vec_len(recycle)); - vec_free(recycle); + vlib_buffer_free (vm, recycle, vec_len (recycle)); + vec_free (recycle); return from_frame->n_vectors; } +/* *INDENT-OFF* */ VLIB_REGISTER_NODE (esp_encrypt_node) = { .function = esp_encrypt_node_fn, .name = "esp-encrypt", @@ -410,6 +431,13 @@ VLIB_REGISTER_NODE (esp_encrypt_node) = { #undef _ }, }; +/* *INDENT-ON* */ VLIB_NODE_FUNCTION_MULTIARCH (esp_encrypt_node, esp_encrypt_node_fn) - +/* + * fd.io coding-style-patch-verification: ON + * + * Local Variables: + * eval: (c-set-style "gnu") + * End: + */ diff --git a/vnet/vnet/ipsec/ikev2.c b/vnet/vnet/ipsec/ikev2.c index 8455c1263d6..dd00c9edef3 100644 --- a/vnet/vnet/ipsec/ikev2.c +++ b/vnet/vnet/ipsec/ikev2.c @@ -22,28 +22,30 @@ #include <vnet/ipsec/ikev2.h> #include <vnet/ipsec/ikev2_priv.h> -static int ikev2_delete_tunnel_interface(vnet_main_t * vnm, - ikev2_sa_t *sa, - ikev2_child_sa_t * child); +static int ikev2_delete_tunnel_interface (vnet_main_t * vnm, + ikev2_sa_t * sa, + ikev2_child_sa_t * child); #define ikev2_set_state(sa, v) do { \ (sa)->state = v; \ clib_warning("sa state changed to " #v); \ } while(0); -typedef struct { +typedef struct +{ u32 next_index; u32 sw_if_index; } ikev2_trace_t; -static u8 * format_ikev2_trace (u8 * s, va_list * args) +static u8 * +format_ikev2_trace (u8 * s, va_list * args) { CLIB_UNUSED (vlib_main_t * vm) = va_arg (*args, vlib_main_t *); CLIB_UNUSED (vlib_node_t * node) = va_arg (*args, vlib_node_t *); - ikev2_trace_t * t = va_arg (*args, ikev2_trace_t *); + ikev2_trace_t *t = va_arg (*args, ikev2_trace_t *); s = format (s, "ikev2: sw_if_index %d, next index %d", - t->sw_if_index, t->next_index); + t->sw_if_index, t->next_index); return s; } @@ -57,259 +59,264 @@ _(IKE_REQ_RETRANSMIT, "IKE request retransmit") \ _(IKE_REQ_IGNORE, "IKE request ignore (old msgid)") \ _(NOT_IKEV2, "Non IKEv2 packets received") -typedef enum { +typedef enum +{ #define _(sym,str) IKEV2_ERROR_##sym, foreach_ikev2_error #undef _ - IKEV2_N_ERROR, + IKEV2_N_ERROR, } ikev2_error_t; -static char * ikev2_error_strings[] = { +static char *ikev2_error_strings[] = { #define _(sym,string) string, foreach_ikev2_error #undef _ }; -typedef enum { +typedef enum +{ IKEV2_NEXT_IP4_LOOKUP, IKEV2_NEXT_ERROR_DROP, IKEV2_N_NEXT, } ikev2_next_t; static ikev2_sa_transform_t * -ikev2_find_transform_data(ikev2_sa_transform_t * t) +ikev2_find_transform_data (ikev2_sa_transform_t * t) { - ikev2_main_t * km = &ikev2_main; - ikev2_sa_transform_t * td; + ikev2_main_t *km = &ikev2_main; + ikev2_sa_transform_t *td; - vec_foreach(td, km->supported_transforms) - { - if (td->type != t->type) - continue; + vec_foreach (td, km->supported_transforms) + { + if (td->type != t->type) + continue; - if (td->transform_id != t->transform_id) - continue; + if (td->transform_id != t->transform_id) + continue; - if (td->type == IKEV2_TRANSFORM_TYPE_ENCR) - { - if (vec_len(t->attrs) != 4 || t->attrs[0] != 0x80 || t->attrs[1] != 14) - continue; + if (td->type == IKEV2_TRANSFORM_TYPE_ENCR) + { + if (vec_len (t->attrs) != 4 || t->attrs[0] != 0x80 + || t->attrs[1] != 14) + continue; - if (((t->attrs[2] << 8 | t->attrs[3]) / 8) != td->key_len) - continue; - } - return td; - } + if (((t->attrs[2] << 8 | t->attrs[3]) / 8) != td->key_len) + continue; + } + return td; + } return 0; } static ikev2_sa_proposal_t * -ikev2_select_proposal(ikev2_sa_proposal_t *proposals, ikev2_protocol_id_t prot_id) +ikev2_select_proposal (ikev2_sa_proposal_t * proposals, + ikev2_protocol_id_t prot_id) { - ikev2_sa_proposal_t * rv = 0; - ikev2_sa_proposal_t * proposal; - ikev2_sa_transform_t * transform, * new_t; + ikev2_sa_proposal_t *rv = 0; + ikev2_sa_proposal_t *proposal; + ikev2_sa_transform_t *transform, *new_t; u8 mandatory_bitmap, optional_bitmap; if (prot_id == IKEV2_PROTOCOL_IKE) { - mandatory_bitmap = (1 << IKEV2_TRANSFORM_TYPE_ENCR) | - (1 << IKEV2_TRANSFORM_TYPE_PRF) | - (1 << IKEV2_TRANSFORM_TYPE_INTEG) | - (1 << IKEV2_TRANSFORM_TYPE_DH); - optional_bitmap = mandatory_bitmap; + mandatory_bitmap = (1 << IKEV2_TRANSFORM_TYPE_ENCR) | + (1 << IKEV2_TRANSFORM_TYPE_PRF) | + (1 << IKEV2_TRANSFORM_TYPE_INTEG) | (1 << IKEV2_TRANSFORM_TYPE_DH); + optional_bitmap = mandatory_bitmap; } else if (prot_id == IKEV2_PROTOCOL_ESP) { mandatory_bitmap = (1 << IKEV2_TRANSFORM_TYPE_ENCR) | - (1 << IKEV2_TRANSFORM_TYPE_ESN); - optional_bitmap = mandatory_bitmap | - (1 << IKEV2_TRANSFORM_TYPE_INTEG) | - (1 << IKEV2_TRANSFORM_TYPE_DH); + (1 << IKEV2_TRANSFORM_TYPE_ESN); + optional_bitmap = mandatory_bitmap | + (1 << IKEV2_TRANSFORM_TYPE_INTEG) | (1 << IKEV2_TRANSFORM_TYPE_DH); } else if (prot_id == IKEV2_PROTOCOL_AH) { mandatory_bitmap = (1 << IKEV2_TRANSFORM_TYPE_INTEG) | - (1 << IKEV2_TRANSFORM_TYPE_ESN); - optional_bitmap = mandatory_bitmap | - (1 << IKEV2_TRANSFORM_TYPE_DH); + (1 << IKEV2_TRANSFORM_TYPE_ESN); + optional_bitmap = mandatory_bitmap | (1 << IKEV2_TRANSFORM_TYPE_DH); } else return 0; - vec_add2(rv, proposal, 1); - - vec_foreach(proposal, proposals) - { - u8 bitmap = 0; - if (proposal->protocol_id != prot_id) - continue; + vec_add2 (rv, proposal, 1); - vec_foreach(transform, proposal->transforms) - { - if ((1 << transform->type) & bitmap) - continue; + vec_foreach (proposal, proposals) + { + u8 bitmap = 0; + if (proposal->protocol_id != prot_id) + continue; - if (ikev2_find_transform_data(transform)) - { - bitmap |= 1 << transform->type; - vec_add2(rv->transforms, new_t, 1); - clib_memcpy(new_t, transform, sizeof(*new_t)); - new_t->attrs = vec_dup(transform->attrs); - } - } + vec_foreach (transform, proposal->transforms) + { + if ((1 << transform->type) & bitmap) + continue; + + if (ikev2_find_transform_data (transform)) + { + bitmap |= 1 << transform->type; + vec_add2 (rv->transforms, new_t, 1); + clib_memcpy (new_t, transform, sizeof (*new_t)); + new_t->attrs = vec_dup (transform->attrs); + } + } - clib_warning("bitmap is %x mandatory is %x optional is %x", - bitmap, mandatory_bitmap, optional_bitmap); + clib_warning ("bitmap is %x mandatory is %x optional is %x", + bitmap, mandatory_bitmap, optional_bitmap); - if ((bitmap & mandatory_bitmap) == mandatory_bitmap && - (bitmap & ~optional_bitmap) == 0) - { - rv->proposal_num = proposal->proposal_num; - rv->protocol_id = proposal->protocol_id; - RAND_bytes((u8 *) &rv->spi, sizeof(rv->spi)); - goto done; - } - else - { - vec_free(rv->transforms); - } - } + if ((bitmap & mandatory_bitmap) == mandatory_bitmap && + (bitmap & ~optional_bitmap) == 0) + { + rv->proposal_num = proposal->proposal_num; + rv->protocol_id = proposal->protocol_id; + RAND_bytes ((u8 *) & rv->spi, sizeof (rv->spi)); + goto done; + } + else + { + vec_free (rv->transforms); + } + } - vec_free(rv); + vec_free (rv); done: return rv; } ikev2_sa_transform_t * -ikev2_sa_get_td_for_type(ikev2_sa_proposal_t * p, ikev2_transform_type_t type) +ikev2_sa_get_td_for_type (ikev2_sa_proposal_t * p, + ikev2_transform_type_t type) { - ikev2_sa_transform_t * t; + ikev2_sa_transform_t *t; if (!p) return 0; - vec_foreach(t, p->transforms) - { - if (t->type == type) - return ikev2_find_transform_data(t); - } + vec_foreach (t, p->transforms) + { + if (t->type == type) + return ikev2_find_transform_data (t); + } return 0; } ikev2_child_sa_t * -ikev2_sa_get_child(ikev2_sa_t * sa, u32 spi, ikev2_protocol_id_t prot_id) +ikev2_sa_get_child (ikev2_sa_t * sa, u32 spi, ikev2_protocol_id_t prot_id) { - ikev2_child_sa_t * c; - vec_foreach(c, sa->childs) - { - if (c->i_proposals[0].spi == spi && c->i_proposals[0].protocol_id == prot_id) - return c; - } + ikev2_child_sa_t *c; + vec_foreach (c, sa->childs) + { + if (c->i_proposals[0].spi == spi + && c->i_proposals[0].protocol_id == prot_id) + return c; + } return 0; } void -ikev2_sa_free_proposal_vector(ikev2_sa_proposal_t ** v) +ikev2_sa_free_proposal_vector (ikev2_sa_proposal_t ** v) { - ikev2_sa_proposal_t * p; - ikev2_sa_transform_t * t; + ikev2_sa_proposal_t *p; + ikev2_sa_transform_t *t; if (!*v) - return; + return; - vec_foreach(p, *v) { - vec_foreach(t, p->transforms) { - vec_free(t->attrs); + vec_foreach (p, *v) + { + vec_foreach (t, p->transforms) + { + vec_free (t->attrs); } - vec_free(p->transforms); + vec_free (p->transforms); } - vec_free(*v); + vec_free (*v); }; static void -ikev2_sa_free_all_child_sa(ikev2_child_sa_t ** childs) +ikev2_sa_free_all_child_sa (ikev2_child_sa_t ** childs) { - ikev2_child_sa_t * c; - vec_foreach(c, *childs) - { - ikev2_sa_free_proposal_vector(&c->r_proposals); - ikev2_sa_free_proposal_vector(&c->i_proposals); - vec_free(c->sk_ai); - vec_free(c->sk_ar); - vec_free(c->sk_ei); - vec_free(c->sk_er); - } + ikev2_child_sa_t *c; + vec_foreach (c, *childs) + { + ikev2_sa_free_proposal_vector (&c->r_proposals); + ikev2_sa_free_proposal_vector (&c->i_proposals); + vec_free (c->sk_ai); + vec_free (c->sk_ar); + vec_free (c->sk_ei); + vec_free (c->sk_er); + } - vec_free(*childs); + vec_free (*childs); } static void -ikev2_sa_del_child_sa(ikev2_sa_t * sa, ikev2_child_sa_t * child) +ikev2_sa_del_child_sa (ikev2_sa_t * sa, ikev2_child_sa_t * child) { - ikev2_sa_free_proposal_vector(&child->r_proposals); - ikev2_sa_free_proposal_vector(&child->i_proposals); - vec_free(child->sk_ai); - vec_free(child->sk_ar); - vec_free(child->sk_ei); - vec_free(child->sk_er); - - vec_del1(sa->childs, child - sa->childs); + ikev2_sa_free_proposal_vector (&child->r_proposals); + ikev2_sa_free_proposal_vector (&child->i_proposals); + vec_free (child->sk_ai); + vec_free (child->sk_ar); + vec_free (child->sk_ei); + vec_free (child->sk_er); + + vec_del1 (sa->childs, child - sa->childs); } static void -ikev2_sa_free_all_vec(ikev2_sa_t *sa) +ikev2_sa_free_all_vec (ikev2_sa_t * sa) { - vec_free(sa->i_nonce); - vec_free(sa->i_dh_data); - vec_free(sa->dh_shared_key); - - ikev2_sa_free_proposal_vector(&sa->r_proposals); - ikev2_sa_free_proposal_vector(&sa->i_proposals); - - vec_free(sa->sk_d); - vec_free(sa->sk_ai); - vec_free(sa->sk_ar); - vec_free(sa->sk_ei); - vec_free(sa->sk_er); - vec_free(sa->sk_pi); - vec_free(sa->sk_pr); - - vec_free(sa->i_id.data); - vec_free(sa->i_auth.data); - vec_free(sa->r_id.data); - vec_free(sa->r_auth.data); + vec_free (sa->i_nonce); + vec_free (sa->i_dh_data); + vec_free (sa->dh_shared_key); + + ikev2_sa_free_proposal_vector (&sa->r_proposals); + ikev2_sa_free_proposal_vector (&sa->i_proposals); + + vec_free (sa->sk_d); + vec_free (sa->sk_ai); + vec_free (sa->sk_ar); + vec_free (sa->sk_ei); + vec_free (sa->sk_er); + vec_free (sa->sk_pi); + vec_free (sa->sk_pr); + + vec_free (sa->i_id.data); + vec_free (sa->i_auth.data); + vec_free (sa->r_id.data); + vec_free (sa->r_auth.data); if (sa->r_auth.key) - EVP_PKEY_free(sa->r_auth.key); + EVP_PKEY_free (sa->r_auth.key); - vec_free(sa->del); + vec_free (sa->del); - ikev2_sa_free_all_child_sa(&sa->childs); + ikev2_sa_free_all_child_sa (&sa->childs); } static void -ikev2_delete_sa(ikev2_sa_t *sa) +ikev2_delete_sa (ikev2_sa_t * sa) { - ikev2_main_t * km = &ikev2_main; - u32 cpu_index = os_get_cpu_number(); - uword * p; + ikev2_main_t *km = &ikev2_main; + u32 cpu_index = os_get_cpu_number (); + uword *p; - ikev2_sa_free_all_vec(sa); + ikev2_sa_free_all_vec (sa); - p = hash_get(km->per_thread_data[cpu_index].sa_by_rspi, sa->rspi); + p = hash_get (km->per_thread_data[cpu_index].sa_by_rspi, sa->rspi); if (p) { - hash_unset(km->per_thread_data[cpu_index].sa_by_rspi, sa->rspi); - pool_put(km->per_thread_data[cpu_index].sas, sa); + hash_unset (km->per_thread_data[cpu_index].sa_by_rspi, sa->rspi); + pool_put (km->per_thread_data[cpu_index].sas, sa); } } static void -ikev2_generate_sa_init_data(ikev2_sa_t *sa) +ikev2_generate_sa_init_data (ikev2_sa_t * sa) { - ikev2_sa_transform_t * t = 0, * t2; - ikev2_main_t * km = &ikev2_main; + ikev2_sa_transform_t *t = 0, *t2; + ikev2_main_t *km = &ikev2_main; if (sa->dh_group == IKEV2_TRANSFORM_DH_TYPE_NONE) { @@ -317,299 +324,311 @@ ikev2_generate_sa_init_data(ikev2_sa_t *sa) } /* check if received DH group is on our list of supported groups */ - vec_foreach(t2, km->supported_transforms) - { - if (t2->type == IKEV2_TRANSFORM_TYPE_DH && - sa->dh_group == t2->dh_type) - { - t = t2; - break; - } - } + vec_foreach (t2, km->supported_transforms) + { + if (t2->type == IKEV2_TRANSFORM_TYPE_DH && sa->dh_group == t2->dh_type) + { + t = t2; + break; + } + } if (!t) { - clib_warning("unknown dh data group %u (data len %u)", sa->dh_group, - vec_len(sa->i_dh_data)); + clib_warning ("unknown dh data group %u (data len %u)", sa->dh_group, + vec_len (sa->i_dh_data)); sa->dh_group = IKEV2_TRANSFORM_DH_TYPE_NONE; return; } /* generate rspi */ - RAND_bytes((u8 *) &sa->rspi, 8); + RAND_bytes ((u8 *) & sa->rspi, 8); /* generate nonce */ - sa->r_nonce = vec_new(u8, IKEV2_NONCE_SIZE); - RAND_bytes((u8 *) sa->r_nonce, IKEV2_NONCE_SIZE); + sa->r_nonce = vec_new (u8, IKEV2_NONCE_SIZE); + RAND_bytes ((u8 *) sa->r_nonce, IKEV2_NONCE_SIZE); /* generate dh keys */ - ikev2_generate_dh(sa, t); + ikev2_generate_dh (sa, t); } static void -ikev2_calc_keys(ikev2_sa_t *sa) +ikev2_calc_keys (ikev2_sa_t * sa) { - u8 * tmp; + u8 *tmp; /* calculate SKEYSEED = prf(Ni | Nr, g^ir) */ - u8 * skeyseed = 0; - u8 * s = 0; - ikev2_sa_transform_t * tr_encr, * tr_prf, * tr_integ; - tr_encr = ikev2_sa_get_td_for_type(sa->r_proposals, IKEV2_TRANSFORM_TYPE_ENCR); - tr_prf = ikev2_sa_get_td_for_type(sa->r_proposals, IKEV2_TRANSFORM_TYPE_PRF); - tr_integ = ikev2_sa_get_td_for_type(sa->r_proposals, IKEV2_TRANSFORM_TYPE_INTEG); - - vec_append(s, sa->i_nonce); - vec_append(s, sa->r_nonce); - skeyseed = ikev2_calc_prf(tr_prf, s, sa->dh_shared_key); - - /* Calculate S = Ni | Nr | SPIi | SPIr*/ - u64 * spi; - vec_add2(s, tmp, 2 * sizeof(*spi)); + u8 *skeyseed = 0; + u8 *s = 0; + ikev2_sa_transform_t *tr_encr, *tr_prf, *tr_integ; + tr_encr = + ikev2_sa_get_td_for_type (sa->r_proposals, IKEV2_TRANSFORM_TYPE_ENCR); + tr_prf = + ikev2_sa_get_td_for_type (sa->r_proposals, IKEV2_TRANSFORM_TYPE_PRF); + tr_integ = + ikev2_sa_get_td_for_type (sa->r_proposals, IKEV2_TRANSFORM_TYPE_INTEG); + + vec_append (s, sa->i_nonce); + vec_append (s, sa->r_nonce); + skeyseed = ikev2_calc_prf (tr_prf, s, sa->dh_shared_key); + + /* Calculate S = Ni | Nr | SPIi | SPIr */ + u64 *spi; + vec_add2 (s, tmp, 2 * sizeof (*spi)); spi = (u64 *) tmp; - spi[0] = clib_host_to_net_u64(sa->ispi); - spi[1] = clib_host_to_net_u64(sa->rspi); + spi[0] = clib_host_to_net_u64 (sa->ispi); + spi[1] = clib_host_to_net_u64 (sa->rspi); /* calculate PRFplus */ - u8 * keymat; - int len = tr_prf->key_trunc + /* SK_d */ - tr_integ->key_len * 2 + /* SK_ai, SK_ar */ - tr_encr->key_len * 2 + /* SK_ei, SK_er */ - tr_prf->key_len * 2 ; /* SK_pi, SK_pr */ + u8 *keymat; + int len = tr_prf->key_trunc + /* SK_d */ + tr_integ->key_len * 2 + /* SK_ai, SK_ar */ + tr_encr->key_len * 2 + /* SK_ei, SK_er */ + tr_prf->key_len * 2; /* SK_pi, SK_pr */ - keymat = ikev2_calc_prfplus(tr_prf, skeyseed, s, len); - vec_free(skeyseed); - vec_free(s); + keymat = ikev2_calc_prfplus (tr_prf, skeyseed, s, len); + vec_free (skeyseed); + vec_free (s); int pos = 0; /* SK_d */ - sa->sk_d = vec_new(u8, tr_prf->key_trunc); - clib_memcpy(sa->sk_d, keymat + pos, tr_prf->key_trunc); + sa->sk_d = vec_new (u8, tr_prf->key_trunc); + clib_memcpy (sa->sk_d, keymat + pos, tr_prf->key_trunc); pos += tr_prf->key_trunc; /* SK_ai */ - sa->sk_ai = vec_new(u8, tr_integ->key_len); - clib_memcpy(sa->sk_ai, keymat + pos, tr_integ->key_len); + sa->sk_ai = vec_new (u8, tr_integ->key_len); + clib_memcpy (sa->sk_ai, keymat + pos, tr_integ->key_len); pos += tr_integ->key_len; /* SK_ar */ - sa->sk_ar = vec_new(u8, tr_integ->key_len); - clib_memcpy(sa->sk_ar, keymat + pos, tr_integ->key_len); + sa->sk_ar = vec_new (u8, tr_integ->key_len); + clib_memcpy (sa->sk_ar, keymat + pos, tr_integ->key_len); pos += tr_integ->key_len; /* SK_ei */ - sa->sk_ei = vec_new(u8, tr_encr->key_len); - clib_memcpy(sa->sk_ei, keymat + pos, tr_encr->key_len); + sa->sk_ei = vec_new (u8, tr_encr->key_len); + clib_memcpy (sa->sk_ei, keymat + pos, tr_encr->key_len); pos += tr_encr->key_len; /* SK_er */ - sa->sk_er = vec_new(u8, tr_encr->key_len); - clib_memcpy(sa->sk_er, keymat + pos, tr_encr->key_len); + sa->sk_er = vec_new (u8, tr_encr->key_len); + clib_memcpy (sa->sk_er, keymat + pos, tr_encr->key_len); pos += tr_encr->key_len; /* SK_pi */ - sa->sk_pi = vec_new(u8, tr_prf->key_len); - clib_memcpy(sa->sk_pi, keymat + pos, tr_prf->key_len); + sa->sk_pi = vec_new (u8, tr_prf->key_len); + clib_memcpy (sa->sk_pi, keymat + pos, tr_prf->key_len); pos += tr_prf->key_len; /* SK_pr */ - sa->sk_pr = vec_new(u8, tr_prf->key_len); - clib_memcpy(sa->sk_pr, keymat + pos, tr_prf->key_len); + sa->sk_pr = vec_new (u8, tr_prf->key_len); + clib_memcpy (sa->sk_pr, keymat + pos, tr_prf->key_len); pos += tr_prf->key_len; - vec_free(keymat); + vec_free (keymat); } static void -ikev2_calc_child_keys(ikev2_sa_t *sa, ikev2_child_sa_t * child) +ikev2_calc_child_keys (ikev2_sa_t * sa, ikev2_child_sa_t * child) { - u8 * s = 0; - ikev2_sa_transform_t * tr_prf, * ctr_encr, * ctr_integ; - tr_prf = ikev2_sa_get_td_for_type(sa->r_proposals, IKEV2_TRANSFORM_TYPE_PRF); - ctr_encr = ikev2_sa_get_td_for_type(child->r_proposals, IKEV2_TRANSFORM_TYPE_ENCR); - ctr_integ = ikev2_sa_get_td_for_type(child->r_proposals, IKEV2_TRANSFORM_TYPE_INTEG); - - vec_append(s, sa->i_nonce); - vec_append(s, sa->r_nonce); + u8 *s = 0; + ikev2_sa_transform_t *tr_prf, *ctr_encr, *ctr_integ; + tr_prf = + ikev2_sa_get_td_for_type (sa->r_proposals, IKEV2_TRANSFORM_TYPE_PRF); + ctr_encr = + ikev2_sa_get_td_for_type (child->r_proposals, IKEV2_TRANSFORM_TYPE_ENCR); + ctr_integ = + ikev2_sa_get_td_for_type (child->r_proposals, IKEV2_TRANSFORM_TYPE_INTEG); + + vec_append (s, sa->i_nonce); + vec_append (s, sa->r_nonce); /* calculate PRFplus */ - u8 * keymat; + u8 *keymat; int len = ctr_encr->key_len * 2 + ctr_integ->key_len * 2; - keymat = ikev2_calc_prfplus(tr_prf, sa->sk_d, s, len); + keymat = ikev2_calc_prfplus (tr_prf, sa->sk_d, s, len); int pos = 0; /* SK_ei */ - child->sk_ei = vec_new(u8, ctr_encr->key_len); - clib_memcpy(child->sk_ei, keymat + pos, ctr_encr->key_len); + child->sk_ei = vec_new (u8, ctr_encr->key_len); + clib_memcpy (child->sk_ei, keymat + pos, ctr_encr->key_len); pos += ctr_encr->key_len; /* SK_ai */ - child->sk_ai = vec_new(u8, ctr_integ->key_len); - clib_memcpy(child->sk_ai, keymat + pos, ctr_integ->key_len); + child->sk_ai = vec_new (u8, ctr_integ->key_len); + clib_memcpy (child->sk_ai, keymat + pos, ctr_integ->key_len); pos += ctr_integ->key_len; /* SK_er */ - child->sk_er = vec_new(u8, ctr_encr->key_len); - clib_memcpy(child->sk_er, keymat + pos, ctr_encr->key_len); + child->sk_er = vec_new (u8, ctr_encr->key_len); + clib_memcpy (child->sk_er, keymat + pos, ctr_encr->key_len); pos += ctr_encr->key_len; /* SK_ar */ - child->sk_ar = vec_new(u8, ctr_integ->key_len); - clib_memcpy(child->sk_ar, keymat + pos, ctr_integ->key_len); + child->sk_ar = vec_new (u8, ctr_integ->key_len); + clib_memcpy (child->sk_ar, keymat + pos, ctr_integ->key_len); pos += ctr_integ->key_len; - ASSERT(pos == len); + ASSERT (pos == len); - vec_free(keymat); + vec_free (keymat); } static void -ikev2_process_sa_init_req(vlib_main_t * vm, ikev2_sa_t *sa, ike_header_t * ike) +ikev2_process_sa_init_req (vlib_main_t * vm, ikev2_sa_t * sa, + ike_header_t * ike) { int p = 0; - u32 len = clib_net_to_host_u32(ike->length); + u32 len = clib_net_to_host_u32 (ike->length); u8 payload = ike->nextpayload; - clib_warning("ispi %lx rspi %lx nextpayload %x version %x " - "exchange %x flags %x msgid %x length %u", - clib_net_to_host_u64(ike->ispi), - clib_net_to_host_u64(ike->rspi), - payload, ike->version, - ike->exchange, ike->flags, - clib_net_to_host_u32(ike->msgid), - len); + clib_warning ("ispi %lx rspi %lx nextpayload %x version %x " + "exchange %x flags %x msgid %x length %u", + clib_net_to_host_u64 (ike->ispi), + clib_net_to_host_u64 (ike->rspi), + payload, ike->version, + ike->exchange, ike->flags, + clib_net_to_host_u32 (ike->msgid), len); - sa->ispi = clib_net_to_host_u64(ike->ispi); + sa->ispi = clib_net_to_host_u64 (ike->ispi); /* store whole IKE payload - needed for PSK auth */ - vec_free(sa->last_sa_init_req_packet_data); - vec_add(sa->last_sa_init_req_packet_data, ike, len); - - while (p < len && payload!= IKEV2_PAYLOAD_NONE) { - ike_payload_header_t * ikep = (ike_payload_header_t *) &ike->payload[p]; - u32 plen = clib_net_to_host_u16(ikep->length); - - if (plen < sizeof(ike_payload_header_t)) - return; + vec_free (sa->last_sa_init_req_packet_data); + vec_add (sa->last_sa_init_req_packet_data, ike, len); - if (payload == IKEV2_PAYLOAD_SA) - { - ikev2_sa_free_proposal_vector(&sa->i_proposals); - sa->i_proposals = ikev2_parse_sa_payload(ikep); - } - else if (payload == IKEV2_PAYLOAD_KE) - { - ike_ke_payload_header_t * ke = (ike_ke_payload_header_t *) ikep; - sa->dh_group = clib_net_to_host_u16(ke->dh_group); - vec_free(sa->i_dh_data); - vec_add(sa->i_dh_data, ke->payload, plen - sizeof(*ke)); - } - else if (payload == IKEV2_PAYLOAD_NONCE) - { - vec_free(sa->i_nonce); - vec_add(sa->i_nonce, ikep->payload, plen - sizeof(*ikep)); - } - else if (payload == IKEV2_PAYLOAD_NOTIFY) - { - ikev2_notify_t * n = ikev2_parse_notify_payload(ikep); - vec_free(n); - } - else if (payload == IKEV2_PAYLOAD_VENDOR) - { - ikev2_parse_vendor_payload(ikep); - } - else - { - clib_warning("unknown payload %u flags %x length %u", payload, ikep->flags, plen); - if (ikep->flags & IKEV2_PAYLOAD_FLAG_CRITICAL) { - ikev2_set_state(sa, IKEV2_STATE_NOTIFY_AND_DELETE); - sa->unsupported_cp = payload; - return; - } - } + while (p < len && payload != IKEV2_PAYLOAD_NONE) + { + ike_payload_header_t *ikep = (ike_payload_header_t *) & ike->payload[p]; + u32 plen = clib_net_to_host_u16 (ikep->length); + + if (plen < sizeof (ike_payload_header_t)) + return; + + if (payload == IKEV2_PAYLOAD_SA) + { + ikev2_sa_free_proposal_vector (&sa->i_proposals); + sa->i_proposals = ikev2_parse_sa_payload (ikep); + } + else if (payload == IKEV2_PAYLOAD_KE) + { + ike_ke_payload_header_t *ke = (ike_ke_payload_header_t *) ikep; + sa->dh_group = clib_net_to_host_u16 (ke->dh_group); + vec_free (sa->i_dh_data); + vec_add (sa->i_dh_data, ke->payload, plen - sizeof (*ke)); + } + else if (payload == IKEV2_PAYLOAD_NONCE) + { + vec_free (sa->i_nonce); + vec_add (sa->i_nonce, ikep->payload, plen - sizeof (*ikep)); + } + else if (payload == IKEV2_PAYLOAD_NOTIFY) + { + ikev2_notify_t *n = ikev2_parse_notify_payload (ikep); + vec_free (n); + } + else if (payload == IKEV2_PAYLOAD_VENDOR) + { + ikev2_parse_vendor_payload (ikep); + } + else + { + clib_warning ("unknown payload %u flags %x length %u", payload, + ikep->flags, plen); + if (ikep->flags & IKEV2_PAYLOAD_FLAG_CRITICAL) + { + ikev2_set_state (sa, IKEV2_STATE_NOTIFY_AND_DELETE); + sa->unsupported_cp = payload; + return; + } + } - payload = ikep->nextpayload; - p+=plen; - } + payload = ikep->nextpayload; + p += plen; + } - ikev2_set_state(sa, IKEV2_STATE_SA_INIT); + ikev2_set_state (sa, IKEV2_STATE_SA_INIT); } static u8 * -ikev2_decrypt_sk_payload(ikev2_sa_t * sa, ike_header_t * ike, u8 * payload) +ikev2_decrypt_sk_payload (ikev2_sa_t * sa, ike_header_t * ike, u8 * payload) { int p = 0; u8 last_payload = 0; - u8 * hmac = 0; - u32 len = clib_net_to_host_u32(ike->length); - ike_payload_header_t * ikep = 0; + u8 *hmac = 0; + u32 len = clib_net_to_host_u32 (ike->length); + ike_payload_header_t *ikep = 0; u32 plen = 0; - ikev2_sa_transform_t * tr_integ; - tr_integ = ikev2_sa_get_td_for_type(sa->r_proposals, IKEV2_TRANSFORM_TYPE_INTEG); + ikev2_sa_transform_t *tr_integ; + tr_integ = + ikev2_sa_get_td_for_type (sa->r_proposals, IKEV2_TRANSFORM_TYPE_INTEG); while (p < len && - *payload != IKEV2_PAYLOAD_NONE && last_payload != IKEV2_PAYLOAD_SK) + *payload != IKEV2_PAYLOAD_NONE && last_payload != IKEV2_PAYLOAD_SK) { - ikep = (ike_payload_header_t *) &ike->payload[p]; - plen = clib_net_to_host_u16(ikep->length); + ikep = (ike_payload_header_t *) & ike->payload[p]; + plen = clib_net_to_host_u16 (ikep->length); - if (plen < sizeof(*ikep)) - return 0; + if (plen < sizeof (*ikep)) + return 0; if (*payload == IKEV2_PAYLOAD_SK) - { - clib_warning("received IKEv2 payload SK, len %u", plen - 4); - last_payload = *payload; - } + { + clib_warning ("received IKEv2 payload SK, len %u", plen - 4); + last_payload = *payload; + } else - { - clib_warning("unknown payload %u flags %x length %u", payload, ikep->flags, plen); - if (ikep->flags & IKEV2_PAYLOAD_FLAG_CRITICAL) - { - sa->unsupported_cp = *payload; - return 0; - } - } - - *payload = ikep->nextpayload; - p+=plen; - } + { + clib_warning ("unknown payload %u flags %x length %u", payload, + ikep->flags, plen); + if (ikep->flags & IKEV2_PAYLOAD_FLAG_CRITICAL) + { + sa->unsupported_cp = *payload; + return 0; + } + } + + *payload = ikep->nextpayload; + p += plen; + } - if (last_payload != IKEV2_PAYLOAD_SK) { - clib_warning("Last payload must be SK"); - return 0; - } + if (last_payload != IKEV2_PAYLOAD_SK) + { + clib_warning ("Last payload must be SK"); + return 0; + } - hmac = ikev2_calc_integr(tr_integ, sa->sk_ai, (u8 *) ike, - len - tr_integ->key_trunc); + hmac = ikev2_calc_integr (tr_integ, sa->sk_ai, (u8 *) ike, + len - tr_integ->key_trunc); - plen = plen - sizeof(*ikep) - tr_integ->key_trunc; + plen = plen - sizeof (*ikep) - tr_integ->key_trunc; - if (memcmp(hmac, &ikep->payload[plen], tr_integ->key_trunc)) + if (memcmp (hmac, &ikep->payload[plen], tr_integ->key_trunc)) { - clib_warning("message integrity check failed"); - vec_free(hmac); + clib_warning ("message integrity check failed"); + vec_free (hmac); return 0; } - vec_free(hmac); + vec_free (hmac); - return ikev2_decrypt_data(sa, ikep->payload, plen); + return ikev2_decrypt_data (sa, ikep->payload, plen); } static void ikev2_initial_contact_cleanup (ikev2_sa_t * sa) { - ikev2_main_t * km = &ikev2_main; - ikev2_sa_t * tmp; - u32 i, * delete = 0; - ikev2_child_sa_t * c; - u32 cpu_index = os_get_cpu_number(); + ikev2_main_t *km = &ikev2_main; + ikev2_sa_t *tmp; + u32 i, *delete = 0; + ikev2_child_sa_t *c; + u32 cpu_index = os_get_cpu_number (); if (!sa->initial_contact) return; /* find old IKE SAs with the same authenticated identity */ + /* *INDENT-OFF* */ pool_foreach (tmp, km->per_thread_data[cpu_index].sas, ({ if (tmp->i_id.type != sa->i_id.type || vec_len(tmp->i_id.data) != vec_len(sa->i_id.data) || @@ -619,297 +638,302 @@ ikev2_initial_contact_cleanup (ikev2_sa_t * sa) if (sa->rspi != tmp->rspi) vec_add1(delete, tmp - km->per_thread_data[cpu_index].sas); })); + /* *INDENT-ON* */ - for (i = 0; i < vec_len(delete); i++) + for (i = 0; i < vec_len (delete); i++) { - tmp = pool_elt_at_index(km->per_thread_data[cpu_index].sas, delete[i]); - vec_foreach(c, tmp->childs) - ikev2_delete_tunnel_interface(km->vnet_main, tmp, c); - ikev2_delete_sa(tmp); + tmp = pool_elt_at_index (km->per_thread_data[cpu_index].sas, delete[i]); + vec_foreach (c, tmp->childs) + ikev2_delete_tunnel_interface (km->vnet_main, tmp, c); + ikev2_delete_sa (tmp); } - vec_free(delete); + vec_free (delete); sa->initial_contact = 0; } static void -ikev2_process_auth_req(vlib_main_t * vm, ikev2_sa_t *sa, ike_header_t * ike) +ikev2_process_auth_req (vlib_main_t * vm, ikev2_sa_t * sa, ike_header_t * ike) { - ikev2_child_sa_t * first_child_sa; + ikev2_child_sa_t *first_child_sa; int p = 0; - u32 len = clib_net_to_host_u32(ike->length); + u32 len = clib_net_to_host_u32 (ike->length); u8 payload = ike->nextpayload; - u8 * plaintext = 0; + u8 *plaintext = 0; - ike_payload_header_t * ikep; + ike_payload_header_t *ikep; u32 plen; - clib_warning("ispi %lx rspi %lx nextpayload %x version %x " - "exchange %x flags %x msgid %x length %u", - clib_net_to_host_u64(ike->ispi), - clib_net_to_host_u64(ike->rspi), - payload, ike->version, - ike->exchange, ike->flags, - clib_net_to_host_u32(ike->msgid), - len); + clib_warning ("ispi %lx rspi %lx nextpayload %x version %x " + "exchange %x flags %x msgid %x length %u", + clib_net_to_host_u64 (ike->ispi), + clib_net_to_host_u64 (ike->rspi), + payload, ike->version, + ike->exchange, ike->flags, + clib_net_to_host_u32 (ike->msgid), len); - ikev2_calc_keys(sa); + ikev2_calc_keys (sa); - plaintext = ikev2_decrypt_sk_payload(sa, ike, &payload); + plaintext = ikev2_decrypt_sk_payload (sa, ike, &payload); if (!plaintext) { if (sa->unsupported_cp) - ikev2_set_state(sa, IKEV2_STATE_NOTIFY_AND_DELETE); + ikev2_set_state (sa, IKEV2_STATE_NOTIFY_AND_DELETE); goto cleanup_and_exit; } /* create 1st child SA */ - ikev2_sa_free_all_child_sa(&sa->childs); - vec_add2(sa->childs, first_child_sa, 1); + ikev2_sa_free_all_child_sa (&sa->childs); + vec_add2 (sa->childs, first_child_sa, 1); /* process encrypted payload */ p = 0; - while (p < vec_len(plaintext) && payload != IKEV2_PAYLOAD_NONE) + while (p < vec_len (plaintext) && payload != IKEV2_PAYLOAD_NONE) { - ikep = (ike_payload_header_t *) &plaintext[p]; - plen = clib_net_to_host_u16(ikep->length); - - if (plen < sizeof(ike_payload_header_t)) - goto cleanup_and_exit; - - if (payload == IKEV2_PAYLOAD_SA) /* 33 */ - { - clib_warning("received payload SA, len %u", plen - sizeof(*ikep)); - ikev2_sa_free_proposal_vector(&first_child_sa->i_proposals); - first_child_sa->i_proposals = ikev2_parse_sa_payload(ikep); - } - else if (payload == IKEV2_PAYLOAD_IDI) /* 35 */ - { - ike_id_payload_header_t * id = (ike_id_payload_header_t *) ikep; - - sa->i_id.type = id->id_type; - vec_free(sa->i_id.data); - vec_add(sa->i_id.data, id->payload, plen - sizeof(*id)); - - clib_warning("received payload IDi, len %u id_type %u", - plen - sizeof(*id), id->id_type); - } - else if (payload == IKEV2_PAYLOAD_AUTH) /* 39 */ - { - ike_auth_payload_header_t * a = (ike_auth_payload_header_t *) ikep; - - sa->i_auth.method = a->auth_method; - vec_free(sa->i_auth.data); - vec_add(sa->i_auth.data, a->payload, plen - sizeof(*a)); - - clib_warning("received payload AUTH, len %u auth_type %u", - plen - sizeof(*a), a->auth_method); - } - else if (payload == IKEV2_PAYLOAD_NOTIFY) /* 41 */ - { - ikev2_notify_t * n = ikev2_parse_notify_payload(ikep); - if (n->msg_type == IKEV2_NOTIFY_MSG_INITIAL_CONTACT) - { - sa->initial_contact = 1; - } - vec_free(n); - } - else if (payload == IKEV2_PAYLOAD_VENDOR) /* 43 */ - { - ikev2_parse_vendor_payload(ikep); - } - else if (payload == IKEV2_PAYLOAD_TSI) /* 44 */ - { - clib_warning("received payload TSi, len %u", plen - sizeof(*ikep)); - - vec_free(first_child_sa->tsi); - first_child_sa->tsi = ikev2_parse_ts_payload(ikep); - } - else if (payload == IKEV2_PAYLOAD_TSR) /* 45 */ - { - clib_warning("received payload TSr, len %u", plen - sizeof(*ikep)); - - vec_free(first_child_sa->tsr); - first_child_sa->tsr = ikev2_parse_ts_payload(ikep); - } + ikep = (ike_payload_header_t *) & plaintext[p]; + plen = clib_net_to_host_u16 (ikep->length); + + if (plen < sizeof (ike_payload_header_t)) + goto cleanup_and_exit; + + if (payload == IKEV2_PAYLOAD_SA) /* 33 */ + { + clib_warning ("received payload SA, len %u", plen - sizeof (*ikep)); + ikev2_sa_free_proposal_vector (&first_child_sa->i_proposals); + first_child_sa->i_proposals = ikev2_parse_sa_payload (ikep); + } + else if (payload == IKEV2_PAYLOAD_IDI) /* 35 */ + { + ike_id_payload_header_t *id = (ike_id_payload_header_t *) ikep; + + sa->i_id.type = id->id_type; + vec_free (sa->i_id.data); + vec_add (sa->i_id.data, id->payload, plen - sizeof (*id)); + + clib_warning ("received payload IDi, len %u id_type %u", + plen - sizeof (*id), id->id_type); + } + else if (payload == IKEV2_PAYLOAD_AUTH) /* 39 */ + { + ike_auth_payload_header_t *a = (ike_auth_payload_header_t *) ikep; + + sa->i_auth.method = a->auth_method; + vec_free (sa->i_auth.data); + vec_add (sa->i_auth.data, a->payload, plen - sizeof (*a)); + + clib_warning ("received payload AUTH, len %u auth_type %u", + plen - sizeof (*a), a->auth_method); + } + else if (payload == IKEV2_PAYLOAD_NOTIFY) /* 41 */ + { + ikev2_notify_t *n = ikev2_parse_notify_payload (ikep); + if (n->msg_type == IKEV2_NOTIFY_MSG_INITIAL_CONTACT) + { + sa->initial_contact = 1; + } + vec_free (n); + } + else if (payload == IKEV2_PAYLOAD_VENDOR) /* 43 */ + { + ikev2_parse_vendor_payload (ikep); + } + else if (payload == IKEV2_PAYLOAD_TSI) /* 44 */ + { + clib_warning ("received payload TSi, len %u", + plen - sizeof (*ikep)); + + vec_free (first_child_sa->tsi); + first_child_sa->tsi = ikev2_parse_ts_payload (ikep); + } + else if (payload == IKEV2_PAYLOAD_TSR) /* 45 */ + { + clib_warning ("received payload TSr, len %u", + plen - sizeof (*ikep)); + + vec_free (first_child_sa->tsr); + first_child_sa->tsr = ikev2_parse_ts_payload (ikep); + } else - { - clib_warning("unknown payload %u flags %x length %u data %u", - payload, ikep->flags, plen - 4, - format_hex_bytes, ikep->payload, plen - 4); - - if (ikep->flags & IKEV2_PAYLOAD_FLAG_CRITICAL) { - ikev2_set_state(sa, IKEV2_STATE_NOTIFY_AND_DELETE); - sa->unsupported_cp = payload; - return; - } - } + { + clib_warning ("unknown payload %u flags %x length %u data %u", + payload, ikep->flags, plen - 4, + format_hex_bytes, ikep->payload, plen - 4); + + if (ikep->flags & IKEV2_PAYLOAD_FLAG_CRITICAL) + { + ikev2_set_state (sa, IKEV2_STATE_NOTIFY_AND_DELETE); + sa->unsupported_cp = payload; + return; + } + } payload = ikep->nextpayload; p += plen; } cleanup_and_exit: - vec_free(plaintext); + vec_free (plaintext); } static void -ikev2_process_informational_req(vlib_main_t * vm, ikev2_sa_t *sa, ike_header_t * ike) +ikev2_process_informational_req (vlib_main_t * vm, ikev2_sa_t * sa, + ike_header_t * ike) { int p = 0; - u32 len = clib_net_to_host_u32(ike->length); + u32 len = clib_net_to_host_u32 (ike->length); u8 payload = ike->nextpayload; - u8 * plaintext = 0; + u8 *plaintext = 0; - ike_payload_header_t * ikep; + ike_payload_header_t *ikep; u32 plen; - clib_warning("ispi %lx rspi %lx nextpayload %x version %x " - "exchange %x flags %x msgid %x length %u", - clib_net_to_host_u64(ike->ispi), - clib_net_to_host_u64(ike->rspi), - payload, ike->version, - ike->exchange, ike->flags, - clib_net_to_host_u32(ike->msgid), - len); + clib_warning ("ispi %lx rspi %lx nextpayload %x version %x " + "exchange %x flags %x msgid %x length %u", + clib_net_to_host_u64 (ike->ispi), + clib_net_to_host_u64 (ike->rspi), + payload, ike->version, + ike->exchange, ike->flags, + clib_net_to_host_u32 (ike->msgid), len); - plaintext = ikev2_decrypt_sk_payload(sa, ike, &payload); + plaintext = ikev2_decrypt_sk_payload (sa, ike, &payload); if (!plaintext) goto cleanup_and_exit; /* process encrypted payload */ p = 0; - while (p < vec_len(plaintext) && payload != IKEV2_PAYLOAD_NONE) + while (p < vec_len (plaintext) && payload != IKEV2_PAYLOAD_NONE) { - ikep = (ike_payload_header_t *) &plaintext[p]; - plen = clib_net_to_host_u16(ikep->length); - - if (plen < sizeof(ike_payload_header_t)) - goto cleanup_and_exit; - - if (payload == IKEV2_PAYLOAD_NOTIFY) /* 41 */ - { - ikev2_notify_t * n = ikev2_parse_notify_payload(ikep); - if (n->msg_type == IKEV2_NOTIFY_MSG_AUTHENTICATION_FAILED) - ikev2_set_state(sa, IKEV2_STATE_AUTH_FAILED); - vec_free(n); - } - else if (payload == IKEV2_PAYLOAD_DELETE) /* 42 */ - { - sa->del = ikev2_parse_delete_payload(ikep); - } - else if (payload == IKEV2_PAYLOAD_VENDOR) /* 43 */ - { - ikev2_parse_vendor_payload(ikep); - } + ikep = (ike_payload_header_t *) & plaintext[p]; + plen = clib_net_to_host_u16 (ikep->length); + + if (plen < sizeof (ike_payload_header_t)) + goto cleanup_and_exit; + + if (payload == IKEV2_PAYLOAD_NOTIFY) /* 41 */ + { + ikev2_notify_t *n = ikev2_parse_notify_payload (ikep); + if (n->msg_type == IKEV2_NOTIFY_MSG_AUTHENTICATION_FAILED) + ikev2_set_state (sa, IKEV2_STATE_AUTH_FAILED); + vec_free (n); + } + else if (payload == IKEV2_PAYLOAD_DELETE) /* 42 */ + { + sa->del = ikev2_parse_delete_payload (ikep); + } + else if (payload == IKEV2_PAYLOAD_VENDOR) /* 43 */ + { + ikev2_parse_vendor_payload (ikep); + } else - { - clib_warning("unknown payload %u flags %x length %u data %u", - payload, ikep->flags, plen - 4, - format_hex_bytes, ikep->payload, plen - 4); - - if (ikep->flags & IKEV2_PAYLOAD_FLAG_CRITICAL) { - sa->unsupported_cp = payload; - return; - } - } + { + clib_warning ("unknown payload %u flags %x length %u data %u", + payload, ikep->flags, plen - 4, + format_hex_bytes, ikep->payload, plen - 4); + + if (ikep->flags & IKEV2_PAYLOAD_FLAG_CRITICAL) + { + sa->unsupported_cp = payload; + return; + } + } payload = ikep->nextpayload; p += plen; } cleanup_and_exit: - vec_free(plaintext); + vec_free (plaintext); } static void -ikev2_process_create_child_sa_req(vlib_main_t * vm, ikev2_sa_t *sa, ike_header_t * ike) +ikev2_process_create_child_sa_req (vlib_main_t * vm, ikev2_sa_t * sa, + ike_header_t * ike) { int p = 0; - u32 len = clib_net_to_host_u32(ike->length); + u32 len = clib_net_to_host_u32 (ike->length); u8 payload = ike->nextpayload; - u8 * plaintext = 0; + u8 *plaintext = 0; u8 rekeying = 0; u8 i_nonce[IKEV2_NONCE_SIZE]; - ike_payload_header_t * ikep; + ike_payload_header_t *ikep; u32 plen; - ikev2_notify_t * n = 0; - ikev2_ts_t * tsi = 0; - ikev2_ts_t * tsr = 0; - ikev2_sa_proposal_t * proposal = 0; - ikev2_child_sa_t * child_sa; - - clib_warning("ispi %lx rspi %lx nextpayload %x version %x " - "exchange %x flags %x msgid %x length %u", - clib_net_to_host_u64(ike->ispi), - clib_net_to_host_u64(ike->rspi), - payload, ike->version, - ike->exchange, ike->flags, - clib_net_to_host_u32(ike->msgid), - len); - - plaintext = ikev2_decrypt_sk_payload(sa, ike, &payload); + ikev2_notify_t *n = 0; + ikev2_ts_t *tsi = 0; + ikev2_ts_t *tsr = 0; + ikev2_sa_proposal_t *proposal = 0; + ikev2_child_sa_t *child_sa; + + clib_warning ("ispi %lx rspi %lx nextpayload %x version %x " + "exchange %x flags %x msgid %x length %u", + clib_net_to_host_u64 (ike->ispi), + clib_net_to_host_u64 (ike->rspi), + payload, ike->version, + ike->exchange, ike->flags, + clib_net_to_host_u32 (ike->msgid), len); + + plaintext = ikev2_decrypt_sk_payload (sa, ike, &payload); if (!plaintext) goto cleanup_and_exit; /* process encrypted payload */ p = 0; - while (p < vec_len(plaintext) && payload != IKEV2_PAYLOAD_NONE) + while (p < vec_len (plaintext) && payload != IKEV2_PAYLOAD_NONE) { - ikep = (ike_payload_header_t *) &plaintext[p]; - plen = clib_net_to_host_u16(ikep->length); + ikep = (ike_payload_header_t *) & plaintext[p]; + plen = clib_net_to_host_u16 (ikep->length); - if (plen < sizeof(ike_payload_header_t)) - goto cleanup_and_exit; + if (plen < sizeof (ike_payload_header_t)) + goto cleanup_and_exit; else if (payload == IKEV2_PAYLOAD_SA) - { - proposal = ikev2_parse_sa_payload(ikep); - } + { + proposal = ikev2_parse_sa_payload (ikep); + } else if (payload == IKEV2_PAYLOAD_NOTIFY) - { - n = ikev2_parse_notify_payload(ikep); - if (n->msg_type == IKEV2_NOTIFY_MSG_REKEY_SA) - { - rekeying = 1; - } - } + { + n = ikev2_parse_notify_payload (ikep); + if (n->msg_type == IKEV2_NOTIFY_MSG_REKEY_SA) + { + rekeying = 1; + } + } else if (payload == IKEV2_PAYLOAD_DELETE) - { - sa->del = ikev2_parse_delete_payload(ikep); - } + { + sa->del = ikev2_parse_delete_payload (ikep); + } else if (payload == IKEV2_PAYLOAD_VENDOR) - { - ikev2_parse_vendor_payload(ikep); - } + { + ikev2_parse_vendor_payload (ikep); + } else if (payload == IKEV2_PAYLOAD_NONCE) - { - clib_memcpy(i_nonce, ikep->payload, plen - sizeof(*ikep)); - } + { + clib_memcpy (i_nonce, ikep->payload, plen - sizeof (*ikep)); + } else if (payload == IKEV2_PAYLOAD_TSI) - { - tsi = ikev2_parse_ts_payload(ikep); - } + { + tsi = ikev2_parse_ts_payload (ikep); + } else if (payload == IKEV2_PAYLOAD_TSR) - { - tsr = ikev2_parse_ts_payload(ikep); - } + { + tsr = ikev2_parse_ts_payload (ikep); + } else - { - clib_warning("unknown payload %u flags %x length %u data %u", - payload, ikep->flags, plen - 4, - format_hex_bytes, ikep->payload, plen - 4); - - if (ikep->flags & IKEV2_PAYLOAD_FLAG_CRITICAL) { - sa->unsupported_cp = payload; - return; - } - } + { + clib_warning ("unknown payload %u flags %x length %u data %u", + payload, ikep->flags, plen - 4, + format_hex_bytes, ikep->payload, plen - 4); + + if (ikep->flags & IKEV2_PAYLOAD_FLAG_CRITICAL) + { + sa->unsupported_cp = payload; + return; + } + } payload = ikep->nextpayload; p += plen; @@ -917,46 +941,48 @@ ikev2_process_create_child_sa_req(vlib_main_t * vm, ikev2_sa_t *sa, ike_header_t if (rekeying) { - ikev2_rekey_t * rekey; - child_sa = ikev2_sa_get_child(sa, n->spi, n->protocol_id); + ikev2_rekey_t *rekey; + child_sa = ikev2_sa_get_child (sa, n->spi, n->protocol_id); if (!child_sa) - { - clib_warning("child SA spi %lx not found", n->spi); - goto cleanup_and_exit; - } - vec_add2(sa->rekey, rekey, 1); + { + clib_warning ("child SA spi %lx not found", n->spi); + goto cleanup_and_exit; + } + vec_add2 (sa->rekey, rekey, 1); rekey->protocol_id = n->protocol_id; rekey->spi = n->spi; rekey->i_proposal = proposal; - rekey->r_proposal = ikev2_select_proposal(proposal, IKEV2_PROTOCOL_ESP); + rekey->r_proposal = + ikev2_select_proposal (proposal, IKEV2_PROTOCOL_ESP); rekey->tsi = tsi; rekey->tsr = tsr; /* update Ni */ - vec_free(sa->i_nonce); - vec_add(sa->i_nonce, i_nonce, IKEV2_NONCE_SIZE); + vec_free (sa->i_nonce); + vec_add (sa->i_nonce, i_nonce, IKEV2_NONCE_SIZE); /* generate new Nr */ - vec_free(sa->r_nonce); - sa->r_nonce = vec_new(u8, IKEV2_NONCE_SIZE); - RAND_bytes((u8 *) sa->r_nonce, IKEV2_NONCE_SIZE); + vec_free (sa->r_nonce); + sa->r_nonce = vec_new (u8, IKEV2_NONCE_SIZE); + RAND_bytes ((u8 *) sa->r_nonce, IKEV2_NONCE_SIZE); } cleanup_and_exit: - vec_free(plaintext); - vec_free(n); + vec_free (plaintext); + vec_free (n); } static u8 * -ikev2_sa_generate_authmsg(ikev2_sa_t *sa, int is_responder) +ikev2_sa_generate_authmsg (ikev2_sa_t * sa, int is_responder) { - u8 * authmsg = 0; - u8 * data; - u8 * nonce; - ikev2_id_t * id; - u8 * key; - u8 * packet_data; - ikev2_sa_transform_t * tr_prf; + u8 *authmsg = 0; + u8 *data; + u8 *nonce; + ikev2_id_t *id; + u8 *key; + u8 *packet_data; + ikev2_sa_transform_t *tr_prf; - tr_prf = ikev2_sa_get_td_for_type(sa->r_proposals, IKEV2_TRANSFORM_TYPE_PRF); + tr_prf = + ikev2_sa_get_td_for_type (sa->r_proposals, IKEV2_TRANSFORM_TYPE_PRF); if (is_responder) { @@ -973,22 +999,22 @@ ikev2_sa_generate_authmsg(ikev2_sa_t *sa, int is_responder) packet_data = sa->last_sa_init_req_packet_data; } - data = vec_new(u8, 4); + data = vec_new (u8, 4); data[0] = id->type; - vec_append(data, id->data); + vec_append (data, id->data); - u8 * id_hash = ikev2_calc_prf(tr_prf, key, data); - vec_append(authmsg, packet_data); - vec_append(authmsg, nonce); - vec_append(authmsg, id_hash); - vec_free(id_hash); - vec_free(data); + u8 *id_hash = ikev2_calc_prf (tr_prf, key, data); + vec_append (authmsg, packet_data); + vec_append (authmsg, nonce); + vec_append (authmsg, id_hash); + vec_free (id_hash); + vec_free (data); return authmsg; } static int -ikev2_ts_cmp(ikev2_ts_t * ts1, ikev2_ts_t * ts2) +ikev2_ts_cmp (ikev2_ts_t * ts1, ikev2_ts_t * ts2) { if (ts1->ts_type == ts2->ts_type && ts1->protocol_id == ts2->protocol_id && ts1->start_port == ts2->start_port && ts1->end_port == ts2->end_port && @@ -1000,12 +1026,13 @@ ikev2_ts_cmp(ikev2_ts_t * ts1, ikev2_ts_t * ts2) } static void -ikev2_sa_match_ts(ikev2_sa_t *sa) +ikev2_sa_match_ts (ikev2_sa_t * sa) { - ikev2_main_t * km = &ikev2_main; - ikev2_profile_t * p; - ikev2_ts_t * ts, * tsi = 0, * tsr = 0; + ikev2_main_t *km = &ikev2_main; + ikev2_profile_t *p; + ikev2_ts_t *ts, *tsi = 0, *tsr = 0; + /* *INDENT-OFF* */ pool_foreach (p, km->profiles, ({ /* check id */ @@ -1034,44 +1061,48 @@ ikev2_sa_match_ts(ikev2_sa_t *sa) break; })); + /* *INDENT-ON* */ if (tsi && tsr) { - vec_free(sa->childs[0].tsi); - vec_free(sa->childs[0].tsr); + vec_free (sa->childs[0].tsi); + vec_free (sa->childs[0].tsr); sa->childs[0].tsi = tsi; sa->childs[0].tsr = tsr; } else { - vec_free(tsi); - vec_free(tsr); - ikev2_set_state(sa, IKEV2_STATE_TS_UNACCEPTABLE); + vec_free (tsi); + vec_free (tsr); + ikev2_set_state (sa, IKEV2_STATE_TS_UNACCEPTABLE); } } static void -ikev2_sa_auth(ikev2_sa_t *sa) +ikev2_sa_auth (ikev2_sa_t * sa) { - ikev2_main_t * km = &ikev2_main; - ikev2_profile_t * p, * sel_p = 0; - u8 * authmsg, * key_pad, * psk = 0, * auth = 0; - ikev2_sa_transform_t * tr_prf; + ikev2_main_t *km = &ikev2_main; + ikev2_profile_t *p, *sel_p = 0; + u8 *authmsg, *key_pad, *psk = 0, *auth = 0; + ikev2_sa_transform_t *tr_prf; - tr_prf = ikev2_sa_get_td_for_type(sa->r_proposals, IKEV2_TRANSFORM_TYPE_PRF); + tr_prf = + ikev2_sa_get_td_for_type (sa->r_proposals, IKEV2_TRANSFORM_TYPE_PRF); /* only shared key and rsa signature */ if (!(sa->i_auth.method == IKEV2_AUTH_METHOD_SHARED_KEY_MIC || - sa->i_auth.method == IKEV2_AUTH_METHOD_RSA_SIG)) + sa->i_auth.method == IKEV2_AUTH_METHOD_RSA_SIG)) { - clib_warning("unsupported authentication method %u", sa->i_auth.method); - ikev2_set_state(sa, IKEV2_STATE_AUTH_FAILED); + clib_warning ("unsupported authentication method %u", + sa->i_auth.method); + ikev2_set_state (sa, IKEV2_STATE_AUTH_FAILED); return; } - key_pad = format(0, "%s", IKEV2_KEY_PAD); - authmsg = ikev2_sa_generate_authmsg(sa, 0); + key_pad = format (0, "%s", IKEV2_KEY_PAD); + authmsg = ikev2_sa_generate_authmsg (sa, 0); + /* *INDENT-OFF* */ pool_foreach (p, km->profiles, ({ /* check id */ @@ -1114,56 +1145,58 @@ ikev2_sa_auth(ikev2_sa_t *sa) vec_free(auth); vec_free(psk); })); + /* *INDENT-ON* */ - vec_free(authmsg); + vec_free (authmsg); if (sa->state == IKEV2_STATE_AUTHENTICATED) { - vec_free(sa->r_id.data); - sa->r_id.data = vec_dup(sel_p->loc_id.data); + vec_free (sa->r_id.data); + sa->r_id.data = vec_dup (sel_p->loc_id.data); sa->r_id.type = sel_p->loc_id.type; /* generate our auth data */ - authmsg = ikev2_sa_generate_authmsg(sa, 1); + authmsg = ikev2_sa_generate_authmsg (sa, 1); if (sel_p->auth.method == IKEV2_AUTH_METHOD_SHARED_KEY_MIC) - { - sa->r_auth.data = ikev2_calc_prf(tr_prf, psk, authmsg); - sa->r_auth.method = IKEV2_AUTH_METHOD_SHARED_KEY_MIC; - } + { + sa->r_auth.data = ikev2_calc_prf (tr_prf, psk, authmsg); + sa->r_auth.method = IKEV2_AUTH_METHOD_SHARED_KEY_MIC; + } else if (sel_p->auth.method == IKEV2_AUTH_METHOD_RSA_SIG) - { - sa->r_auth.data = ikev2_calc_sign(km->pkey, authmsg); - sa->r_auth.method = IKEV2_AUTH_METHOD_RSA_SIG; - } - vec_free(authmsg); + { + sa->r_auth.data = ikev2_calc_sign (km->pkey, authmsg); + sa->r_auth.method = IKEV2_AUTH_METHOD_RSA_SIG; + } + vec_free (authmsg); /* select transforms for 1st child sa */ - ikev2_sa_free_proposal_vector(&sa->childs[0].r_proposals); - sa->childs[0].r_proposals = ikev2_select_proposal(sa->childs[0].i_proposals, - IKEV2_PROTOCOL_ESP); + ikev2_sa_free_proposal_vector (&sa->childs[0].r_proposals); + sa->childs[0].r_proposals = + ikev2_select_proposal (sa->childs[0].i_proposals, IKEV2_PROTOCOL_ESP); } else { - ikev2_set_state(sa, IKEV2_STATE_AUTH_FAILED); + ikev2_set_state (sa, IKEV2_STATE_AUTH_FAILED); } - vec_free(psk); - vec_free(key_pad); + vec_free (psk); + vec_free (key_pad); } static int -ikev2_create_tunnel_interface(vnet_main_t * vnm, ikev2_sa_t *sa, ikev2_child_sa_t * child) +ikev2_create_tunnel_interface (vnet_main_t * vnm, ikev2_sa_t * sa, + ikev2_child_sa_t * child) { ipsec_add_del_tunnel_args_t a; - ikev2_sa_transform_t * tr; - u8 encr_type = 0; + ikev2_sa_transform_t *tr; + u8 encr_type = 0; if (!child->r_proposals) { - ikev2_set_state(sa, IKEV2_STATE_NO_PROPOSAL_CHOSEN); + ikev2_set_state (sa, IKEV2_STATE_NO_PROPOSAL_CHOSEN); return 1; } - memset(&a, 0, sizeof(a)); + memset (&a, 0, sizeof (a)); a.is_add = 1; a.local_ip.as_u32 = sa->raddr.as_u32; a.remote_ip.as_u32 = sa->iaddr.as_u32; @@ -1171,86 +1204,90 @@ ikev2_create_tunnel_interface(vnet_main_t * vnm, ikev2_sa_t *sa, ikev2_child_sa_ a.remote_spi = child->r_proposals[0].spi; a.anti_replay = 1; - tr = ikev2_sa_get_td_for_type(child->r_proposals, IKEV2_TRANSFORM_TYPE_ESN); + tr = + ikev2_sa_get_td_for_type (child->r_proposals, IKEV2_TRANSFORM_TYPE_ESN); if (tr) - a.esn = tr->esn_type; + a.esn = tr->esn_type; else a.esn = 0; - tr = ikev2_sa_get_td_for_type(child->r_proposals, IKEV2_TRANSFORM_TYPE_ENCR); + tr = + ikev2_sa_get_td_for_type (child->r_proposals, IKEV2_TRANSFORM_TYPE_ENCR); if (tr) { if (tr->encr_type == IKEV2_TRANSFORM_ENCR_TYPE_AES_CBC && tr->key_len) - { - switch (tr->key_len) - { - case 16: - encr_type = IPSEC_CRYPTO_ALG_AES_CBC_128; - break; - case 24: - encr_type = IPSEC_CRYPTO_ALG_AES_CBC_192; - break; - case 32: - encr_type = IPSEC_CRYPTO_ALG_AES_CBC_256; - break; - default: - ikev2_set_state(sa, IKEV2_STATE_NO_PROPOSAL_CHOSEN); - return 1; - break; - } - } + { + switch (tr->key_len) + { + case 16: + encr_type = IPSEC_CRYPTO_ALG_AES_CBC_128; + break; + case 24: + encr_type = IPSEC_CRYPTO_ALG_AES_CBC_192; + break; + case 32: + encr_type = IPSEC_CRYPTO_ALG_AES_CBC_256; + break; + default: + ikev2_set_state (sa, IKEV2_STATE_NO_PROPOSAL_CHOSEN); + return 1; + break; + } + } else - { - ikev2_set_state(sa, IKEV2_STATE_NO_PROPOSAL_CHOSEN); - return 1; - } + { + ikev2_set_state (sa, IKEV2_STATE_NO_PROPOSAL_CHOSEN); + return 1; + } } else { - ikev2_set_state(sa, IKEV2_STATE_NO_PROPOSAL_CHOSEN); + ikev2_set_state (sa, IKEV2_STATE_NO_PROPOSAL_CHOSEN); return 1; } - tr = ikev2_sa_get_td_for_type(child->r_proposals, IKEV2_TRANSFORM_TYPE_INTEG); + tr = + ikev2_sa_get_td_for_type (child->r_proposals, IKEV2_TRANSFORM_TYPE_INTEG); if (tr) { if (tr->integ_type != IKEV2_TRANSFORM_INTEG_TYPE_AUTH_HMAC_SHA1_96) - { - ikev2_set_state(sa, IKEV2_STATE_NO_PROPOSAL_CHOSEN); - return 1; - } + { + ikev2_set_state (sa, IKEV2_STATE_NO_PROPOSAL_CHOSEN); + return 1; + } } else { - ikev2_set_state(sa, IKEV2_STATE_NO_PROPOSAL_CHOSEN); + ikev2_set_state (sa, IKEV2_STATE_NO_PROPOSAL_CHOSEN); return 1; } - ikev2_calc_child_keys(sa, child); + ikev2_calc_child_keys (sa, child); a.integ_alg = IPSEC_INTEG_ALG_SHA1_96; - a.local_integ_key_len = vec_len(child->sk_ar); - clib_memcpy(a.local_integ_key, child->sk_ar, a.local_integ_key_len); - a.remote_integ_key_len = vec_len(child->sk_ai); - clib_memcpy(a.remote_integ_key, child->sk_ai, a.remote_integ_key_len); + a.local_integ_key_len = vec_len (child->sk_ar); + clib_memcpy (a.local_integ_key, child->sk_ar, a.local_integ_key_len); + a.remote_integ_key_len = vec_len (child->sk_ai); + clib_memcpy (a.remote_integ_key, child->sk_ai, a.remote_integ_key_len); a.crypto_alg = encr_type; - a.local_crypto_key_len = vec_len(child->sk_er); - clib_memcpy(a.local_crypto_key, child->sk_er, a.local_crypto_key_len); - a.remote_crypto_key_len = vec_len(child->sk_ei); - clib_memcpy(a.remote_crypto_key, child->sk_ei, a.remote_crypto_key_len); + a.local_crypto_key_len = vec_len (child->sk_er); + clib_memcpy (a.local_crypto_key, child->sk_er, a.local_crypto_key_len); + a.remote_crypto_key_len = vec_len (child->sk_ei); + clib_memcpy (a.remote_crypto_key, child->sk_ei, a.remote_crypto_key_len); - ipsec_add_del_tunnel_if(&a); + ipsec_add_del_tunnel_if (&a); return 0; } static int -ikev2_delete_tunnel_interface(vnet_main_t * vnm, ikev2_sa_t *sa, ikev2_child_sa_t * child) +ikev2_delete_tunnel_interface (vnet_main_t * vnm, ikev2_sa_t * sa, + ikev2_child_sa_t * child) { ipsec_add_del_tunnel_args_t a; - if (!vec_len(child->r_proposals)) + if (!vec_len (child->r_proposals)) return 0; a.is_add = 0; @@ -1259,205 +1296,217 @@ ikev2_delete_tunnel_interface(vnet_main_t * vnm, ikev2_sa_t *sa, ikev2_child_sa_ a.local_spi = child->i_proposals[0].spi; a.remote_spi = child->r_proposals[0].spi; - ipsec_add_del_tunnel_if(&a); + ipsec_add_del_tunnel_if (&a); return 0; } static u32 -ikev2_generate_resp(ikev2_sa_t *sa, ike_header_t * ike) +ikev2_generate_resp (ikev2_sa_t * sa, ike_header_t * ike) { - v8 * integ = 0; - ike_payload_header_t * ph; + v8 *integ = 0; + ike_payload_header_t *ph; u16 plen; u32 tlen = 0; - ikev2_sa_transform_t * tr_encr, *tr_integ; - tr_encr = ikev2_sa_get_td_for_type(sa->r_proposals, IKEV2_TRANSFORM_TYPE_ENCR); - tr_integ = ikev2_sa_get_td_for_type(sa->r_proposals, IKEV2_TRANSFORM_TYPE_INTEG); + ikev2_sa_transform_t *tr_encr, *tr_integ; + tr_encr = + ikev2_sa_get_td_for_type (sa->r_proposals, IKEV2_TRANSFORM_TYPE_ENCR); + tr_integ = + ikev2_sa_get_td_for_type (sa->r_proposals, IKEV2_TRANSFORM_TYPE_INTEG); - ikev2_payload_chain_t * chain = 0; - ikev2_payload_new_chain(chain); + ikev2_payload_chain_t *chain = 0; + ikev2_payload_new_chain (chain); if (ike->exchange == IKEV2_EXCHANGE_SA_INIT) { if (sa->r_proposals == 0) - { - ikev2_payload_add_notify(chain, IKEV2_NOTIFY_MSG_NO_PROPOSAL_CHOSEN, 0); - ikev2_set_state(sa, IKEV2_STATE_NOTIFY_AND_DELETE); - } + { + ikev2_payload_add_notify (chain, + IKEV2_NOTIFY_MSG_NO_PROPOSAL_CHOSEN, 0); + ikev2_set_state (sa, IKEV2_STATE_NOTIFY_AND_DELETE); + } else if (sa->dh_group == IKEV2_TRANSFORM_DH_TYPE_NONE) - { - u8 * data = vec_new(u8, 2); - ikev2_sa_transform_t * tr_dh; - tr_dh = ikev2_sa_get_td_for_type(sa->r_proposals, IKEV2_TRANSFORM_TYPE_DH); - ASSERT(tr_dh && tr_dh->dh_type); - - data[0] = (tr_dh->dh_type >> 8) & 0xff; - data[1] = (tr_dh->dh_type) & 0xff; - - ikev2_payload_add_notify(chain, IKEV2_NOTIFY_MSG_INVALID_KE_PAYLOAD, data); - vec_free(data); - ikev2_set_state(sa, IKEV2_STATE_NOTIFY_AND_DELETE); - } + { + u8 *data = vec_new (u8, 2); + ikev2_sa_transform_t *tr_dh; + tr_dh = + ikev2_sa_get_td_for_type (sa->r_proposals, + IKEV2_TRANSFORM_TYPE_DH); + ASSERT (tr_dh && tr_dh->dh_type); + + data[0] = (tr_dh->dh_type >> 8) & 0xff; + data[1] = (tr_dh->dh_type) & 0xff; + + ikev2_payload_add_notify (chain, + IKEV2_NOTIFY_MSG_INVALID_KE_PAYLOAD, + data); + vec_free (data); + ikev2_set_state (sa, IKEV2_STATE_NOTIFY_AND_DELETE); + } else if (sa->state == IKEV2_STATE_NOTIFY_AND_DELETE) - { - u8 * data = vec_new(u8, 1); - - data[0] = sa->unsupported_cp; - ikev2_payload_add_notify(chain, - IKEV2_NOTIFY_MSG_UNSUPPORTED_CRITICAL_PAYLOAD, - data); - vec_free(data); - } + { + u8 *data = vec_new (u8, 1); + + data[0] = sa->unsupported_cp; + ikev2_payload_add_notify (chain, + IKEV2_NOTIFY_MSG_UNSUPPORTED_CRITICAL_PAYLOAD, + data); + vec_free (data); + } else - { - ike->rspi = clib_host_to_net_u64(sa->rspi); - ikev2_payload_add_sa(chain, sa->r_proposals); - ikev2_payload_add_ke(chain, sa->dh_group, sa->r_dh_data); - ikev2_payload_add_nonce(chain, sa->r_nonce); - } + { + ike->rspi = clib_host_to_net_u64 (sa->rspi); + ikev2_payload_add_sa (chain, sa->r_proposals); + ikev2_payload_add_ke (chain, sa->dh_group, sa->r_dh_data); + ikev2_payload_add_nonce (chain, sa->r_nonce); + } } else if (ike->exchange == IKEV2_EXCHANGE_IKE_AUTH) { if (sa->state == IKEV2_STATE_AUTHENTICATED) - { - ikev2_payload_add_id(chain, &sa->r_id, IKEV2_PAYLOAD_IDR); - ikev2_payload_add_auth(chain, &sa->r_auth); - ikev2_payload_add_sa(chain, sa->childs[0].r_proposals); - ikev2_payload_add_ts(chain, sa->childs[0].tsi, IKEV2_PAYLOAD_TSI); - ikev2_payload_add_ts(chain, sa->childs[0].tsr, IKEV2_PAYLOAD_TSR); - } + { + ikev2_payload_add_id (chain, &sa->r_id, IKEV2_PAYLOAD_IDR); + ikev2_payload_add_auth (chain, &sa->r_auth); + ikev2_payload_add_sa (chain, sa->childs[0].r_proposals); + ikev2_payload_add_ts (chain, sa->childs[0].tsi, IKEV2_PAYLOAD_TSI); + ikev2_payload_add_ts (chain, sa->childs[0].tsr, IKEV2_PAYLOAD_TSR); + } else if (sa->state == IKEV2_STATE_AUTH_FAILED) - { - ikev2_payload_add_notify(chain, IKEV2_NOTIFY_MSG_AUTHENTICATION_FAILED, 0); - ikev2_set_state(sa, IKEV2_STATE_NOTIFY_AND_DELETE); - } + { + ikev2_payload_add_notify (chain, + IKEV2_NOTIFY_MSG_AUTHENTICATION_FAILED, + 0); + ikev2_set_state (sa, IKEV2_STATE_NOTIFY_AND_DELETE); + } else if (sa->state == IKEV2_STATE_TS_UNACCEPTABLE) - { - ikev2_payload_add_notify(chain, IKEV2_NOTIFY_MSG_TS_UNACCEPTABLE, 0); - ikev2_payload_add_id(chain, &sa->r_id, IKEV2_PAYLOAD_IDR); - ikev2_payload_add_auth(chain, &sa->r_auth); - } + { + ikev2_payload_add_notify (chain, IKEV2_NOTIFY_MSG_TS_UNACCEPTABLE, + 0); + ikev2_payload_add_id (chain, &sa->r_id, IKEV2_PAYLOAD_IDR); + ikev2_payload_add_auth (chain, &sa->r_auth); + } else if (sa->state == IKEV2_STATE_NO_PROPOSAL_CHOSEN) - { - ikev2_payload_add_notify(chain, IKEV2_NOTIFY_MSG_NO_PROPOSAL_CHOSEN, 0); - ikev2_payload_add_id(chain, &sa->r_id, IKEV2_PAYLOAD_IDR); - ikev2_payload_add_auth(chain, &sa->r_auth); - ikev2_payload_add_ts(chain, sa->childs[0].tsi, IKEV2_PAYLOAD_TSI); - ikev2_payload_add_ts(chain, sa->childs[0].tsr, IKEV2_PAYLOAD_TSR); - } + { + ikev2_payload_add_notify (chain, + IKEV2_NOTIFY_MSG_NO_PROPOSAL_CHOSEN, 0); + ikev2_payload_add_id (chain, &sa->r_id, IKEV2_PAYLOAD_IDR); + ikev2_payload_add_auth (chain, &sa->r_auth); + ikev2_payload_add_ts (chain, sa->childs[0].tsi, IKEV2_PAYLOAD_TSI); + ikev2_payload_add_ts (chain, sa->childs[0].tsr, IKEV2_PAYLOAD_TSR); + } else if (sa->state == IKEV2_STATE_NOTIFY_AND_DELETE) - { - u8 * data = vec_new(u8, 1); - - data[0] = sa->unsupported_cp; - ikev2_payload_add_notify(chain, - IKEV2_NOTIFY_MSG_UNSUPPORTED_CRITICAL_PAYLOAD, - data); - vec_free(data); - } + { + u8 *data = vec_new (u8, 1); + + data[0] = sa->unsupported_cp; + ikev2_payload_add_notify (chain, + IKEV2_NOTIFY_MSG_UNSUPPORTED_CRITICAL_PAYLOAD, + data); + vec_free (data); + } else - { - ikev2_set_state(sa, IKEV2_STATE_DELETED); - goto done; - } + { + ikev2_set_state (sa, IKEV2_STATE_DELETED); + goto done; + } } else if (ike->exchange == IKEV2_EXCHANGE_INFORMATIONAL) { /* if pending delete */ if (sa->del) - { - /* The response to a request that deletes the IKE SA is an empty - INFORMATIONAL response. */ - if (sa->del[0].protocol_id == IKEV2_PROTOCOL_IKE) - { - ikev2_set_state(sa, IKEV2_STATE_NOTIFY_AND_DELETE); - } - /* The response to a request that deletes ESP or AH SAs will contain - delete payloads for the paired SAs going in the other direction. */ - else - { - ikev2_payload_add_delete(chain, sa->del); - } - vec_free(sa->del); - sa->del = 0; - } + { + /* The response to a request that deletes the IKE SA is an empty + INFORMATIONAL response. */ + if (sa->del[0].protocol_id == IKEV2_PROTOCOL_IKE) + { + ikev2_set_state (sa, IKEV2_STATE_NOTIFY_AND_DELETE); + } + /* The response to a request that deletes ESP or AH SAs will contain + delete payloads for the paired SAs going in the other direction. */ + else + { + ikev2_payload_add_delete (chain, sa->del); + } + vec_free (sa->del); + sa->del = 0; + } /* received N(AUTHENTICATION_FAILED) */ else if (sa->state == IKEV2_STATE_AUTH_FAILED) - { - ikev2_set_state(sa, IKEV2_STATE_DELETED); - goto done; - } + { + ikev2_set_state (sa, IKEV2_STATE_DELETED); + goto done; + } /* received unsupported critical payload */ else if (sa->unsupported_cp) - { - u8 * data = vec_new(u8, 1); - - data[0] = sa->unsupported_cp; - ikev2_payload_add_notify(chain, - IKEV2_NOTIFY_MSG_UNSUPPORTED_CRITICAL_PAYLOAD, - data); - vec_free(data); - sa->unsupported_cp = 0; - } + { + u8 *data = vec_new (u8, 1); + + data[0] = sa->unsupported_cp; + ikev2_payload_add_notify (chain, + IKEV2_NOTIFY_MSG_UNSUPPORTED_CRITICAL_PAYLOAD, + data); + vec_free (data); + sa->unsupported_cp = 0; + } /* else send empty response */ } else if (ike->exchange == IKEV2_EXCHANGE_CREATE_CHILD_SA) { if (sa->rekey) - { - ikev2_payload_add_sa(chain, sa->rekey[0].r_proposal); - ikev2_payload_add_nonce(chain, sa->r_nonce); - ikev2_payload_add_ts(chain, sa->rekey[0].tsi, IKEV2_PAYLOAD_TSI); - ikev2_payload_add_ts(chain, sa->rekey[0].tsr, IKEV2_PAYLOAD_TSR); - vec_del1(sa->rekey, 0); - } + { + ikev2_payload_add_sa (chain, sa->rekey[0].r_proposal); + ikev2_payload_add_nonce (chain, sa->r_nonce); + ikev2_payload_add_ts (chain, sa->rekey[0].tsi, IKEV2_PAYLOAD_TSI); + ikev2_payload_add_ts (chain, sa->rekey[0].tsr, IKEV2_PAYLOAD_TSR); + vec_del1 (sa->rekey, 0); + } else if (sa->unsupported_cp) - { - u8 * data = vec_new(u8, 1); - - data[0] = sa->unsupported_cp; - ikev2_payload_add_notify(chain, - IKEV2_NOTIFY_MSG_UNSUPPORTED_CRITICAL_PAYLOAD, - data); - vec_free(data); - sa->unsupported_cp = 0; - } + { + u8 *data = vec_new (u8, 1); + + data[0] = sa->unsupported_cp; + ikev2_payload_add_notify (chain, + IKEV2_NOTIFY_MSG_UNSUPPORTED_CRITICAL_PAYLOAD, + data); + vec_free (data); + sa->unsupported_cp = 0; + } else - { - ikev2_payload_add_notify(chain, IKEV2_NOTIFY_MSG_NO_ADDITIONAL_SAS, 0); - } + { + ikev2_payload_add_notify (chain, IKEV2_NOTIFY_MSG_NO_ADDITIONAL_SAS, + 0); + } } /* IKEv2 header */ ike->version = IKE_VERSION_2; ike->flags = IKEV2_HDR_FLAG_RESPONSE; ike->nextpayload = IKEV2_PAYLOAD_SK; - tlen = sizeof(*ike); + tlen = sizeof (*ike); if (ike->exchange == IKEV2_EXCHANGE_SA_INIT) { - tlen += vec_len(chain->data); + tlen += vec_len (chain->data); ike->nextpayload = chain->first_payload_type; - ike->length = clib_host_to_net_u32(tlen); - clib_memcpy(ike->payload, chain->data, vec_len(chain->data)); + ike->length = clib_host_to_net_u32 (tlen); + clib_memcpy (ike->payload, chain->data, vec_len (chain->data)); /* store whole IKE payload - needed for PSK auth */ - vec_free(sa->last_sa_init_res_packet_data); - vec_add(sa->last_sa_init_res_packet_data, ike, tlen); + vec_free (sa->last_sa_init_res_packet_data); + vec_add (sa->last_sa_init_res_packet_data, ike, tlen); } else { - ikev2_payload_chain_add_padding(chain, tr_encr->block_size); + ikev2_payload_chain_add_padding (chain, tr_encr->block_size); /* SK payload */ - plen = sizeof(*ph); - ph = (ike_payload_header_t *) &ike->payload[0]; + plen = sizeof (*ph); + ph = (ike_payload_header_t *) & ike->payload[0]; ph->nextpayload = chain->first_payload_type; ph->flags = 0; - int enc_len = ikev2_encrypt_data(sa, chain->data, ph->payload); + int enc_len = ikev2_encrypt_data (sa, chain->data, ph->payload); plen += enc_len; /* add space for hmac */ @@ -1465,36 +1514,36 @@ ikev2_generate_resp(ikev2_sa_t *sa, ike_header_t * ike) tlen += plen; /* payload and total length */ - ph->length = clib_host_to_net_u16(plen); - ike->length = clib_host_to_net_u32(tlen); + ph->length = clib_host_to_net_u16 (plen); + ike->length = clib_host_to_net_u32 (tlen); /* calc integrity data for whole packet except hash itself */ - integ = ikev2_calc_integr(tr_integ, sa->sk_ar, (u8 *) ike, - tlen - tr_integ->key_trunc); + integ = ikev2_calc_integr (tr_integ, sa->sk_ar, (u8 *) ike, + tlen - tr_integ->key_trunc); - clib_memcpy(ike->payload + tlen - tr_integ->key_trunc - sizeof(*ike), - integ, tr_integ->key_trunc); + clib_memcpy (ike->payload + tlen - tr_integ->key_trunc - sizeof (*ike), + integ, tr_integ->key_trunc); /* store whole IKE payload - needed for retransmit */ - vec_free(sa->last_res_packet_data); - vec_add(sa->last_res_packet_data, ike, tlen); + vec_free (sa->last_res_packet_data); + vec_add (sa->last_res_packet_data, ike, tlen); } done: ikev2_payload_destroy_chain (chain); - vec_free(integ); + vec_free (integ); return tlen; } static int ikev2_retransmit_sa_init (ike_header_t * ike, - ip4_address_t iaddr, - ip4_address_t raddr) + ip4_address_t iaddr, ip4_address_t raddr) { - ikev2_main_t * km = &ikev2_main; - ikev2_sa_t * sa; - u32 cpu_index = os_get_cpu_number(); + ikev2_main_t *km = &ikev2_main; + ikev2_sa_t *sa; + u32 cpu_index = os_get_cpu_number (); + /* *INDENT-OFF* */ pool_foreach (sa, km->per_thread_data[cpu_index].sas, ({ if (sa->ispi == clib_net_to_host_u64(ike->ispi) && sa->iaddr.as_u32 == iaddr.as_u32 && @@ -1550,6 +1599,7 @@ ikev2_retransmit_sa_init (ike_header_t * ike, } } })); + /* *INDENT-ON* */ /* req is not retransmit */ return 0; @@ -1558,7 +1608,7 @@ ikev2_retransmit_sa_init (ike_header_t * ike, static int ikev2_retransmit_resp (ikev2_sa_t * sa, ike_header_t * ike) { - u32 msg_id = clib_net_to_host_u32(ike->msgid); + u32 msg_id = clib_net_to_host_u32 (ike->msgid); /* new req */ if (msg_id > sa->last_msg_id) @@ -1569,8 +1619,8 @@ ikev2_retransmit_resp (ikev2_sa_t * sa, ike_header_t * ike) /* retransmitted req */ else if (msg_id == sa->last_msg_id) { - ike_header_t * tmp; - tmp = (ike_header_t*)sa->last_res_packet_data; + ike_header_t *tmp; + tmp = (ike_header_t *) sa->last_res_packet_data; ike->ispi = tmp->ispi; ike->rspi = tmp->rspi; ike->nextpayload = tmp->nextpayload; @@ -1579,34 +1629,33 @@ ikev2_retransmit_resp (ikev2_sa_t * sa, ike_header_t * ike) ike->flags = tmp->flags; ike->msgid = tmp->msgid; ike->length = tmp->length; - clib_memcpy(ike->payload, tmp->payload, - clib_net_to_host_u32(tmp->length) - sizeof(*ike)); - clib_warning("IKE msgid %u retransmit from %U to %U", - msg_id, - format_ip4_address, &sa->raddr, - format_ip4_address, &sa->iaddr); + clib_memcpy (ike->payload, tmp->payload, + clib_net_to_host_u32 (tmp->length) - sizeof (*ike)); + clib_warning ("IKE msgid %u retransmit from %U to %U", + msg_id, + format_ip4_address, &sa->raddr, + format_ip4_address, &sa->iaddr); return 1; } /* old req ignore */ else { - clib_warning("IKE msgid %u req ignore from %U to %U", - msg_id, - format_ip4_address, &sa->raddr, - format_ip4_address, &sa->iaddr); + clib_warning ("IKE msgid %u req ignore from %U to %U", + msg_id, + format_ip4_address, &sa->raddr, + format_ip4_address, &sa->iaddr); return -1; } } static uword ikev2_node_fn (vlib_main_t * vm, - vlib_node_runtime_t * node, - vlib_frame_t * frame) + vlib_node_runtime_t * node, vlib_frame_t * frame) { - u32 n_left_from, * from, * to_next; + u32 n_left_from, *from, *to_next; ikev2_next_t next_index; - ikev2_main_t * km = &ikev2_main; - u32 cpu_index = os_get_cpu_number(); + ikev2_main_t *km = &ikev2_main; + u32 cpu_index = os_get_cpu_number (); from = vlib_frame_vector_args (frame); n_left_from = frame->n_vectors; @@ -1619,293 +1668,297 @@ ikev2_node_fn (vlib_main_t * vm, vlib_get_next_frame (vm, node, next_index, to_next, n_left_to_next); while (n_left_from > 0 && n_left_to_next > 0) - { - u32 bi0; - vlib_buffer_t * b0; - u32 next0 = IKEV2_NEXT_ERROR_DROP; - u32 sw_if_index0; - ip4_header_t * ip40; - udp_header_t * udp0; - ike_header_t * ike0; - ikev2_sa_t * sa0 = 0; - int len = 0; - int r; - - /* speculatively enqueue b0 to the current next frame */ - bi0 = from[0]; - to_next[0] = bi0; - from += 1; - to_next += 1; - n_left_from -= 1; - n_left_to_next -= 1; - - b0 = vlib_get_buffer (vm, bi0); - ike0 = vlib_buffer_get_current (b0); - vlib_buffer_advance(b0, - sizeof(*udp0)); - udp0 = vlib_buffer_get_current (b0); - vlib_buffer_advance(b0, - sizeof(*ip40)); - ip40 = vlib_buffer_get_current (b0); - - if (ike0->version != IKE_VERSION_2) - { - vlib_node_increment_counter(vm, ikev2_node.index, - IKEV2_ERROR_NOT_IKEV2, 1); - goto dispatch0; - } - - if (ike0->exchange == IKEV2_EXCHANGE_SA_INIT) - { - ikev2_sa_t sa; /* temporary store for SA */ - sa0 = &sa; - memset (sa0, 0, sizeof (*sa0)); - - if (ike0->rspi == 0) - { - sa0->raddr.as_u32 = ip40->dst_address.as_u32; - sa0->iaddr.as_u32 = ip40->src_address.as_u32; - - r = ikev2_retransmit_sa_init(ike0, sa0->iaddr, sa0->raddr); - if (r == 1) - { - vlib_node_increment_counter(vm, ikev2_node.index, - IKEV2_ERROR_IKE_SA_INIT_RETRANSMIT, - 1); - len = clib_net_to_host_u32(ike0->length); - goto dispatch0; - } - else if (r == -1) - { - vlib_node_increment_counter(vm, ikev2_node.index, - IKEV2_ERROR_IKE_SA_INIT_IGNORE, - 1); - goto dispatch0; - } - - ikev2_process_sa_init_req(vm, sa0, ike0); - - if (sa0->state == IKEV2_STATE_SA_INIT) - { - ikev2_sa_free_proposal_vector(&sa0->r_proposals); - sa0->r_proposals = ikev2_select_proposal(sa0->i_proposals, - IKEV2_PROTOCOL_IKE); - ikev2_generate_sa_init_data(sa0); - } - - if (sa0->state == IKEV2_STATE_SA_INIT || - sa0->state == IKEV2_STATE_NOTIFY_AND_DELETE) - { - len = ikev2_generate_resp(sa0, ike0); - } - - if (sa0->state == IKEV2_STATE_SA_INIT) - { - /* add SA to the pool */ - pool_get (km->per_thread_data[cpu_index].sas, sa0); - clib_memcpy(sa0, &sa, sizeof(*sa0)); - hash_set (km->per_thread_data[cpu_index].sa_by_rspi, - sa0->rspi, - sa0 - km->per_thread_data[cpu_index].sas); - } - else - { - ikev2_sa_free_all_vec(sa0); - } - } - } - else if (ike0->exchange == IKEV2_EXCHANGE_IKE_AUTH) - { - uword * p; - p = hash_get(km->per_thread_data[cpu_index].sa_by_rspi, - clib_net_to_host_u64(ike0->rspi)); - if (p) - { - sa0 = pool_elt_at_index (km->per_thread_data[cpu_index].sas, - p[0]); - - r = ikev2_retransmit_resp(sa0, ike0); - if (r == 1) - { - vlib_node_increment_counter(vm, ikev2_node.index, - IKEV2_ERROR_IKE_REQ_RETRANSMIT, - 1); - len = clib_net_to_host_u32(ike0->length); - goto dispatch0; - } - else if (r == -1) - { - vlib_node_increment_counter(vm, ikev2_node.index, - IKEV2_ERROR_IKE_REQ_IGNORE, - 1); - goto dispatch0; - } - - ikev2_process_auth_req(vm, sa0, ike0); - ikev2_sa_auth(sa0); - if (sa0->state == IKEV2_STATE_AUTHENTICATED) - { - ikev2_initial_contact_cleanup(sa0); - ikev2_sa_match_ts(sa0); - if (sa0->state != IKEV2_STATE_TS_UNACCEPTABLE) - ikev2_create_tunnel_interface(km->vnet_main, sa0, - &sa0->childs[0]); - } - len = ikev2_generate_resp(sa0, ike0); - } - } - else if (ike0->exchange == IKEV2_EXCHANGE_INFORMATIONAL) - { - uword * p; - p = hash_get(km->per_thread_data[cpu_index].sa_by_rspi, - clib_net_to_host_u64(ike0->rspi)); - if (p) - { - sa0 = pool_elt_at_index (km->per_thread_data[cpu_index].sas, - p[0]); - - r = ikev2_retransmit_resp(sa0, ike0); - if (r == 1) - { - vlib_node_increment_counter(vm, ikev2_node.index, - IKEV2_ERROR_IKE_REQ_RETRANSMIT, - 1); - len = clib_net_to_host_u32(ike0->length); - goto dispatch0; - } - else if (r == -1) - { - vlib_node_increment_counter(vm, ikev2_node.index, - IKEV2_ERROR_IKE_REQ_IGNORE, - 1); - goto dispatch0; - } - - ikev2_process_informational_req(vm, sa0, ike0); - if (sa0->del) - { - if (sa0->del[0].protocol_id != IKEV2_PROTOCOL_IKE) - { - ikev2_delete_t * d, * tmp, * resp = 0; - vec_foreach(d, sa0->del) - { - ikev2_child_sa_t * ch_sa; - ch_sa = ikev2_sa_get_child(sa0, d->spi, - d->protocol_id); - if (ch_sa) - { - ikev2_delete_tunnel_interface(km->vnet_main, - sa0, ch_sa); - vec_add2(resp, tmp, 1); - tmp->protocol_id = d->protocol_id; - tmp->spi = ch_sa->r_proposals[0].spi; - ikev2_sa_del_child_sa(sa0, ch_sa); - } - } - vec_free(sa0->del); - sa0->del = resp; - } - } - len = ikev2_generate_resp(sa0, ike0); - } - } - else if (ike0->exchange == IKEV2_EXCHANGE_CREATE_CHILD_SA) - { - uword * p; - p = hash_get(km->per_thread_data[cpu_index].sa_by_rspi, - clib_net_to_host_u64(ike0->rspi)); - if (p) - { - sa0 = pool_elt_at_index (km->per_thread_data[cpu_index].sas, - p[0]); - - r = ikev2_retransmit_resp(sa0, ike0); - if (r == 1) - { - vlib_node_increment_counter(vm, ikev2_node.index, - IKEV2_ERROR_IKE_REQ_RETRANSMIT, - 1); - len = clib_net_to_host_u32(ike0->length); - goto dispatch0; - } - else if (r == -1) - { - vlib_node_increment_counter(vm, ikev2_node.index, - IKEV2_ERROR_IKE_REQ_IGNORE, - 1); - goto dispatch0; - } - - ikev2_process_create_child_sa_req(vm, sa0, ike0); - if (sa0->rekey) - { - if (sa0->rekey[0].protocol_id != IKEV2_PROTOCOL_IKE) - { - ikev2_child_sa_t * child; - vec_add2(sa0->childs, child, 1); - child->r_proposals = sa0->rekey[0].r_proposal; - child->i_proposals = sa0->rekey[0].i_proposal; - child->tsi = sa0->rekey[0].tsi; - child->tsr = sa0->rekey[0].tsr; - ikev2_create_tunnel_interface(km->vnet_main, sa0, - child); - } - len = ikev2_generate_resp(sa0, ike0); - } - } - } - else - { - clib_warning("IKEv2 exchange %u packet received from %U to %U", - ike0->exchange, - format_ip4_address, ip40->src_address.as_u8, - format_ip4_address, ip40->dst_address.as_u8); - } - -dispatch0: - /* if we are sending packet back, rewrite headers */ - if (len) - { - next0 = IKEV2_NEXT_IP4_LOOKUP; - ip40->dst_address.as_u32 = sa0->iaddr.as_u32; - ip40->src_address.as_u32 = sa0->raddr.as_u32; - udp0->length = clib_host_to_net_u16(len + sizeof(udp_header_t)); - udp0->checksum = 0; - b0->current_length = len + sizeof(ip4_header_t) + sizeof(udp_header_t); - ip40->length = clib_host_to_net_u16(b0->current_length); - ip40->checksum = ip4_header_checksum (ip40); - } - /* delete sa */ - if (sa0 && (sa0->state == IKEV2_STATE_DELETED || - sa0->state == IKEV2_STATE_NOTIFY_AND_DELETE)) - { - ikev2_child_sa_t * c; - - vec_foreach(c, sa0->childs) - ikev2_delete_tunnel_interface(km->vnet_main, sa0, c); - - ikev2_delete_sa(sa0); - } - sw_if_index0 = vnet_buffer(b0)->sw_if_index[VLIB_RX]; - - if (PREDICT_FALSE((node->flags & VLIB_NODE_FLAG_TRACE) - && (b0->flags & VLIB_BUFFER_IS_TRACED))) - { - ikev2_trace_t *t = vlib_add_trace (vm, node, b0, sizeof (*t)); - t->sw_if_index = sw_if_index0; - t->next_index = next0; - } - - vlib_validate_buffer_enqueue_x1 (vm, node, next_index, to_next, - n_left_to_next, bi0, next0); - } + { + u32 bi0; + vlib_buffer_t *b0; + u32 next0 = IKEV2_NEXT_ERROR_DROP; + u32 sw_if_index0; + ip4_header_t *ip40; + udp_header_t *udp0; + ike_header_t *ike0; + ikev2_sa_t *sa0 = 0; + int len = 0; + int r; + + /* speculatively enqueue b0 to the current next frame */ + bi0 = from[0]; + to_next[0] = bi0; + from += 1; + to_next += 1; + n_left_from -= 1; + n_left_to_next -= 1; + + b0 = vlib_get_buffer (vm, bi0); + ike0 = vlib_buffer_get_current (b0); + vlib_buffer_advance (b0, -sizeof (*udp0)); + udp0 = vlib_buffer_get_current (b0); + vlib_buffer_advance (b0, -sizeof (*ip40)); + ip40 = vlib_buffer_get_current (b0); + + if (ike0->version != IKE_VERSION_2) + { + vlib_node_increment_counter (vm, ikev2_node.index, + IKEV2_ERROR_NOT_IKEV2, 1); + goto dispatch0; + } + + if (ike0->exchange == IKEV2_EXCHANGE_SA_INIT) + { + ikev2_sa_t sa; /* temporary store for SA */ + sa0 = &sa; + memset (sa0, 0, sizeof (*sa0)); + + if (ike0->rspi == 0) + { + sa0->raddr.as_u32 = ip40->dst_address.as_u32; + sa0->iaddr.as_u32 = ip40->src_address.as_u32; + + r = ikev2_retransmit_sa_init (ike0, sa0->iaddr, sa0->raddr); + if (r == 1) + { + vlib_node_increment_counter (vm, ikev2_node.index, + IKEV2_ERROR_IKE_SA_INIT_RETRANSMIT, + 1); + len = clib_net_to_host_u32 (ike0->length); + goto dispatch0; + } + else if (r == -1) + { + vlib_node_increment_counter (vm, ikev2_node.index, + IKEV2_ERROR_IKE_SA_INIT_IGNORE, + 1); + goto dispatch0; + } + + ikev2_process_sa_init_req (vm, sa0, ike0); + + if (sa0->state == IKEV2_STATE_SA_INIT) + { + ikev2_sa_free_proposal_vector (&sa0->r_proposals); + sa0->r_proposals = + ikev2_select_proposal (sa0->i_proposals, + IKEV2_PROTOCOL_IKE); + ikev2_generate_sa_init_data (sa0); + } + + if (sa0->state == IKEV2_STATE_SA_INIT || + sa0->state == IKEV2_STATE_NOTIFY_AND_DELETE) + { + len = ikev2_generate_resp (sa0, ike0); + } + + if (sa0->state == IKEV2_STATE_SA_INIT) + { + /* add SA to the pool */ + pool_get (km->per_thread_data[cpu_index].sas, sa0); + clib_memcpy (sa0, &sa, sizeof (*sa0)); + hash_set (km->per_thread_data[cpu_index].sa_by_rspi, + sa0->rspi, + sa0 - km->per_thread_data[cpu_index].sas); + } + else + { + ikev2_sa_free_all_vec (sa0); + } + } + } + else if (ike0->exchange == IKEV2_EXCHANGE_IKE_AUTH) + { + uword *p; + p = hash_get (km->per_thread_data[cpu_index].sa_by_rspi, + clib_net_to_host_u64 (ike0->rspi)); + if (p) + { + sa0 = pool_elt_at_index (km->per_thread_data[cpu_index].sas, + p[0]); + + r = ikev2_retransmit_resp (sa0, ike0); + if (r == 1) + { + vlib_node_increment_counter (vm, ikev2_node.index, + IKEV2_ERROR_IKE_REQ_RETRANSMIT, + 1); + len = clib_net_to_host_u32 (ike0->length); + goto dispatch0; + } + else if (r == -1) + { + vlib_node_increment_counter (vm, ikev2_node.index, + IKEV2_ERROR_IKE_REQ_IGNORE, + 1); + goto dispatch0; + } + + ikev2_process_auth_req (vm, sa0, ike0); + ikev2_sa_auth (sa0); + if (sa0->state == IKEV2_STATE_AUTHENTICATED) + { + ikev2_initial_contact_cleanup (sa0); + ikev2_sa_match_ts (sa0); + if (sa0->state != IKEV2_STATE_TS_UNACCEPTABLE) + ikev2_create_tunnel_interface (km->vnet_main, sa0, + &sa0->childs[0]); + } + len = ikev2_generate_resp (sa0, ike0); + } + } + else if (ike0->exchange == IKEV2_EXCHANGE_INFORMATIONAL) + { + uword *p; + p = hash_get (km->per_thread_data[cpu_index].sa_by_rspi, + clib_net_to_host_u64 (ike0->rspi)); + if (p) + { + sa0 = pool_elt_at_index (km->per_thread_data[cpu_index].sas, + p[0]); + + r = ikev2_retransmit_resp (sa0, ike0); + if (r == 1) + { + vlib_node_increment_counter (vm, ikev2_node.index, + IKEV2_ERROR_IKE_REQ_RETRANSMIT, + 1); + len = clib_net_to_host_u32 (ike0->length); + goto dispatch0; + } + else if (r == -1) + { + vlib_node_increment_counter (vm, ikev2_node.index, + IKEV2_ERROR_IKE_REQ_IGNORE, + 1); + goto dispatch0; + } + + ikev2_process_informational_req (vm, sa0, ike0); + if (sa0->del) + { + if (sa0->del[0].protocol_id != IKEV2_PROTOCOL_IKE) + { + ikev2_delete_t *d, *tmp, *resp = 0; + vec_foreach (d, sa0->del) + { + ikev2_child_sa_t *ch_sa; + ch_sa = ikev2_sa_get_child (sa0, d->spi, + d->protocol_id); + if (ch_sa) + { + ikev2_delete_tunnel_interface (km->vnet_main, + sa0, ch_sa); + vec_add2 (resp, tmp, 1); + tmp->protocol_id = d->protocol_id; + tmp->spi = ch_sa->r_proposals[0].spi; + ikev2_sa_del_child_sa (sa0, ch_sa); + } + } + vec_free (sa0->del); + sa0->del = resp; + } + } + len = ikev2_generate_resp (sa0, ike0); + } + } + else if (ike0->exchange == IKEV2_EXCHANGE_CREATE_CHILD_SA) + { + uword *p; + p = hash_get (km->per_thread_data[cpu_index].sa_by_rspi, + clib_net_to_host_u64 (ike0->rspi)); + if (p) + { + sa0 = pool_elt_at_index (km->per_thread_data[cpu_index].sas, + p[0]); + + r = ikev2_retransmit_resp (sa0, ike0); + if (r == 1) + { + vlib_node_increment_counter (vm, ikev2_node.index, + IKEV2_ERROR_IKE_REQ_RETRANSMIT, + 1); + len = clib_net_to_host_u32 (ike0->length); + goto dispatch0; + } + else if (r == -1) + { + vlib_node_increment_counter (vm, ikev2_node.index, + IKEV2_ERROR_IKE_REQ_IGNORE, + 1); + goto dispatch0; + } + + ikev2_process_create_child_sa_req (vm, sa0, ike0); + if (sa0->rekey) + { + if (sa0->rekey[0].protocol_id != IKEV2_PROTOCOL_IKE) + { + ikev2_child_sa_t *child; + vec_add2 (sa0->childs, child, 1); + child->r_proposals = sa0->rekey[0].r_proposal; + child->i_proposals = sa0->rekey[0].i_proposal; + child->tsi = sa0->rekey[0].tsi; + child->tsr = sa0->rekey[0].tsr; + ikev2_create_tunnel_interface (km->vnet_main, sa0, + child); + } + len = ikev2_generate_resp (sa0, ike0); + } + } + } + else + { + clib_warning ("IKEv2 exchange %u packet received from %U to %U", + ike0->exchange, + format_ip4_address, ip40->src_address.as_u8, + format_ip4_address, ip40->dst_address.as_u8); + } + + dispatch0: + /* if we are sending packet back, rewrite headers */ + if (len) + { + next0 = IKEV2_NEXT_IP4_LOOKUP; + ip40->dst_address.as_u32 = sa0->iaddr.as_u32; + ip40->src_address.as_u32 = sa0->raddr.as_u32; + udp0->length = + clib_host_to_net_u16 (len + sizeof (udp_header_t)); + udp0->checksum = 0; + b0->current_length = + len + sizeof (ip4_header_t) + sizeof (udp_header_t); + ip40->length = clib_host_to_net_u16 (b0->current_length); + ip40->checksum = ip4_header_checksum (ip40); + } + /* delete sa */ + if (sa0 && (sa0->state == IKEV2_STATE_DELETED || + sa0->state == IKEV2_STATE_NOTIFY_AND_DELETE)) + { + ikev2_child_sa_t *c; + + vec_foreach (c, sa0->childs) + ikev2_delete_tunnel_interface (km->vnet_main, sa0, c); + + ikev2_delete_sa (sa0); + } + sw_if_index0 = vnet_buffer (b0)->sw_if_index[VLIB_RX]; + + if (PREDICT_FALSE ((node->flags & VLIB_NODE_FLAG_TRACE) + && (b0->flags & VLIB_BUFFER_IS_TRACED))) + { + ikev2_trace_t *t = vlib_add_trace (vm, node, b0, sizeof (*t)); + t->sw_if_index = sw_if_index0; + t->next_index = next0; + } + + vlib_validate_buffer_enqueue_x1 (vm, node, next_index, to_next, + n_left_to_next, bi0, next0); + } vlib_put_next_frame (vm, node, next_index, n_left_to_next); } vlib_node_increment_counter (vm, ikev2_node.index, - IKEV2_ERROR_PROCESSED, frame->n_vectors); + IKEV2_ERROR_PROCESSED, frame->n_vectors); return frame->n_vectors; } +/* *INDENT-OFF* */ VLIB_REGISTER_NODE (ikev2_node,static) = { .function = ikev2_node_fn, .name = "ikev2", @@ -1923,55 +1976,56 @@ VLIB_REGISTER_NODE (ikev2_node,static) = { [IKEV2_NEXT_ERROR_DROP] = "error-drop", }, }; +/* *INDENT-ON* */ static ikev2_profile_t * -ikev2_profile_index_by_name(u8 * name) +ikev2_profile_index_by_name (u8 * name) { - ikev2_main_t * km = &ikev2_main; - uword * p; + ikev2_main_t *km = &ikev2_main; + uword *p; p = mhash_get (&km->profile_index_by_name, name); if (!p) return 0; - return pool_elt_at_index(km->profiles, p[0]); + return pool_elt_at_index (km->profiles, p[0]); } clib_error_t * -ikev2_set_local_key(vlib_main_t * vm, u8 * file) +ikev2_set_local_key (vlib_main_t * vm, u8 * file) { - ikev2_main_t * km = &ikev2_main; + ikev2_main_t *km = &ikev2_main; - km->pkey = ikev2_load_key_file(file); + km->pkey = ikev2_load_key_file (file); if (km->pkey == NULL) - return clib_error_return(0, "load key '%s' failed", file); + return clib_error_return (0, "load key '%s' failed", file); return 0; } clib_error_t * -ikev2_add_del_profile(vlib_main_t * vm, u8 * name, int is_add) +ikev2_add_del_profile (vlib_main_t * vm, u8 * name, int is_add) { - ikev2_main_t * km = &ikev2_main; - ikev2_profile_t * p; + ikev2_main_t *km = &ikev2_main; + ikev2_profile_t *p; if (is_add) { - if (ikev2_profile_index_by_name(name)) - return clib_error_return(0, "policy %v already exists", name); + if (ikev2_profile_index_by_name (name)) + return clib_error_return (0, "policy %v already exists", name); pool_get (km->profiles, p); - memset(p, 0, sizeof(*p)); - p->name = vec_dup(name); + memset (p, 0, sizeof (*p)); + p->name = vec_dup (name); uword index = p - km->profiles; mhash_set_mem (&km->profile_index_by_name, name, &index, 0); } else { - p = ikev2_profile_index_by_name(name); + p = ikev2_profile_index_by_name (name); if (!p) - return clib_error_return(0, "policy %v does not exists", name); + return clib_error_return (0, "policy %v does not exists", name); vec_free (p->name); pool_put (km->profiles, p); @@ -1981,90 +2035,94 @@ ikev2_add_del_profile(vlib_main_t * vm, u8 * name, int is_add) } clib_error_t * -ikev2_set_profile_auth(vlib_main_t * vm, u8 * name, u8 auth_method, - u8 * auth_data, u8 data_hex_format) +ikev2_set_profile_auth (vlib_main_t * vm, u8 * name, u8 auth_method, + u8 * auth_data, u8 data_hex_format) { - ikev2_profile_t * p; - clib_error_t * r; + ikev2_profile_t *p; + clib_error_t *r; - p = ikev2_profile_index_by_name(name); + p = ikev2_profile_index_by_name (name); - if (!p) { - r = clib_error_return(0, "unknown profile %v", name); - return r; - } - vec_free(p->auth.data); + if (!p) + { + r = clib_error_return (0, "unknown profile %v", name); + return r; + } + vec_free (p->auth.data); p->auth.method = auth_method; - p->auth.data = vec_dup(auth_data); + p->auth.data = vec_dup (auth_data); p->auth.hex = data_hex_format; if (auth_method == IKEV2_AUTH_METHOD_RSA_SIG) { if (p->auth.key) - EVP_PKEY_free(p->auth.key); - p->auth.key = ikev2_load_cert_file(auth_data); + EVP_PKEY_free (p->auth.key); + p->auth.key = ikev2_load_cert_file (auth_data); if (p->auth.key == NULL) - return clib_error_return(0, "load cert '%s' failed", auth_data); + return clib_error_return (0, "load cert '%s' failed", auth_data); } return 0; } clib_error_t * -ikev2_set_profile_id(vlib_main_t * vm, u8 * name, u8 id_type, u8 * data, - int is_local) +ikev2_set_profile_id (vlib_main_t * vm, u8 * name, u8 id_type, u8 * data, + int is_local) { - ikev2_profile_t * p; - clib_error_t * r; + ikev2_profile_t *p; + clib_error_t *r; - if (id_type > IKEV2_ID_TYPE_ID_RFC822_ADDR && id_type < IKEV2_ID_TYPE_ID_KEY_ID) + if (id_type > IKEV2_ID_TYPE_ID_RFC822_ADDR + && id_type < IKEV2_ID_TYPE_ID_KEY_ID) { - r = clib_error_return(0, "unsupported identity type %U", - format_ikev2_id_type, id_type); + r = clib_error_return (0, "unsupported identity type %U", + format_ikev2_id_type, id_type); return r; } - p = ikev2_profile_index_by_name(name); + p = ikev2_profile_index_by_name (name); - if (!p) { - r = clib_error_return(0, "unknown profile %v", name); - return r; - } + if (!p) + { + r = clib_error_return (0, "unknown profile %v", name); + return r; + } if (is_local) { - vec_free(p->loc_id.data); + vec_free (p->loc_id.data); p->loc_id.type = id_type; - p->loc_id.data = vec_dup(data); + p->loc_id.data = vec_dup (data); } else { - vec_free(p->rem_id.data); + vec_free (p->rem_id.data); p->rem_id.type = id_type; - p->rem_id.data = vec_dup(data); + p->rem_id.data = vec_dup (data); } return 0; } clib_error_t * -ikev2_set_profile_ts(vlib_main_t * vm, u8 * name, u8 protocol_id, - u16 start_port, u16 end_port, ip4_address_t start_addr, - ip4_address_t end_addr, int is_local) +ikev2_set_profile_ts (vlib_main_t * vm, u8 * name, u8 protocol_id, + u16 start_port, u16 end_port, ip4_address_t start_addr, + ip4_address_t end_addr, int is_local) { - ikev2_profile_t * p; - clib_error_t * r; + ikev2_profile_t *p; + clib_error_t *r; - p = ikev2_profile_index_by_name(name); + p = ikev2_profile_index_by_name (name); - if (!p) { - r = clib_error_return(0, "unknown profile %v", name); - return r; - } + if (!p) + { + r = clib_error_return (0, "unknown profile %v", name); + return r; + } if (is_local) { - p->loc_ts.start_addr.as_u32= start_addr.as_u32; + p->loc_ts.start_addr.as_u32 = start_addr.as_u32; p->loc_ts.end_addr.as_u32 = end_addr.as_u32; p->loc_ts.start_port = start_port; p->loc_ts.end_port = end_port; @@ -2088,24 +2146,24 @@ ikev2_set_profile_ts(vlib_main_t * vm, u8 * name, u8 protocol_id, clib_error_t * ikev2_init (vlib_main_t * vm) { - ikev2_main_t * km = &ikev2_main; - clib_error_t * error; - vlib_thread_main_t * tm = vlib_get_thread_main(); + ikev2_main_t *km = &ikev2_main; + clib_error_t *error; + vlib_thread_main_t *tm = vlib_get_thread_main (); int thread_id; memset (km, 0, sizeof (ikev2_main_t)); - km->vnet_main = vnet_get_main(); + km->vnet_main = vnet_get_main (); km->vlib_main = vm; - ikev2_crypto_init(km); + ikev2_crypto_init (km); mhash_init_vec_string (&km->profile_index_by_name, sizeof (uword)); - vec_validate(km->per_thread_data, tm->n_vlib_mains-1); + vec_validate (km->per_thread_data, tm->n_vlib_mains - 1); for (thread_id = 0; thread_id < tm->n_vlib_mains - 1; thread_id++) { km->per_thread_data[thread_id].sa_by_rspi = - hash_create (0, sizeof (uword)); + hash_create (0, sizeof (uword)); } if ((error = vlib_call_init_function (vm, ikev2_cli_init))) @@ -2117,3 +2175,11 @@ ikev2_init (vlib_main_t * vm) } + +/* + * fd.io coding-style-patch-verification: ON + * + * Local Variables: + * eval: (c-set-style "gnu") + * End: + */ diff --git a/vnet/vnet/ipsec/ikev2.h b/vnet/vnet/ipsec/ikev2.h index 0b5eb3c7df8..723fdde8c1c 100644 --- a/vnet/vnet/ipsec/ikev2.h +++ b/vnet/vnet/ipsec/ikev2.h @@ -26,51 +26,56 @@ typedef u8 v8; +/* *INDENT-OFF* */ typedef CLIB_PACKED (struct { - u64 ispi; - u64 rspi; - u8 nextpayload; - u8 version; - u8 exchange; - u8 flags; - u32 msgid; - u32 length; - u8 payload[0]; + u64 ispi; + u64 rspi; + u8 nextpayload; + u8 version; + u8 exchange; + u8 flags; + u32 msgid; u32 length; u8 payload[0]; }) ike_header_t; - -typedef CLIB_PACKED (struct { - u8 nextpayload; - u8 flags; - u16 length; - u16 dh_group; - u8 reserved[2]; - u8 payload[0]; -}) ike_ke_payload_header_t; - +/* *INDENT-ON* */ + +/* *INDENT-OFF* */ +typedef CLIB_PACKED (struct + { + u8 nextpayload; + u8 flags; + u16 length; + u16 dh_group; + u8 reserved[2]; u8 payload[0];}) ike_ke_payload_header_t; +/* *INDENT-ON* */ + +/* *INDENT-OFF* */ typedef CLIB_PACKED (struct { - u8 nextpayload; - u8 flags; - u16 length; - u8 payload[0]; + u8 nextpayload; + u8 flags; + u16 length; u8 payload[0]; }) ike_payload_header_t; +/* *INDENT-ON* */ +/* *INDENT-OFF* */ typedef CLIB_PACKED (struct { - u8 nextpayload; - u8 flags; - u16 length; - u8 auth_method; - u8 reserved[3]; - u8 payload[0]; + u8 nextpayload; + u8 flags; + u16 length; + u8 auth_method; + u8 reserved[3]; + u8 payload[0]; }) ike_auth_payload_header_t; +/* *INDENT-ON* */ +/* *INDENT-OFF* */ typedef CLIB_PACKED (struct { - u8 nextpayload; - u8 flags; - u16 length; - u8 id_type; - u8 reserved[3]; - u8 payload[0]; + u8 nextpayload; + u8 flags; + u16 length; + u8 id_type; + u8 reserved[3]; u8 payload[0]; }) ike_id_payload_header_t; +/* *INDENT-ON* */ #define IKE_VERSION_2 0x20 @@ -99,9 +104,10 @@ typedef CLIB_PACKED (struct { #define IKEV2_PAYLOAD_TSR 45 #define IKEV2_PAYLOAD_SK 46 -typedef enum { +typedef enum +{ IKEV2_PROTOCOL_IKE = 1, - IKEV2_PROTOCOL_AH = 2, + IKEV2_PROTOCOL_AH = 2, IKEV2_PROTOCOL_ESP = 3, } ikev2_protocol_id_t; @@ -179,7 +185,8 @@ typedef enum { _(16431, SIGNATURE_HASH_ALGORITHMS) -typedef enum { +typedef enum +{ #define _(v,f) IKEV2_NOTIFY_MSG_##f = v, foreach_ikev2_notify_msg_type #undef _ @@ -193,7 +200,8 @@ typedef enum { _(4, DH, "dh-group") \ _(5, ESN, "esn") -typedef enum { +typedef enum +{ #define _(v,f,s) IKEV2_TRANSFORM_TYPE_##f = v, foreach_ikev2_transform_type #undef _ @@ -215,7 +223,8 @@ typedef enum { _(12, AES_CBC, "aes-cbc") \ _(13, AES_CTR, "aes-ctr") -typedef enum { +typedef enum +{ #define _(v,f,str) IKEV2_TRANSFORM_ENCR_TYPE_##f = v, foreach_ikev2_transform_encr_type #undef _ @@ -231,7 +240,8 @@ typedef enum { _(7, PRF_HMAC_SHA2_512, "hmac-sha2-512") \ _(8, PRF_AES128_CMAC, "aes128-cmac") -typedef enum { +typedef enum +{ #define _(v,f,str) IKEV2_TRANSFORM_PRF_TYPE_##f = v, foreach_ikev2_transform_prf_type #undef _ @@ -254,7 +264,8 @@ typedef enum { _(13, AUTH_HMAC_SHA2_384_192, "hmac-sha2-384-192") \ _(14, AUTH_HMAC_SHA2_512_256, "hmac-sha2-512-256") -typedef enum { +typedef enum +{ #define _(v,f, str) IKEV2_TRANSFORM_INTEG_TYPE_##f = v, foreach_ikev2_transform_integ_type #undef _ @@ -303,7 +314,8 @@ typedef enum { _(25, ECP_192, "ecp-192") #endif -typedef enum { +typedef enum +{ #define _(v,f, str) IKEV2_TRANSFORM_DH_TYPE_##f = v, foreach_ikev2_transform_dh_type #undef _ @@ -313,7 +325,8 @@ typedef enum { _(0, NO_ESN, "no") \ _(1, ESN, "yes") -typedef enum { +typedef enum +{ #define _(v,f,str) IKEV2_TRANSFORM_ESN_TYPE_##f = v, foreach_ikev2_transform_esn_type #undef _ @@ -323,7 +336,8 @@ typedef enum { _( 1, RSA_SIG, "rsa-sig") \ _( 2, SHARED_KEY_MIC, "shared-key-mic") -typedef enum { +typedef enum +{ #define _(v,f,s) IKEV2_AUTH_METHOD_##f = v, foreach_ikev2_auth_method #undef _ @@ -338,44 +352,59 @@ typedef enum { _(10, ID_DER_ASN1_GN, "der-asn1-gn") \ _(11, ID_KEY_ID, "key-id") -typedef enum { +typedef enum +{ #define _(v,f,s) IKEV2_ID_TYPE_##f = v, foreach_ikev2_id_type #undef _ } ikev2_id_type_t; -clib_error_t * ikev2_init (vlib_main_t * vm); -clib_error_t * ikev2_set_local_key(vlib_main_t * vm, u8 * file); -clib_error_t * ikev2_add_del_profile(vlib_main_t * vm, u8 * name, int is_add); -clib_error_t * ikev2_set_profile_auth(vlib_main_t * vm, u8 * name, - u8 auth_method, u8 * data, - u8 data_hex_format); -clib_error_t * ikev2_set_profile_id(vlib_main_t * vm, u8 * name, - u8 id_type, u8 * data, int is_local); -clib_error_t * ikev2_set_profile_ts(vlib_main_t * vm, u8 * name, u8 protocol_id, - u16 start_port, u16 end_port, - ip4_address_t start_addr, - ip4_address_t end_addr, int is_local); +clib_error_t *ikev2_init (vlib_main_t * vm); +clib_error_t *ikev2_set_local_key (vlib_main_t * vm, u8 * file); +clib_error_t *ikev2_add_del_profile (vlib_main_t * vm, u8 * name, int is_add); +clib_error_t *ikev2_set_profile_auth (vlib_main_t * vm, u8 * name, + u8 auth_method, u8 * data, + u8 data_hex_format); +clib_error_t *ikev2_set_profile_id (vlib_main_t * vm, u8 * name, + u8 id_type, u8 * data, int is_local); +clib_error_t *ikev2_set_profile_ts (vlib_main_t * vm, u8 * name, + u8 protocol_id, u16 start_port, + u16 end_port, ip4_address_t start_addr, + ip4_address_t end_addr, int is_local); /* ikev2_format.c */ -u8 * format_ikev2_auth_method (u8 * s, va_list * args); -u8 * format_ikev2_id_type (u8 * s, va_list * args); -u8 * format_ikev2_transform_type (u8 * s, va_list * args); -u8 * format_ikev2_notify_msg_type (u8 * s, va_list * args); -u8 * format_ikev2_transform_encr_type(u8 * s, va_list * args); -u8 * format_ikev2_transform_prf_type(u8 * s, va_list * args); -u8 * format_ikev2_transform_integ_type(u8 * s, va_list * args); -u8 * format_ikev2_transform_dh_type(u8 * s, va_list * args); -u8 * format_ikev2_transform_esn_type(u8 * s, va_list * args); -u8 * format_ikev2_sa_transform(u8 * s, va_list * args); +u8 *format_ikev2_auth_method (u8 * s, va_list * args); +u8 *format_ikev2_id_type (u8 * s, va_list * args); +u8 *format_ikev2_transform_type (u8 * s, va_list * args); +u8 *format_ikev2_notify_msg_type (u8 * s, va_list * args); +u8 *format_ikev2_transform_encr_type (u8 * s, va_list * args); +u8 *format_ikev2_transform_prf_type (u8 * s, va_list * args); +u8 *format_ikev2_transform_integ_type (u8 * s, va_list * args); +u8 *format_ikev2_transform_dh_type (u8 * s, va_list * args); +u8 *format_ikev2_transform_esn_type (u8 * s, va_list * args); +u8 *format_ikev2_sa_transform (u8 * s, va_list * args); uword unformat_ikev2_auth_method (unformat_input_t * input, va_list * args); uword unformat_ikev2_id_type (unformat_input_t * input, va_list * args); -uword unformat_ikev2_transform_type (unformat_input_t * input, va_list * args); -uword unformat_ikev2_transform_encr_type (unformat_input_t * input, va_list * args); -uword unformat_ikev2_transform_prf_type (unformat_input_t * input, va_list * args); -uword unformat_ikev2_transform_integ_type (unformat_input_t * input, va_list * args); -uword unformat_ikev2_transform_dh_type (unformat_input_t * input, va_list * args); -uword unformat_ikev2_transform_esn_type (unformat_input_t * input, va_list * args); +uword unformat_ikev2_transform_type (unformat_input_t * input, + va_list * args); +uword unformat_ikev2_transform_encr_type (unformat_input_t * input, + va_list * args); +uword unformat_ikev2_transform_prf_type (unformat_input_t * input, + va_list * args); +uword unformat_ikev2_transform_integ_type (unformat_input_t * input, + va_list * args); +uword unformat_ikev2_transform_dh_type (unformat_input_t * input, + va_list * args); +uword unformat_ikev2_transform_esn_type (unformat_input_t * input, + va_list * args); #endif /* __included_ikev2_h__ */ + +/* + * fd.io coding-style-patch-verification: ON + * + * Local Variables: + * eval: (c-set-style "gnu") + * End: + */ diff --git a/vnet/vnet/ipsec/ikev2_cli.c b/vnet/vnet/ipsec/ikev2_cli.c index c8c8ea140b5..beba8352c8c 100644 --- a/vnet/vnet/ipsec/ikev2_cli.c +++ b/vnet/vnet/ipsec/ikev2_cli.c @@ -23,21 +23,23 @@ u8 * format_ikev2_id_type_and_data (u8 * s, va_list * args) { - ikev2_id_t * id = va_arg (*args, ikev2_id_t *); + ikev2_id_t *id = va_arg (*args, ikev2_id_t *); - if (id->type == 0 || vec_len(id->data) == 0) - return format(s, "none"); + if (id->type == 0 || vec_len (id->data) == 0) + return format (s, "none"); - s = format(s, "%U", format_ikev2_id_type, id->type); + s = format (s, "%U", format_ikev2_id_type, id->type); if (id->type == IKEV2_ID_TYPE_ID_FQDN || id->type == IKEV2_ID_TYPE_ID_RFC822_ADDR) { - s = format(s, " %v", id->data); + s = format (s, " %v", id->data); } else { - s = format(s, " %U", format_hex_bytes, &id->data, (uword) (vec_len(id->data))); + s = + format (s, " %U", format_hex_bytes, &id->data, + (uword) (vec_len (id->data))); } return s; @@ -46,17 +48,18 @@ format_ikev2_id_type_and_data (u8 * s, va_list * args) static clib_error_t * show_ikev2_sa_command_fn (vlib_main_t * vm, - unformat_input_t * input, - vlib_cli_command_t * cmd) + unformat_input_t * input, vlib_cli_command_t * cmd) { - ikev2_main_t * km = &ikev2_main; - ikev2_main_per_thread_data_t * tkm; - ikev2_sa_t * sa; - ikev2_ts_t * ts; - ikev2_child_sa_t * child; - ikev2_sa_transform_t * tr; - - vec_foreach(tkm, km->per_thread_data) { + ikev2_main_t *km = &ikev2_main; + ikev2_main_per_thread_data_t *tkm; + ikev2_sa_t *sa; + ikev2_ts_t *ts; + ikev2_child_sa_t *child; + ikev2_sa_transform_t *tr; + + vec_foreach (tkm, km->per_thread_data) + { + /* *INDENT-OFF* */ pool_foreach (sa, tkm->sas, ({ u8 * s = 0; vlib_cli_output(vm, " iip %U ispi %lx rip %U rspi %lx", @@ -152,154 +155,177 @@ show_ikev2_sa_command_fn (vlib_main_t * vm, } vlib_cli_output(vm, ""); })); + /* *INDENT-ON* */ } return 0; } +/* *INDENT-OFF* */ VLIB_CLI_COMMAND (show_ikev2_sa_command, static) = { .path = "show ikev2 sa", .short_help = "show ikev2 sa", .function = show_ikev2_sa_command_fn, }; +/* *INDENT-ON* */ static clib_error_t * ikev2_profile_add_del_command_fn (vlib_main_t * vm, - unformat_input_t * input, - vlib_cli_command_t * cmd) + unformat_input_t * input, + vlib_cli_command_t * cmd) { - unformat_input_t _line_input, * line_input = &_line_input; - u8 * name = 0; - clib_error_t * r = 0; + unformat_input_t _line_input, *line_input = &_line_input; + u8 *name = 0; + clib_error_t *r = 0; u32 id_type; - u8 * data = 0; + u8 *data = 0; u32 tmp1, tmp2, tmp3; ip4_address_t ip4; ip4_address_t end_addr; - const char * valid_chars = "a-zA-Z0-9_"; + const char *valid_chars = "a-zA-Z0-9_"; - if (! unformat_user (input, unformat_line_input, line_input)) + if (!unformat_user (input, unformat_line_input, line_input)) return 0; - while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT) { - if (unformat (line_input, "add %U", unformat_token, valid_chars, &name)) - { - r = ikev2_add_del_profile(vm, name, 1); - goto done; - } - else if (unformat (line_input, "del %U", unformat_token, valid_chars, &name)) - { - r = ikev2_add_del_profile(vm, name, 0); - goto done; - } - else if (unformat (line_input, "set %U auth shared-key-mic string %v", - unformat_token, valid_chars, &name, &data)) - { - r = ikev2_set_profile_auth(vm, name, IKEV2_AUTH_METHOD_SHARED_KEY_MIC, - data, 0); - goto done; - } - else if (unformat (line_input, "set %U auth shared-key-mic hex %U", - unformat_token, valid_chars, &name, - unformat_hex_string, &data)) - { - r = ikev2_set_profile_auth(vm, name, IKEV2_AUTH_METHOD_SHARED_KEY_MIC, - data, 1); - goto done; - } - else if (unformat (line_input, "set %U auth rsa-sig cert-file %v", - unformat_token, valid_chars, &name, - &data)) - { - r = ikev2_set_profile_auth(vm, name, IKEV2_AUTH_METHOD_RSA_SIG, data, 0); - goto done; - } - else if (unformat (line_input, "set %U id local %U %U", - unformat_token, valid_chars, &name, - unformat_ikev2_id_type, &id_type, - unformat_ip4_address, &ip4)) - { - data = vec_new(u8, 4); - clib_memcpy(data, ip4.as_u8, 4); - r = ikev2_set_profile_id(vm, name, (u8) id_type, data, /*local*/ 1); - goto done; - } - else if (unformat (line_input, "set %U id local %U 0x%U", - unformat_token, valid_chars, &name, - unformat_ikev2_id_type, &id_type, - unformat_hex_string, &data)) - { - r = ikev2_set_profile_id(vm, name, (u8) id_type, data, /*local*/ 1); - goto done; - } - else if (unformat (line_input, "set %U id local %U %v", - unformat_token, valid_chars, &name, - unformat_ikev2_id_type, &id_type, &data)) - { - r = ikev2_set_profile_id(vm, name, (u8) id_type, data, /*local*/ 1); - goto done; - } - else if (unformat (line_input, "set %U id remote %U %U", - unformat_token, valid_chars, &name, - unformat_ikev2_id_type, &id_type, - unformat_ip4_address, &ip4)) - { - data = vec_new(u8, 4); - clib_memcpy(data, ip4.as_u8, 4); - r = ikev2_set_profile_id(vm, name, (u8) id_type, data, /*remote*/ 0); - goto done; - } - else if (unformat (line_input, "set %U id remote %U 0x%U", - unformat_token, valid_chars, &name, - unformat_ikev2_id_type, &id_type, - unformat_hex_string, &data)) - { - r = ikev2_set_profile_id(vm, name, (u8) id_type, data, /*remote*/ 0); - goto done; - } - else if (unformat (line_input, "set %U id remote %U %v", - unformat_token, valid_chars, &name, - unformat_ikev2_id_type, &id_type, &data)) - { - r = ikev2_set_profile_id(vm, name, (u8) id_type, data, /*remote*/ 0); - goto done; - } - else if (unformat (line_input, "set %U traffic-selector local " - "ip-range %U - %U port-range %u - %u protocol %u", - unformat_token, valid_chars, &name, - unformat_ip4_address, &ip4, - unformat_ip4_address, &end_addr, - &tmp1, &tmp2, &tmp3)) - { - r = ikev2_set_profile_ts(vm, name, (u8)tmp3, (u16)tmp1, (u16)tmp2, - ip4, end_addr, /*local*/ 1); - goto done; - } - else if (unformat (line_input, "set %U traffic-selector remote " - "ip-range %U - %U port-range %u - %u protocol %u", - unformat_token, valid_chars, &name, - unformat_ip4_address, &ip4, - unformat_ip4_address, &end_addr, - &tmp1, &tmp2, &tmp3)) - { - r = ikev2_set_profile_ts(vm, name, (u8)tmp3, (u16)tmp1, (u16)tmp2, - ip4, end_addr, /*remote*/ 0); - goto done; - } - else - break; - } + while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT) + { + if (unformat (line_input, "add %U", unformat_token, valid_chars, &name)) + { + r = ikev2_add_del_profile (vm, name, 1); + goto done; + } + else + if (unformat + (line_input, "del %U", unformat_token, valid_chars, &name)) + { + r = ikev2_add_del_profile (vm, name, 0); + goto done; + } + else if (unformat (line_input, "set %U auth shared-key-mic string %v", + unformat_token, valid_chars, &name, &data)) + { + r = + ikev2_set_profile_auth (vm, name, + IKEV2_AUTH_METHOD_SHARED_KEY_MIC, data, + 0); + goto done; + } + else if (unformat (line_input, "set %U auth shared-key-mic hex %U", + unformat_token, valid_chars, &name, + unformat_hex_string, &data)) + { + r = + ikev2_set_profile_auth (vm, name, + IKEV2_AUTH_METHOD_SHARED_KEY_MIC, data, + 1); + goto done; + } + else if (unformat (line_input, "set %U auth rsa-sig cert-file %v", + unformat_token, valid_chars, &name, &data)) + { + r = + ikev2_set_profile_auth (vm, name, IKEV2_AUTH_METHOD_RSA_SIG, data, + 0); + goto done; + } + else if (unformat (line_input, "set %U id local %U %U", + unformat_token, valid_chars, &name, + unformat_ikev2_id_type, &id_type, + unformat_ip4_address, &ip4)) + { + data = vec_new (u8, 4); + clib_memcpy (data, ip4.as_u8, 4); + r = + ikev2_set_profile_id (vm, name, (u8) id_type, data, /*local */ 1); + goto done; + } + else if (unformat (line_input, "set %U id local %U 0x%U", + unformat_token, valid_chars, &name, + unformat_ikev2_id_type, &id_type, + unformat_hex_string, &data)) + { + r = + ikev2_set_profile_id (vm, name, (u8) id_type, data, /*local */ 1); + goto done; + } + else if (unformat (line_input, "set %U id local %U %v", + unformat_token, valid_chars, &name, + unformat_ikev2_id_type, &id_type, &data)) + { + r = + ikev2_set_profile_id (vm, name, (u8) id_type, data, /*local */ 1); + goto done; + } + else if (unformat (line_input, "set %U id remote %U %U", + unformat_token, valid_chars, &name, + unformat_ikev2_id_type, &id_type, + unformat_ip4_address, &ip4)) + { + data = vec_new (u8, 4); + clib_memcpy (data, ip4.as_u8, 4); + r = + ikev2_set_profile_id (vm, name, (u8) id_type, data, /*remote */ + 0); + goto done; + } + else if (unformat (line_input, "set %U id remote %U 0x%U", + unformat_token, valid_chars, &name, + unformat_ikev2_id_type, &id_type, + unformat_hex_string, &data)) + { + r = + ikev2_set_profile_id (vm, name, (u8) id_type, data, /*remote */ + 0); + goto done; + } + else if (unformat (line_input, "set %U id remote %U %v", + unformat_token, valid_chars, &name, + unformat_ikev2_id_type, &id_type, &data)) + { + r = + ikev2_set_profile_id (vm, name, (u8) id_type, data, /*remote */ + 0); + goto done; + } + else if (unformat (line_input, "set %U traffic-selector local " + "ip-range %U - %U port-range %u - %u protocol %u", + unformat_token, valid_chars, &name, + unformat_ip4_address, &ip4, + unformat_ip4_address, &end_addr, + &tmp1, &tmp2, &tmp3)) + { + r = + ikev2_set_profile_ts (vm, name, (u8) tmp3, (u16) tmp1, (u16) tmp2, + ip4, end_addr, /*local */ 1); + goto done; + } + else if (unformat (line_input, "set %U traffic-selector remote " + "ip-range %U - %U port-range %u - %u protocol %u", + unformat_token, valid_chars, &name, + unformat_ip4_address, &ip4, + unformat_ip4_address, &end_addr, + &tmp1, &tmp2, &tmp3)) + { + r = + ikev2_set_profile_ts (vm, name, (u8) tmp3, (u16) tmp1, (u16) tmp2, + ip4, end_addr, /*remote */ 0); + goto done; + } + else + break; + } r = clib_error_return (0, "parse error: '%U'", - format_unformat_error, line_input); + format_unformat_error, line_input); done: - vec_free(name); - vec_free(data); + vec_free (name); + vec_free (data); unformat_free (line_input); return r; } +/* *INDENT-OFF* */ VLIB_CLI_COMMAND (ikev2_profile_add_del_command, static) = { .path = "ikev2 profile", .short_help = @@ -312,15 +338,17 @@ VLIB_CLI_COMMAND (ikev2_profile_add_del_command, static) = { "protocol <protocol-number>", .function = ikev2_profile_add_del_command_fn, }; +/* *INDENT-ON* */ static clib_error_t * show_ikev2_profile_command_fn (vlib_main_t * vm, - unformat_input_t * input, - vlib_cli_command_t * cmd) + unformat_input_t * input, + vlib_cli_command_t * cmd) { - ikev2_main_t * km = &ikev2_main; - ikev2_profile_t * p; + ikev2_main_t *km = &ikev2_main; + ikev2_profile_t *p; + /* *INDENT-OFF* */ pool_foreach (p, km->profiles, ({ vlib_cli_output(vm, "profile %v", p->name); @@ -383,53 +411,59 @@ show_ikev2_profile_command_fn (vlib_main_t * vm, p->rem_ts.start_port, p->rem_ts.end_port, p->rem_ts.protocol_id); })); + /* *INDENT-ON* */ return 0; } +/* *INDENT-OFF* */ VLIB_CLI_COMMAND (show_ikev2_profile_command, static) = { .path = "show ikev2 profile", .short_help = "show ikev2 profile", .function = show_ikev2_profile_command_fn, }; +/* *INDENT-ON* */ static clib_error_t * set_ikev2_local_key_command_fn (vlib_main_t * vm, - unformat_input_t * input, - vlib_cli_command_t * cmd) + unformat_input_t * input, + vlib_cli_command_t * cmd) { - unformat_input_t _line_input, * line_input = &_line_input; - clib_error_t * r = 0; - u8 * data = 0; + unformat_input_t _line_input, *line_input = &_line_input; + clib_error_t *r = 0; + u8 *data = 0; - if (! unformat_user (input, unformat_line_input, line_input)) + if (!unformat_user (input, unformat_line_input, line_input)) return 0; - while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT) { - if (unformat (line_input, "%v", &data)) - { - r = ikev2_set_local_key(vm, data); - goto done; - } - else - break; - } + while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT) + { + if (unformat (line_input, "%v", &data)) + { + r = ikev2_set_local_key (vm, data); + goto done; + } + else + break; + } r = clib_error_return (0, "parse error: '%U'", - format_unformat_error, line_input); + format_unformat_error, line_input); done: - vec_free(data); + vec_free (data); unformat_free (line_input); return r; } +/* *INDENT-OFF* */ VLIB_CLI_COMMAND (set_ikev2_local_key_command, static) = { .path = "set ikev2 local key", .short_help = "set ikev2 local key <file>", .function = set_ikev2_local_key_command_fn, }; +/* *INDENT-ON* */ clib_error_t * ikev2_cli_init (vlib_main_t * vm) @@ -438,3 +472,11 @@ ikev2_cli_init (vlib_main_t * vm) } VLIB_INIT_FUNCTION (ikev2_cli_init); + +/* + * fd.io coding-style-patch-verification: ON + * + * Local Variables: + * eval: (c-set-style "gnu") + * End: + */ diff --git a/vnet/vnet/ipsec/ikev2_crypto.c b/vnet/vnet/ipsec/ikev2_crypto.c index b8dce034e3f..32927629c5e 100644 --- a/vnet/vnet/ipsec/ikev2_crypto.c +++ b/vnet/vnet/ipsec/ikev2_crypto.c @@ -28,469 +28,473 @@ /* from RFC7296 */ static const char modp_dh_768_prime[] = -"FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1" -"29024E088A67CC74020BBEA63B139B22514A08798E3404DD" -"EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245" -"E485B576625E7EC6F44C42E9A63A3620FFFFFFFFFFFFFFFF"; + "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1" + "29024E088A67CC74020BBEA63B139B22514A08798E3404DD" + "EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245" + "E485B576625E7EC6F44C42E9A63A3620FFFFFFFFFFFFFFFF"; static const char modp_dh_768_generator[] = "02"; static const char modp_dh_1024_prime[] = -"FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1" -"29024E088A67CC74020BBEA63B139B22514A08798E3404DD" -"EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245" -"E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED" -"EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE65381" -"FFFFFFFFFFFFFFFF"; + "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1" + "29024E088A67CC74020BBEA63B139B22514A08798E3404DD" + "EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245" + "E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED" + "EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE65381" "FFFFFFFFFFFFFFFF"; static const char modp_dh_1024_generator[] = "02"; /* from RFC3526 */ static const char modp_dh_1536_prime[] = -"FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1" -"29024E088A67CC74020BBEA63B139B22514A08798E3404DD" -"EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245" -"E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED" -"EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3D" -"C2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F" -"83655D23DCA3AD961C62F356208552BB9ED529077096966D" -"670C354E4ABC9804F1746C08CA237327FFFFFFFFFFFFFFFF"; + "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1" + "29024E088A67CC74020BBEA63B139B22514A08798E3404DD" + "EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245" + "E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED" + "EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3D" + "C2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F" + "83655D23DCA3AD961C62F356208552BB9ED529077096966D" + "670C354E4ABC9804F1746C08CA237327FFFFFFFFFFFFFFFF"; static const char modp_dh_1536_generator[] = "02"; static const char modp_dh_2048_prime[] = -"FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1" -"29024E088A67CC74020BBEA63B139B22514A08798E3404DD" -"EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245" -"E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED" -"EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3D" -"C2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F" -"83655D23DCA3AD961C62F356208552BB9ED529077096966D" -"670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B" -"E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9" -"DE2BCBF6955817183995497CEA956AE515D2261898FA0510" -"15728E5A8AACAA68FFFFFFFFFFFFFFFF"; + "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1" + "29024E088A67CC74020BBEA63B139B22514A08798E3404DD" + "EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245" + "E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED" + "EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3D" + "C2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F" + "83655D23DCA3AD961C62F356208552BB9ED529077096966D" + "670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B" + "E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9" + "DE2BCBF6955817183995497CEA956AE515D2261898FA0510" + "15728E5A8AACAA68FFFFFFFFFFFFFFFF"; static const char modp_dh_2048_generator[] = "02"; static const char modp_dh_3072_prime[] = -"FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1" -"29024E088A67CC74020BBEA63B139B22514A08798E3404DD" -"EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245" -"E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED" -"EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3D" -"C2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F" -"83655D23DCA3AD961C62F356208552BB9ED529077096966D" -"670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B" -"E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9" -"DE2BCBF6955817183995497CEA956AE515D2261898FA0510" -"15728E5A8AAAC42DAD33170D04507A33A85521ABDF1CBA64" -"ECFB850458DBEF0A8AEA71575D060C7DB3970F85A6E1E4C7" -"ABF5AE8CDB0933D71E8C94E04A25619DCEE3D2261AD2EE6B" -"F12FFA06D98A0864D87602733EC86A64521F2B18177B200C" -"BBE117577A615D6C770988C0BAD946E208E24FA074E5AB31" -"43DB5BFCE0FD108E4B82D120A93AD2CAFFFFFFFFFFFFFFFF"; + "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1" + "29024E088A67CC74020BBEA63B139B22514A08798E3404DD" + "EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245" + "E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED" + "EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3D" + "C2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F" + "83655D23DCA3AD961C62F356208552BB9ED529077096966D" + "670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B" + "E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9" + "DE2BCBF6955817183995497CEA956AE515D2261898FA0510" + "15728E5A8AAAC42DAD33170D04507A33A85521ABDF1CBA64" + "ECFB850458DBEF0A8AEA71575D060C7DB3970F85A6E1E4C7" + "ABF5AE8CDB0933D71E8C94E04A25619DCEE3D2261AD2EE6B" + "F12FFA06D98A0864D87602733EC86A64521F2B18177B200C" + "BBE117577A615D6C770988C0BAD946E208E24FA074E5AB31" + "43DB5BFCE0FD108E4B82D120A93AD2CAFFFFFFFFFFFFFFFF"; static const char modp_dh_3072_generator[] = "02"; static const char modp_dh_4096_prime[] = -"FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1" -"29024E088A67CC74020BBEA63B139B22514A08798E3404DD" -"EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245" -"E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED" -"EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3D" -"C2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F" -"83655D23DCA3AD961C62F356208552BB9ED529077096966D" -"670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B" -"E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9" -"DE2BCBF6955817183995497CEA956AE515D2261898FA0510" -"15728E5A8AAAC42DAD33170D04507A33A85521ABDF1CBA64" -"ECFB850458DBEF0A8AEA71575D060C7DB3970F85A6E1E4C7" -"ABF5AE8CDB0933D71E8C94E04A25619DCEE3D2261AD2EE6B" -"F12FFA06D98A0864D87602733EC86A64521F2B18177B200C" -"BBE117577A615D6C770988C0BAD946E208E24FA074E5AB31" -"43DB5BFCE0FD108E4B82D120A92108011A723C12A787E6D7" -"88719A10BDBA5B2699C327186AF4E23C1A946834B6150BDA" -"2583E9CA2AD44CE8DBBBC2DB04DE8EF92E8EFC141FBECAA6" -"287C59474E6BC05D99B2964FA090C3A2233BA186515BE7ED" -"1F612970CEE2D7AFB81BDD762170481CD0069127D5B05AA9" -"93B4EA988D8FDDC186FFB7DC90A6C08F4DF435C934063199" -"FFFFFFFFFFFFFFFF"; + "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1" + "29024E088A67CC74020BBEA63B139B22514A08798E3404DD" + "EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245" + "E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED" + "EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3D" + "C2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F" + "83655D23DCA3AD961C62F356208552BB9ED529077096966D" + "670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B" + "E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9" + "DE2BCBF6955817183995497CEA956AE515D2261898FA0510" + "15728E5A8AAAC42DAD33170D04507A33A85521ABDF1CBA64" + "ECFB850458DBEF0A8AEA71575D060C7DB3970F85A6E1E4C7" + "ABF5AE8CDB0933D71E8C94E04A25619DCEE3D2261AD2EE6B" + "F12FFA06D98A0864D87602733EC86A64521F2B18177B200C" + "BBE117577A615D6C770988C0BAD946E208E24FA074E5AB31" + "43DB5BFCE0FD108E4B82D120A92108011A723C12A787E6D7" + "88719A10BDBA5B2699C327186AF4E23C1A946834B6150BDA" + "2583E9CA2AD44CE8DBBBC2DB04DE8EF92E8EFC141FBECAA6" + "287C59474E6BC05D99B2964FA090C3A2233BA186515BE7ED" + "1F612970CEE2D7AFB81BDD762170481CD0069127D5B05AA9" + "93B4EA988D8FDDC186FFB7DC90A6C08F4DF435C934063199" "FFFFFFFFFFFFFFFF"; static const char modp_dh_4096_generator[] = "02"; static const char modp_dh_6144_prime[] = -"FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E08" -"8A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B" -"302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9" -"A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE6" -"49286651ECE45B3DC2007CB8A163BF0598DA48361C55D39A69163FA8" -"FD24CF5F83655D23DCA3AD961C62F356208552BB9ED529077096966D" -"670C354E4ABC9804F1746C08CA18217C32905E462E36CE3BE39E772C" -"180E86039B2783A2EC07A28FB5C55DF06F4C52C9DE2BCBF695581718" -"3995497CEA956AE515D2261898FA051015728E5A8AAAC42DAD33170D" -"04507A33A85521ABDF1CBA64ECFB850458DBEF0A8AEA71575D060C7D" -"B3970F85A6E1E4C7ABF5AE8CDB0933D71E8C94E04A25619DCEE3D226" -"1AD2EE6BF12FFA06D98A0864D87602733EC86A64521F2B18177B200C" -"BBE117577A615D6C770988C0BAD946E208E24FA074E5AB3143DB5BFC" -"E0FD108E4B82D120A92108011A723C12A787E6D788719A10BDBA5B26" -"99C327186AF4E23C1A946834B6150BDA2583E9CA2AD44CE8DBBBC2DB" -"04DE8EF92E8EFC141FBECAA6287C59474E6BC05D99B2964FA090C3A2" -"233BA186515BE7ED1F612970CEE2D7AFB81BDD762170481CD0069127" -"D5B05AA993B4EA988D8FDDC186FFB7DC90A6C08F4DF435C934028492" -"36C3FAB4D27C7026C1D4DCB2602646DEC9751E763DBA37BDF8FF9406" -"AD9E530EE5DB382F413001AEB06A53ED9027D831179727B0865A8918" -"DA3EDBEBCF9B14ED44CE6CBACED4BB1BDB7F1447E6CC254B33205151" -"2BD7AF426FB8F401378CD2BF5983CA01C64B92ECF032EA15D1721D03" -"F482D7CE6E74FEF6D55E702F46980C82B5A84031900B1C9E59E7C97F" -"BEC7E8F323A97A7E36CC88BE0F1D45B7FF585AC54BD407B22B4154AA" -"CC8F6D7EBF48E1D814CC5ED20F8037E0A79715EEF29BE32806A1D58B" -"B7C5DA76F550AA3D8A1FBFF0EB19CCB1A313D55CDA56C9EC2EF29632" -"387FE8D76E3C0468043E8F663F4860EE12BF2D5B0B7474D6E694F91E" -"6DCC4024FFFFFFFFFFFFFFFF"; + "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E08" + "8A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B" + "302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9" + "A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE6" + "49286651ECE45B3DC2007CB8A163BF0598DA48361C55D39A69163FA8" + "FD24CF5F83655D23DCA3AD961C62F356208552BB9ED529077096966D" + "670C354E4ABC9804F1746C08CA18217C32905E462E36CE3BE39E772C" + "180E86039B2783A2EC07A28FB5C55DF06F4C52C9DE2BCBF695581718" + "3995497CEA956AE515D2261898FA051015728E5A8AAAC42DAD33170D" + "04507A33A85521ABDF1CBA64ECFB850458DBEF0A8AEA71575D060C7D" + "B3970F85A6E1E4C7ABF5AE8CDB0933D71E8C94E04A25619DCEE3D226" + "1AD2EE6BF12FFA06D98A0864D87602733EC86A64521F2B18177B200C" + "BBE117577A615D6C770988C0BAD946E208E24FA074E5AB3143DB5BFC" + "E0FD108E4B82D120A92108011A723C12A787E6D788719A10BDBA5B26" + "99C327186AF4E23C1A946834B6150BDA2583E9CA2AD44CE8DBBBC2DB" + "04DE8EF92E8EFC141FBECAA6287C59474E6BC05D99B2964FA090C3A2" + "233BA186515BE7ED1F612970CEE2D7AFB81BDD762170481CD0069127" + "D5B05AA993B4EA988D8FDDC186FFB7DC90A6C08F4DF435C934028492" + "36C3FAB4D27C7026C1D4DCB2602646DEC9751E763DBA37BDF8FF9406" + "AD9E530EE5DB382F413001AEB06A53ED9027D831179727B0865A8918" + "DA3EDBEBCF9B14ED44CE6CBACED4BB1BDB7F1447E6CC254B33205151" + "2BD7AF426FB8F401378CD2BF5983CA01C64B92ECF032EA15D1721D03" + "F482D7CE6E74FEF6D55E702F46980C82B5A84031900B1C9E59E7C97F" + "BEC7E8F323A97A7E36CC88BE0F1D45B7FF585AC54BD407B22B4154AA" + "CC8F6D7EBF48E1D814CC5ED20F8037E0A79715EEF29BE32806A1D58B" + "B7C5DA76F550AA3D8A1FBFF0EB19CCB1A313D55CDA56C9EC2EF29632" + "387FE8D76E3C0468043E8F663F4860EE12BF2D5B0B7474D6E694F91E" + "6DCC4024FFFFFFFFFFFFFFFF"; static const char modp_dh_6144_generator[] = "02"; static const char modp_dh_8192_prime[] = -"FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1" -"29024E088A67CC74020BBEA63B139B22514A08798E3404DD" -"EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245" -"E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED" -"EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3D" -"C2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F" -"83655D23DCA3AD961C62F356208552BB9ED529077096966D" -"670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B" -"E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9" -"DE2BCBF6955817183995497CEA956AE515D2261898FA0510" -"15728E5A8AAAC42DAD33170D04507A33A85521ABDF1CBA64" -"ECFB850458DBEF0A8AEA71575D060C7DB3970F85A6E1E4C7" -"ABF5AE8CDB0933D71E8C94E04A25619DCEE3D2261AD2EE6B" -"F12FFA06D98A0864D87602733EC86A64521F2B18177B200C" -"BBE117577A615D6C770988C0BAD946E208E24FA074E5AB31" -"43DB5BFCE0FD108E4B82D120A92108011A723C12A787E6D7" -"88719A10BDBA5B2699C327186AF4E23C1A946834B6150BDA" -"2583E9CA2AD44CE8DBBBC2DB04DE8EF92E8EFC141FBECAA6" -"287C59474E6BC05D99B2964FA090C3A2233BA186515BE7ED" -"1F612970CEE2D7AFB81BDD762170481CD0069127D5B05AA9" -"93B4EA988D8FDDC186FFB7DC90A6C08F4DF435C934028492" -"36C3FAB4D27C7026C1D4DCB2602646DEC9751E763DBA37BD" -"F8FF9406AD9E530EE5DB382F413001AEB06A53ED9027D831" -"179727B0865A8918DA3EDBEBCF9B14ED44CE6CBACED4BB1B" -"DB7F1447E6CC254B332051512BD7AF426FB8F401378CD2BF" -"5983CA01C64B92ECF032EA15D1721D03F482D7CE6E74FEF6" -"D55E702F46980C82B5A84031900B1C9E59E7C97FBEC7E8F3" -"23A97A7E36CC88BE0F1D45B7FF585AC54BD407B22B4154AA" -"CC8F6D7EBF48E1D814CC5ED20F8037E0A79715EEF29BE328" -"06A1D58BB7C5DA76F550AA3D8A1FBFF0EB19CCB1A313D55C" -"DA56C9EC2EF29632387FE8D76E3C0468043E8F663F4860EE" -"12BF2D5B0B7474D6E694F91E6DBE115974A3926F12FEE5E4" -"38777CB6A932DF8CD8BEC4D073B931BA3BC832B68D9DD300" -"741FA7BF8AFC47ED2576F6936BA424663AAB639C5AE4F568" -"3423B4742BF1C978238F16CBE39D652DE3FDB8BEFC848AD9" -"22222E04A4037C0713EB57A81A23F0C73473FC646CEA306B" -"4BCBC8862F8385DDFA9D4B7FA2C087E879683303ED5BDD3A" -"062B3CF5B3A278A66D2A13F83F44F82DDF310EE074AB6A36" -"4597E899A0255DC164F31CC50846851DF9AB48195DED7EA1" -"B1D510BD7EE74D73FAF36BC31ECFA268359046F4EB879F92" -"4009438B481C6CD7889A002ED5EE382BC9190DA6FC026E47" -"9558E4475677E9AA9E3050E2765694DFC81F56E880B96E71" -"60C980DD98EDD3DFFFFFFFFFFFFFFFFF"; + "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1" + "29024E088A67CC74020BBEA63B139B22514A08798E3404DD" + "EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245" + "E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED" + "EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3D" + "C2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F" + "83655D23DCA3AD961C62F356208552BB9ED529077096966D" + "670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B" + "E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9" + "DE2BCBF6955817183995497CEA956AE515D2261898FA0510" + "15728E5A8AAAC42DAD33170D04507A33A85521ABDF1CBA64" + "ECFB850458DBEF0A8AEA71575D060C7DB3970F85A6E1E4C7" + "ABF5AE8CDB0933D71E8C94E04A25619DCEE3D2261AD2EE6B" + "F12FFA06D98A0864D87602733EC86A64521F2B18177B200C" + "BBE117577A615D6C770988C0BAD946E208E24FA074E5AB31" + "43DB5BFCE0FD108E4B82D120A92108011A723C12A787E6D7" + "88719A10BDBA5B2699C327186AF4E23C1A946834B6150BDA" + "2583E9CA2AD44CE8DBBBC2DB04DE8EF92E8EFC141FBECAA6" + "287C59474E6BC05D99B2964FA090C3A2233BA186515BE7ED" + "1F612970CEE2D7AFB81BDD762170481CD0069127D5B05AA9" + "93B4EA988D8FDDC186FFB7DC90A6C08F4DF435C934028492" + "36C3FAB4D27C7026C1D4DCB2602646DEC9751E763DBA37BD" + "F8FF9406AD9E530EE5DB382F413001AEB06A53ED9027D831" + "179727B0865A8918DA3EDBEBCF9B14ED44CE6CBACED4BB1B" + "DB7F1447E6CC254B332051512BD7AF426FB8F401378CD2BF" + "5983CA01C64B92ECF032EA15D1721D03F482D7CE6E74FEF6" + "D55E702F46980C82B5A84031900B1C9E59E7C97FBEC7E8F3" + "23A97A7E36CC88BE0F1D45B7FF585AC54BD407B22B4154AA" + "CC8F6D7EBF48E1D814CC5ED20F8037E0A79715EEF29BE328" + "06A1D58BB7C5DA76F550AA3D8A1FBFF0EB19CCB1A313D55C" + "DA56C9EC2EF29632387FE8D76E3C0468043E8F663F4860EE" + "12BF2D5B0B7474D6E694F91E6DBE115974A3926F12FEE5E4" + "38777CB6A932DF8CD8BEC4D073B931BA3BC832B68D9DD300" + "741FA7BF8AFC47ED2576F6936BA424663AAB639C5AE4F568" + "3423B4742BF1C978238F16CBE39D652DE3FDB8BEFC848AD9" + "22222E04A4037C0713EB57A81A23F0C73473FC646CEA306B" + "4BCBC8862F8385DDFA9D4B7FA2C087E879683303ED5BDD3A" + "062B3CF5B3A278A66D2A13F83F44F82DDF310EE074AB6A36" + "4597E899A0255DC164F31CC50846851DF9AB48195DED7EA1" + "B1D510BD7EE74D73FAF36BC31ECFA268359046F4EB879F92" + "4009438B481C6CD7889A002ED5EE382BC9190DA6FC026E47" + "9558E4475677E9AA9E3050E2765694DFC81F56E880B96E71" + "60C980DD98EDD3DFFFFFFFFFFFFFFFFF"; static const char modp_dh_8192_generator[] = "02"; /* from RFC5114 */ static const char modp_dh_1024_160_prime[] = -"B10B8F96A080E01DDE92DE5EAE5D54EC52C99FBCFB06A3C6" -"9A6A9DCA52D23B616073E28675A23D189838EF1E2EE652C0" -"13ECB4AEA906112324975C3CD49B83BFACCBDD7D90C4BD70" -"98488E9C219A73724EFFD6FAE5644738FAA31A4FF55BCCC0" -"A151AF5F0DC8B4BD45BF37DF365C1A65E68CFDA76D4DA708" -"DF1FB2BC2E4A4371"; + "B10B8F96A080E01DDE92DE5EAE5D54EC52C99FBCFB06A3C6" + "9A6A9DCA52D23B616073E28675A23D189838EF1E2EE652C0" + "13ECB4AEA906112324975C3CD49B83BFACCBDD7D90C4BD70" + "98488E9C219A73724EFFD6FAE5644738FAA31A4FF55BCCC0" + "A151AF5F0DC8B4BD45BF37DF365C1A65E68CFDA76D4DA708" "DF1FB2BC2E4A4371"; static const char modp_dh_1024_160_generator[] = -"A4D1CBD5C3FD34126765A442EFB99905F8104DD258AC507F" -"D6406CFF14266D31266FEA1E5C41564B777E690F5504F213" -"160217B4B01B886A5E91547F9E2749F4D7FBD7D3B9A92EE1" -"909D0D2263F80A76A6A24C087A091F531DBF0A0169B6A28A" -"D662A4D18E73AFA32D779D5918D08BC8858F4DCEF97C2A24" -"855E6EEB22B3B2E5"; + "A4D1CBD5C3FD34126765A442EFB99905F8104DD258AC507F" + "D6406CFF14266D31266FEA1E5C41564B777E690F5504F213" + "160217B4B01B886A5E91547F9E2749F4D7FBD7D3B9A92EE1" + "909D0D2263F80A76A6A24C087A091F531DBF0A0169B6A28A" + "D662A4D18E73AFA32D779D5918D08BC8858F4DCEF97C2A24" "855E6EEB22B3B2E5"; static const char modp_dh_2048_224_prime[] = -"AD107E1E9123A9D0D660FAA79559C51FA20D64E5683B9FD1" -"B54B1597B61D0A75E6FA141DF95A56DBAF9A3C407BA1DF15" -"EB3D688A309C180E1DE6B85A1274A0A66D3F8152AD6AC212" -"9037C9EDEFDA4DF8D91E8FEF55B7394B7AD5B7D0B6C12207" -"C9F98D11ED34DBF6C6BA0B2C8BBC27BE6A00E0A0B9C49708" -"B3BF8A317091883681286130BC8985DB1602E714415D9330" -"278273C7DE31EFDC7310F7121FD5A07415987D9ADC0A486D" -"CDF93ACC44328387315D75E198C641A480CD86A1B9E587E8" -"BE60E69CC928B2B9C52172E413042E9B23F10B0E16E79763" -"C9B53DCF4BA80A29E3FB73C16B8E75B97EF363E2FFA31F71" -"CF9DE5384E71B81C0AC4DFFE0C10E64F"; + "AD107E1E9123A9D0D660FAA79559C51FA20D64E5683B9FD1" + "B54B1597B61D0A75E6FA141DF95A56DBAF9A3C407BA1DF15" + "EB3D688A309C180E1DE6B85A1274A0A66D3F8152AD6AC212" + "9037C9EDEFDA4DF8D91E8FEF55B7394B7AD5B7D0B6C12207" + "C9F98D11ED34DBF6C6BA0B2C8BBC27BE6A00E0A0B9C49708" + "B3BF8A317091883681286130BC8985DB1602E714415D9330" + "278273C7DE31EFDC7310F7121FD5A07415987D9ADC0A486D" + "CDF93ACC44328387315D75E198C641A480CD86A1B9E587E8" + "BE60E69CC928B2B9C52172E413042E9B23F10B0E16E79763" + "C9B53DCF4BA80A29E3FB73C16B8E75B97EF363E2FFA31F71" + "CF9DE5384E71B81C0AC4DFFE0C10E64F"; static const char modp_dh_2048_224_generator[] = -"AC4032EF4F2D9AE39DF30B5C8FFDAC506CDEBE7B89998CAF" -"74866A08CFE4FFE3A6824A4E10B9A6F0DD921F01A70C4AFA" -"AB739D7700C29F52C57DB17C620A8652BE5E9001A8D66AD7" -"C17669101999024AF4D027275AC1348BB8A762D0521BC98A" -"E247150422EA1ED409939D54DA7460CDB5F6C6B250717CBE" -"F180EB34118E98D119529A45D6F834566E3025E316A330EF" -"BB77A86F0C1AB15B051AE3D428C8F8ACB70A8137150B8EEB" -"10E183EDD19963DDD9E263E4770589EF6AA21E7F5F2FF381" -"B539CCE3409D13CD566AFBB48D6C019181E1BCFE94B30269" -"EDFE72FE9B6AA4BD7B5A0F1C71CFFF4C19C418E1F6EC0179" -"81BC087F2A7065B384B890D3191F2BFA"; + "AC4032EF4F2D9AE39DF30B5C8FFDAC506CDEBE7B89998CAF" + "74866A08CFE4FFE3A6824A4E10B9A6F0DD921F01A70C4AFA" + "AB739D7700C29F52C57DB17C620A8652BE5E9001A8D66AD7" + "C17669101999024AF4D027275AC1348BB8A762D0521BC98A" + "E247150422EA1ED409939D54DA7460CDB5F6C6B250717CBE" + "F180EB34118E98D119529A45D6F834566E3025E316A330EF" + "BB77A86F0C1AB15B051AE3D428C8F8ACB70A8137150B8EEB" + "10E183EDD19963DDD9E263E4770589EF6AA21E7F5F2FF381" + "B539CCE3409D13CD566AFBB48D6C019181E1BCFE94B30269" + "EDFE72FE9B6AA4BD7B5A0F1C71CFFF4C19C418E1F6EC0179" + "81BC087F2A7065B384B890D3191F2BFA"; static const char modp_dh_2048_256_prime[] = -"87A8E61DB4B6663CFFBBD19C651959998CEEF608660DD0F2" -"5D2CEED4435E3B00E00DF8F1D61957D4FAF7DF4561B2AA30" -"16C3D91134096FAA3BF4296D830E9A7C209E0C6497517ABD" -"5A8A9D306BCF67ED91F9E6725B4758C022E0B1EF4275BF7B" -"6C5BFC11D45F9088B941F54EB1E59BB8BC39A0BF12307F5C" -"4FDB70C581B23F76B63ACAE1CAA6B7902D52526735488A0E" -"F13C6D9A51BFA4AB3AD8347796524D8EF6A167B5A41825D9" -"67E144E5140564251CCACB83E6B486F6B3CA3F7971506026" -"C0B857F689962856DED4010ABD0BE621C3A3960A54E710C3" -"75F26375D7014103A4B54330C198AF126116D2276E11715F" -"693877FAD7EF09CADB094AE91E1A1597"; + "87A8E61DB4B6663CFFBBD19C651959998CEEF608660DD0F2" + "5D2CEED4435E3B00E00DF8F1D61957D4FAF7DF4561B2AA30" + "16C3D91134096FAA3BF4296D830E9A7C209E0C6497517ABD" + "5A8A9D306BCF67ED91F9E6725B4758C022E0B1EF4275BF7B" + "6C5BFC11D45F9088B941F54EB1E59BB8BC39A0BF12307F5C" + "4FDB70C581B23F76B63ACAE1CAA6B7902D52526735488A0E" + "F13C6D9A51BFA4AB3AD8347796524D8EF6A167B5A41825D9" + "67E144E5140564251CCACB83E6B486F6B3CA3F7971506026" + "C0B857F689962856DED4010ABD0BE621C3A3960A54E710C3" + "75F26375D7014103A4B54330C198AF126116D2276E11715F" + "693877FAD7EF09CADB094AE91E1A1597"; static const char modp_dh_2048_256_generator[] = -"3FB32C9B73134D0B2E77506660EDBD484CA7B18F21EF2054" -"07F4793A1A0BA12510DBC15077BE463FFF4FED4AAC0BB555" -"BE3A6C1B0C6B47B1BC3773BF7E8C6F62901228F8C28CBB18" -"A55AE31341000A650196F931C77A57F2DDF463E5E9EC144B" -"777DE62AAAB8A8628AC376D282D6ED3864E67982428EBC83" -"1D14348F6F2F9193B5045AF2767164E1DFC967C1FB3F2E55" -"A4BD1BFFE83B9C80D052B985D182EA0ADB2A3B7313D3FE14" -"C8484B1E052588B9B7D2BBD2DF016199ECD06E1557CD0915" -"B3353BBB64E0EC377FD028370DF92B52C7891428CDC67EB6" -"184B523D1DB246C32F63078490F00EF8D647D148D4795451" -"5E2327CFEF98C582664B4C0F6CC41659"; + "3FB32C9B73134D0B2E77506660EDBD484CA7B18F21EF2054" + "07F4793A1A0BA12510DBC15077BE463FFF4FED4AAC0BB555" + "BE3A6C1B0C6B47B1BC3773BF7E8C6F62901228F8C28CBB18" + "A55AE31341000A650196F931C77A57F2DDF463E5E9EC144B" + "777DE62AAAB8A8628AC376D282D6ED3864E67982428EBC83" + "1D14348F6F2F9193B5045AF2767164E1DFC967C1FB3F2E55" + "A4BD1BFFE83B9C80D052B985D182EA0ADB2A3B7313D3FE14" + "C8484B1E052588B9B7D2BBD2DF016199ECD06E1557CD0915" + "B3353BBB64E0EC377FD028370DF92B52C7891428CDC67EB6" + "184B523D1DB246C32F63078490F00EF8D647D148D4795451" + "5E2327CFEF98C582664B4C0F6CC41659"; v8 * -ikev2_calc_prf(ikev2_sa_transform_t * tr, v8 * key, v8 * data) +ikev2_calc_prf (ikev2_sa_transform_t * tr, v8 * key, v8 * data) { HMAC_CTX ctx; - v8 * prf; + v8 *prf; unsigned int len = 0; - prf = vec_new(u8, tr->key_trunc); - HMAC_CTX_init(&ctx); - HMAC_Init_ex(&ctx, key, vec_len(key), tr->md, NULL); - HMAC_Update(&ctx, data, vec_len(data)); - HMAC_Final(&ctx, prf, &len); - HMAC_CTX_cleanup(&ctx); + prf = vec_new (u8, tr->key_trunc); + HMAC_CTX_init (&ctx); + HMAC_Init_ex (&ctx, key, vec_len (key), tr->md, NULL); + HMAC_Update (&ctx, data, vec_len (data)); + HMAC_Final (&ctx, prf, &len); + HMAC_CTX_cleanup (&ctx); - ASSERT(len == tr->key_trunc); + ASSERT (len == tr->key_trunc); return prf; } + u8 * -ikev2_calc_prfplus(ikev2_sa_transform_t * tr, u8 * key, u8 * seed, int len) +ikev2_calc_prfplus (ikev2_sa_transform_t * tr, u8 * key, u8 * seed, int len) { - v8 * t = 0, * s = 0, * tmp = 0, * ret = 0; + v8 *t = 0, *s = 0, *tmp = 0, *ret = 0; u8 x = 0; /* prf+ (K,S) = T1 | T2 | T3 | T4 | ... - where: - T1 = prf (K, S | 0x01) - T2 = prf (K, T1 | S | 0x02) - T3 = prf (K, T2 | S | 0x03) - T4 = prf (K, T3 | S | 0x04) - */ - - while (vec_len(ret) < len && x < 255) { - if (t) { - vec_append(s, t); - vec_free(t); - } + where: + T1 = prf (K, S | 0x01) + T2 = prf (K, T1 | S | 0x02) + T3 = prf (K, T2 | S | 0x03) + T4 = prf (K, T3 | S | 0x04) + */ - vec_append(s, seed); - vec_add2(s, tmp, 1); - *tmp = x + 1; - t = ikev2_calc_prf(tr, key, s); - vec_append(ret, t); - vec_free(s); - x++; - } + while (vec_len (ret) < len && x < 255) + { + if (t) + { + vec_append (s, t); + vec_free (t); + } + + vec_append (s, seed); + vec_add2 (s, tmp, 1); + *tmp = x + 1; + t = ikev2_calc_prf (tr, key, s); + vec_append (ret, t); + vec_free (s); + x++; + } - vec_free(t); + vec_free (t); - if (x == 255) { - vec_free(ret); - } + if (x == 255) + { + vec_free (ret); + } return ret; } v8 * -ikev2_calc_integr(ikev2_sa_transform_t * tr, v8 * key, u8 * data, int len) +ikev2_calc_integr (ikev2_sa_transform_t * tr, v8 * key, u8 * data, int len) { - v8 * r; + v8 *r; HMAC_CTX hctx; unsigned int l; - ASSERT(tr->type == IKEV2_TRANSFORM_TYPE_INTEG); + ASSERT (tr->type == IKEV2_TRANSFORM_TYPE_INTEG); - r = vec_new(u8, tr->key_len); + r = vec_new (u8, tr->key_len); /* verify integrity of data */ - HMAC_CTX_init(&hctx); - HMAC_Init(&hctx, key, vec_len(key), tr->md); - HMAC_Update(&hctx, (const u8 *) data, len); - HMAC_Final(&hctx, r, &l); - HMAC_CTX_cleanup(&hctx); + HMAC_CTX_init (&hctx); + HMAC_Init (&hctx, key, vec_len (key), tr->md); + HMAC_Update (&hctx, (const u8 *) data, len); + HMAC_Final (&hctx, r, &l); + HMAC_CTX_cleanup (&hctx); - ASSERT(l == tr->key_len); + ASSERT (l == tr->key_len); return r; } v8 * -ikev2_decrypt_data(ikev2_sa_t * sa, u8 * data, int len) +ikev2_decrypt_data (ikev2_sa_t * sa, u8 * data, int len) { EVP_CIPHER_CTX ctx; - v8 * r; + v8 *r; int out_len = 0, block_size; - ikev2_sa_transform_t * tr_encr; + ikev2_sa_transform_t *tr_encr; - tr_encr = ikev2_sa_get_td_for_type(sa->r_proposals, IKEV2_TRANSFORM_TYPE_ENCR); + tr_encr = + ikev2_sa_get_td_for_type (sa->r_proposals, IKEV2_TRANSFORM_TYPE_ENCR); block_size = tr_encr->block_size; /* check if data is multiplier of cipher block size */ - if (len % block_size) { - clib_warning("wrong data length"); - return 0; - } + if (len % block_size) + { + clib_warning ("wrong data length"); + return 0; + } - EVP_CIPHER_CTX_init(&ctx); - r = vec_new(u8, len - block_size); - EVP_DecryptInit_ex(&ctx, tr_encr->cipher, NULL, sa->sk_ei, data); - EVP_DecryptUpdate(&ctx, r, &out_len, data+block_size, len-block_size); - EVP_DecryptFinal_ex(&ctx, r + out_len, &out_len); + EVP_CIPHER_CTX_init (&ctx); + r = vec_new (u8, len - block_size); + EVP_DecryptInit_ex (&ctx, tr_encr->cipher, NULL, sa->sk_ei, data); + EVP_DecryptUpdate (&ctx, r, &out_len, data + block_size, len - block_size); + EVP_DecryptFinal_ex (&ctx, r + out_len, &out_len); /* remove padding */ - _vec_len(r) -= r[vec_len(r)-1] + 1; + _vec_len (r) -= r[vec_len (r) - 1] + 1; - EVP_CIPHER_CTX_cleanup(&ctx); + EVP_CIPHER_CTX_cleanup (&ctx); return r; } int -ikev2_encrypt_data(ikev2_sa_t * sa, v8 * src, u8 * dst) +ikev2_encrypt_data (ikev2_sa_t * sa, v8 * src, u8 * dst) { EVP_CIPHER_CTX ctx; int out_len; int bs; - ikev2_sa_transform_t * tr_encr; + ikev2_sa_transform_t *tr_encr; - tr_encr = ikev2_sa_get_td_for_type(sa->r_proposals, IKEV2_TRANSFORM_TYPE_ENCR); + tr_encr = + ikev2_sa_get_td_for_type (sa->r_proposals, IKEV2_TRANSFORM_TYPE_ENCR); bs = tr_encr->block_size; /* generate IV */ - RAND_bytes(dst, bs); + RAND_bytes (dst, bs); - EVP_CIPHER_CTX_init(&ctx); + EVP_CIPHER_CTX_init (&ctx); - EVP_EncryptInit_ex(&ctx, tr_encr->cipher, NULL, sa->sk_er, dst /* dst */ ); - EVP_EncryptUpdate(&ctx, dst + bs, &out_len, src, vec_len(src)); + EVP_EncryptInit_ex (&ctx, tr_encr->cipher, NULL, sa->sk_er, dst /* dst */ ); + EVP_EncryptUpdate (&ctx, dst + bs, &out_len, src, vec_len (src)); - EVP_CIPHER_CTX_cleanup(&ctx); + EVP_CIPHER_CTX_cleanup (&ctx); - ASSERT(vec_len(src) == out_len); + ASSERT (vec_len (src) == out_len); return out_len + bs; } void -ikev2_generate_dh(ikev2_sa_t * sa, ikev2_sa_transform_t * t) +ikev2_generate_dh (ikev2_sa_t * sa, ikev2_sa_transform_t * t) { int r; if (t->dh_group == IKEV2_DH_GROUP_MODP) { - DH * dh = DH_new(); - BN_hex2bn(&dh->p, t->dh_p); - BN_hex2bn(&dh->g, t->dh_g); - DH_generate_key(dh); - - sa->r_dh_data = vec_new(u8, t->key_len); - r = BN_bn2bin(dh->pub_key, sa->r_dh_data); - ASSERT(r == t->key_len); - - BIGNUM *ex; - sa->dh_shared_key = vec_new(u8, t->key_len); - ex = BN_bin2bn(sa->i_dh_data, vec_len(sa->i_dh_data) , NULL); - r = DH_compute_key(sa->dh_shared_key, ex, dh); - ASSERT(r == t->key_len); - BN_clear_free(ex); - DH_free(dh); + DH *dh = DH_new (); + BN_hex2bn (&dh->p, t->dh_p); + BN_hex2bn (&dh->g, t->dh_g); + DH_generate_key (dh); + + sa->r_dh_data = vec_new (u8, t->key_len); + r = BN_bn2bin (dh->pub_key, sa->r_dh_data); + ASSERT (r == t->key_len); + + BIGNUM *ex; + sa->dh_shared_key = vec_new (u8, t->key_len); + ex = BN_bin2bn (sa->i_dh_data, vec_len (sa->i_dh_data), NULL); + r = DH_compute_key (sa->dh_shared_key, ex, dh); + ASSERT (r == t->key_len); + BN_clear_free (ex); + DH_free (dh); } else if (t->dh_group == IKEV2_DH_GROUP_ECP) { - EC_KEY * ec = EC_KEY_new_by_curve_name(t->nid); - ASSERT(ec); + EC_KEY *ec = EC_KEY_new_by_curve_name (t->nid); + ASSERT (ec); - EC_KEY_generate_key(ec); + EC_KEY_generate_key (ec); - const EC_POINT * r_point = EC_KEY_get0_public_key(ec); - const EC_GROUP * group = EC_KEY_get0_group(ec); - BIGNUM * x = NULL, * y = NULL; - BN_CTX * bn_ctx = BN_CTX_new(); + const EC_POINT *r_point = EC_KEY_get0_public_key (ec); + const EC_GROUP *group = EC_KEY_get0_group (ec); + BIGNUM *x = NULL, *y = NULL; + BN_CTX *bn_ctx = BN_CTX_new (); u16 x_off, y_off, len; - EC_POINT * i_point = EC_POINT_new(group); - EC_POINT * shared_point = EC_POINT_new(group); + EC_POINT *i_point = EC_POINT_new (group); + EC_POINT *shared_point = EC_POINT_new (group); - x = BN_new(); - y = BN_new(); + x = BN_new (); + y = BN_new (); len = t->key_len / 2; - EC_POINT_get_affine_coordinates_GFp(group, r_point, x, y, bn_ctx); - sa->r_dh_data = vec_new(u8, t->key_len); - x_off = len - BN_num_bytes(x); - memset(sa->r_dh_data, 0, x_off); - BN_bn2bin(x, sa->r_dh_data + x_off); - y_off = t->key_len - BN_num_bytes(y); - memset(sa->r_dh_data + len, 0, y_off - len); - BN_bn2bin(y, sa->r_dh_data + y_off); - - x = BN_bin2bn(sa->i_dh_data, len, x); - y = BN_bin2bn(sa->i_dh_data + len, len, y); - EC_POINT_set_affine_coordinates_GFp(group, i_point, x, y, bn_ctx); - sa->dh_shared_key = vec_new(u8, t->key_len); - EC_POINT_mul(group, shared_point, NULL, i_point, EC_KEY_get0_private_key(ec), NULL); - EC_POINT_get_affine_coordinates_GFp(group, shared_point, x, y, bn_ctx); - x_off = len - BN_num_bytes(x); - memset(sa->dh_shared_key, 0, x_off); - BN_bn2bin(x, sa->dh_shared_key + x_off); - y_off = t->key_len - BN_num_bytes(y); - memset(sa->dh_shared_key + len, 0, y_off - len); - BN_bn2bin(y, sa->dh_shared_key + y_off); - - EC_KEY_free(ec); - BN_free(x); - BN_free(y); - BN_CTX_free(bn_ctx); - EC_POINT_free(i_point); - EC_POINT_free(shared_point); + EC_POINT_get_affine_coordinates_GFp (group, r_point, x, y, bn_ctx); + sa->r_dh_data = vec_new (u8, t->key_len); + x_off = len - BN_num_bytes (x); + memset (sa->r_dh_data, 0, x_off); + BN_bn2bin (x, sa->r_dh_data + x_off); + y_off = t->key_len - BN_num_bytes (y); + memset (sa->r_dh_data + len, 0, y_off - len); + BN_bn2bin (y, sa->r_dh_data + y_off); + + x = BN_bin2bn (sa->i_dh_data, len, x); + y = BN_bin2bn (sa->i_dh_data + len, len, y); + EC_POINT_set_affine_coordinates_GFp (group, i_point, x, y, bn_ctx); + sa->dh_shared_key = vec_new (u8, t->key_len); + EC_POINT_mul (group, shared_point, NULL, i_point, + EC_KEY_get0_private_key (ec), NULL); + EC_POINT_get_affine_coordinates_GFp (group, shared_point, x, y, bn_ctx); + x_off = len - BN_num_bytes (x); + memset (sa->dh_shared_key, 0, x_off); + BN_bn2bin (x, sa->dh_shared_key + x_off); + y_off = t->key_len - BN_num_bytes (y); + memset (sa->dh_shared_key + len, 0, y_off - len); + BN_bn2bin (y, sa->dh_shared_key + y_off); + + EC_KEY_free (ec); + BN_free (x); + BN_free (y); + BN_CTX_free (bn_ctx); + EC_POINT_free (i_point); + EC_POINT_free (shared_point); } } int -ikev2_verify_sign (EVP_PKEY *pkey, u8 * sigbuf, u8 * data) +ikev2_verify_sign (EVP_PKEY * pkey, u8 * sigbuf, u8 * data) { EVP_MD_CTX md_ctx; - EVP_VerifyInit(&md_ctx, EVP_sha1()); - EVP_VerifyUpdate(&md_ctx, data, vec_len(data)); + EVP_VerifyInit (&md_ctx, EVP_sha1 ()); + EVP_VerifyUpdate (&md_ctx, data, vec_len (data)); - return EVP_VerifyFinal(&md_ctx, sigbuf, vec_len(sigbuf), pkey); + return EVP_VerifyFinal (&md_ctx, sigbuf, vec_len (sigbuf), pkey); } u8 * -ikev2_calc_sign (EVP_PKEY *pkey, u8 * data) +ikev2_calc_sign (EVP_PKEY * pkey, u8 * data) { EVP_MD_CTX md_ctx; unsigned int sig_len = 0; - u8 * sign; + u8 *sign; - EVP_SignInit(&md_ctx, EVP_sha1()); - EVP_SignUpdate(&md_ctx, data, vec_len(data)); + EVP_SignInit (&md_ctx, EVP_sha1 ()); + EVP_SignUpdate (&md_ctx, data, vec_len (data)); /* get sign len */ - EVP_SignFinal(&md_ctx, NULL, &sig_len, pkey); - sign = vec_new(u8, sig_len); + EVP_SignFinal (&md_ctx, NULL, &sig_len, pkey); + sign = vec_new (u8, sig_len); /* calc sign */ - EVP_SignFinal(&md_ctx, sign, &sig_len, pkey); + EVP_SignFinal (&md_ctx, sign, &sig_len, pkey); return sign; } @@ -498,28 +502,28 @@ ikev2_calc_sign (EVP_PKEY *pkey, u8 * data) EVP_PKEY * ikev2_load_cert_file (u8 * file) { - FILE * fp; - X509 * x509; - EVP_PKEY * pkey = NULL; + FILE *fp; + X509 *x509; + EVP_PKEY *pkey = NULL; - fp = fopen((char *)file, "r"); + fp = fopen ((char *) file, "r"); if (!fp) { - clib_warning("open %s failed", file); + clib_warning ("open %s failed", file); goto end; } - x509 = PEM_read_X509(fp, NULL, NULL, NULL); - fclose(fp); + x509 = PEM_read_X509 (fp, NULL, NULL, NULL); + fclose (fp); if (x509 == NULL) { - clib_warning("read cert %s failed", file); + clib_warning ("read cert %s failed", file); goto end; } - pkey = X509_get_pubkey(x509); + pkey = X509_get_pubkey (x509); if (pkey == NULL) - clib_warning("get pubkey %s failed", file); + clib_warning ("get pubkey %s failed", file); end: return pkey; @@ -529,19 +533,19 @@ EVP_PKEY * ikev2_load_key_file (u8 * file) { FILE *fp; - EVP_PKEY * pkey = NULL; + EVP_PKEY *pkey = NULL; - fp = fopen((char *)file, "r"); + fp = fopen ((char *) file, "r"); if (!fp) { - clib_warning("open %s failed", file); + clib_warning ("open %s failed", file); goto end; } - pkey = PEM_read_PrivateKey(fp, NULL, NULL, NULL); - fclose(fp); + pkey = PEM_read_PrivateKey (fp, NULL, NULL, NULL); + fclose (fp); if (pkey == NULL) - clib_warning("read %s failed", file); + clib_warning ("read %s failed", file); end: return pkey; @@ -550,204 +554,212 @@ end: void ikev2_crypto_init (ikev2_main_t * km) { - ikev2_sa_transform_t * tr; + ikev2_sa_transform_t *tr; /* vector of supported transforms - in order of preference */ - vec_add2(km->supported_transforms, tr, 1); - tr->type = IKEV2_TRANSFORM_TYPE_ENCR; - tr->encr_type = IKEV2_TRANSFORM_ENCR_TYPE_AES_CBC; - tr->key_len = 256/8; - tr->block_size = 128/8; - tr->cipher = EVP_aes_256_cbc(); - - vec_add2(km->supported_transforms, tr, 1); - tr->type = IKEV2_TRANSFORM_TYPE_ENCR; - tr->encr_type = IKEV2_TRANSFORM_ENCR_TYPE_AES_CBC; - tr->key_len = 192/8; - tr->block_size = 128/8; - tr->cipher = EVP_aes_192_cbc(); - - vec_add2(km->supported_transforms, tr, 1); - tr->type = IKEV2_TRANSFORM_TYPE_ENCR; - tr->encr_type = IKEV2_TRANSFORM_ENCR_TYPE_AES_CBC; - tr->key_len = 128/8; - tr->block_size = 128/8; - tr->cipher = EVP_aes_128_cbc(); - - vec_add2(km->supported_transforms, tr, 1); - tr->type = IKEV2_TRANSFORM_TYPE_PRF; - tr->prf_type = IKEV2_TRANSFORM_PRF_TYPE_PRF_HMAC_SHA1; - tr->key_len = 160/8; - tr->key_trunc = 160/8; - tr->md = EVP_sha1(); - - vec_add2(km->supported_transforms, tr, 1); - tr->type = IKEV2_TRANSFORM_TYPE_INTEG; - tr->integ_type = IKEV2_TRANSFORM_INTEG_TYPE_AUTH_HMAC_SHA1_96; - tr->key_len = 160/8; - tr->key_trunc = 96/8; - tr->md = EVP_sha1(); + vec_add2 (km->supported_transforms, tr, 1); + tr->type = IKEV2_TRANSFORM_TYPE_ENCR; + tr->encr_type = IKEV2_TRANSFORM_ENCR_TYPE_AES_CBC; + tr->key_len = 256 / 8; + tr->block_size = 128 / 8; + tr->cipher = EVP_aes_256_cbc (); + + vec_add2 (km->supported_transforms, tr, 1); + tr->type = IKEV2_TRANSFORM_TYPE_ENCR; + tr->encr_type = IKEV2_TRANSFORM_ENCR_TYPE_AES_CBC; + tr->key_len = 192 / 8; + tr->block_size = 128 / 8; + tr->cipher = EVP_aes_192_cbc (); + + vec_add2 (km->supported_transforms, tr, 1); + tr->type = IKEV2_TRANSFORM_TYPE_ENCR; + tr->encr_type = IKEV2_TRANSFORM_ENCR_TYPE_AES_CBC; + tr->key_len = 128 / 8; + tr->block_size = 128 / 8; + tr->cipher = EVP_aes_128_cbc (); + + vec_add2 (km->supported_transforms, tr, 1); + tr->type = IKEV2_TRANSFORM_TYPE_PRF; + tr->prf_type = IKEV2_TRANSFORM_PRF_TYPE_PRF_HMAC_SHA1; + tr->key_len = 160 / 8; + tr->key_trunc = 160 / 8; + tr->md = EVP_sha1 (); + + vec_add2 (km->supported_transforms, tr, 1); + tr->type = IKEV2_TRANSFORM_TYPE_INTEG; + tr->integ_type = IKEV2_TRANSFORM_INTEG_TYPE_AUTH_HMAC_SHA1_96; + tr->key_len = 160 / 8; + tr->key_trunc = 96 / 8; + tr->md = EVP_sha1 (); #if defined(OPENSSL_NO_CISCO_FECDH) - vec_add2(km->supported_transforms, tr, 1); - tr->type = IKEV2_TRANSFORM_TYPE_DH; - tr->dh_type = IKEV2_TRANSFORM_DH_TYPE_BRAINPOOL_512; - tr->key_len = (512 * 2)/8; - tr->nid = NID_brainpoolP512r1; - tr->dh_group = IKEV2_DH_GROUP_ECP; - - vec_add2(km->supported_transforms, tr, 1); - tr->type = IKEV2_TRANSFORM_TYPE_DH; - tr->dh_type = IKEV2_TRANSFORM_DH_TYPE_BRAINPOOL_384; - tr->key_len = (384 * 2)/8; - tr->nid = NID_brainpoolP384r1; - tr->dh_group = IKEV2_DH_GROUP_ECP; - - vec_add2(km->supported_transforms, tr, 1); - tr->type = IKEV2_TRANSFORM_TYPE_DH; - tr->dh_type = IKEV2_TRANSFORM_DH_TYPE_BRAINPOOL_256; - tr->key_len = (256 * 2)/8; - tr->nid = NID_brainpoolP256r1; - tr->dh_group = IKEV2_DH_GROUP_ECP; - - vec_add2(km->supported_transforms, tr, 1); - tr->type = IKEV2_TRANSFORM_TYPE_DH; - tr->dh_type = IKEV2_TRANSFORM_DH_TYPE_BRAINPOOL_224; - tr->key_len = (224 * 2)/8; - tr->nid = NID_brainpoolP224r1; - tr->dh_group = IKEV2_DH_GROUP_ECP; - - vec_add2(km->supported_transforms, tr, 1); - tr->type = IKEV2_TRANSFORM_TYPE_DH; - tr->dh_type = IKEV2_TRANSFORM_DH_TYPE_ECP_224; - tr->key_len = (224 * 2)/8; - tr->nid = NID_secp224r1; - tr->dh_group = IKEV2_DH_GROUP_ECP; + vec_add2 (km->supported_transforms, tr, 1); + tr->type = IKEV2_TRANSFORM_TYPE_DH; + tr->dh_type = IKEV2_TRANSFORM_DH_TYPE_BRAINPOOL_512; + tr->key_len = (512 * 2) / 8; + tr->nid = NID_brainpoolP512r1; + tr->dh_group = IKEV2_DH_GROUP_ECP; + + vec_add2 (km->supported_transforms, tr, 1); + tr->type = IKEV2_TRANSFORM_TYPE_DH; + tr->dh_type = IKEV2_TRANSFORM_DH_TYPE_BRAINPOOL_384; + tr->key_len = (384 * 2) / 8; + tr->nid = NID_brainpoolP384r1; + tr->dh_group = IKEV2_DH_GROUP_ECP; + + vec_add2 (km->supported_transforms, tr, 1); + tr->type = IKEV2_TRANSFORM_TYPE_DH; + tr->dh_type = IKEV2_TRANSFORM_DH_TYPE_BRAINPOOL_256; + tr->key_len = (256 * 2) / 8; + tr->nid = NID_brainpoolP256r1; + tr->dh_group = IKEV2_DH_GROUP_ECP; + + vec_add2 (km->supported_transforms, tr, 1); + tr->type = IKEV2_TRANSFORM_TYPE_DH; + tr->dh_type = IKEV2_TRANSFORM_DH_TYPE_BRAINPOOL_224; + tr->key_len = (224 * 2) / 8; + tr->nid = NID_brainpoolP224r1; + tr->dh_group = IKEV2_DH_GROUP_ECP; + + vec_add2 (km->supported_transforms, tr, 1); + tr->type = IKEV2_TRANSFORM_TYPE_DH; + tr->dh_type = IKEV2_TRANSFORM_DH_TYPE_ECP_224; + tr->key_len = (224 * 2) / 8; + tr->nid = NID_secp224r1; + tr->dh_group = IKEV2_DH_GROUP_ECP; #endif - vec_add2(km->supported_transforms, tr, 1); - tr->type = IKEV2_TRANSFORM_TYPE_DH; - tr->dh_type = IKEV2_TRANSFORM_DH_TYPE_ECP_521; - tr->key_len = (528 * 2)/8; - tr->nid = NID_secp521r1; - tr->dh_group = IKEV2_DH_GROUP_ECP; - - vec_add2(km->supported_transforms, tr, 1); - tr->type = IKEV2_TRANSFORM_TYPE_DH; - tr->dh_type = IKEV2_TRANSFORM_DH_TYPE_ECP_384; - tr->key_len = (384 * 2)/8; - tr->nid = NID_secp384r1; - tr->dh_group = IKEV2_DH_GROUP_ECP; - - vec_add2(km->supported_transforms, tr, 1); - tr->type = IKEV2_TRANSFORM_TYPE_DH; - tr->dh_type = IKEV2_TRANSFORM_DH_TYPE_ECP_256; - tr->key_len = (256 * 2)/8; - tr->nid = NID_X9_62_prime256v1; - tr->dh_group = IKEV2_DH_GROUP_ECP; - - vec_add2(km->supported_transforms, tr, 1); - tr->type = IKEV2_TRANSFORM_TYPE_DH; - tr->dh_type = IKEV2_TRANSFORM_DH_TYPE_ECP_192; - tr->key_len = (192 * 2)/8; - tr->nid = NID_X9_62_prime192v1; - tr->dh_group = IKEV2_DH_GROUP_ECP; - - vec_add2(km->supported_transforms, tr, 1); - tr->type = IKEV2_TRANSFORM_TYPE_DH; - tr->dh_type = IKEV2_TRANSFORM_DH_TYPE_MODP_2048_256; - tr->key_len = 2048/8; - tr->dh_p = (const char *) &modp_dh_2048_256_prime; - tr->dh_g = (const char *) &modp_dh_2048_256_generator; - tr->dh_group = IKEV2_DH_GROUP_MODP; - - vec_add2(km->supported_transforms, tr, 1); - tr->type = IKEV2_TRANSFORM_TYPE_DH; - tr->dh_type = IKEV2_TRANSFORM_DH_TYPE_MODP_2048_224; - tr->key_len = 2048/8; - tr->dh_p = (const char *) &modp_dh_2048_224_prime; - tr->dh_g = (const char *) &modp_dh_2048_224_generator; - tr->dh_group = IKEV2_DH_GROUP_MODP; - - vec_add2(km->supported_transforms, tr, 1); - tr->type = IKEV2_TRANSFORM_TYPE_DH; - tr->dh_type = IKEV2_TRANSFORM_DH_TYPE_MODP_1024_160; - tr->key_len = 1024/8; - tr->dh_p = (const char *) &modp_dh_1024_160_prime; - tr->dh_g = (const char *) &modp_dh_1024_160_generator; - tr->dh_group = IKEV2_DH_GROUP_MODP; - - vec_add2(km->supported_transforms, tr, 1); - tr->type = IKEV2_TRANSFORM_TYPE_DH; - tr->dh_type = IKEV2_TRANSFORM_DH_TYPE_MODP_8192; - tr->key_len = 8192/8; - tr->dh_p = (const char *) &modp_dh_8192_prime; - tr->dh_g = (const char *) &modp_dh_8192_generator; - tr->dh_group = IKEV2_DH_GROUP_MODP; - - vec_add2(km->supported_transforms, tr, 1); - tr->type = IKEV2_TRANSFORM_TYPE_DH; - tr->dh_type = IKEV2_TRANSFORM_DH_TYPE_MODP_6144; - tr->key_len = 6144/8; - tr->dh_p = (const char *) &modp_dh_6144_prime; - tr->dh_g = (const char *) &modp_dh_6144_generator; - tr->dh_group = IKEV2_DH_GROUP_MODP; - - vec_add2(km->supported_transforms, tr, 1); - tr->type = IKEV2_TRANSFORM_TYPE_DH; - tr->dh_type = IKEV2_TRANSFORM_DH_TYPE_MODP_4096; - tr->key_len = 4096/8; - tr->dh_p = (const char *) &modp_dh_4096_prime; - tr->dh_g = (const char *) &modp_dh_4096_generator; - tr->dh_group = IKEV2_DH_GROUP_MODP; - - vec_add2(km->supported_transforms, tr, 1); - tr->type = IKEV2_TRANSFORM_TYPE_DH; - tr->dh_type = IKEV2_TRANSFORM_DH_TYPE_MODP_3072; - tr->key_len = 3072/8; - tr->dh_p = (const char *) &modp_dh_3072_prime; - tr->dh_g = (const char *) &modp_dh_3072_generator; - tr->dh_group = IKEV2_DH_GROUP_MODP; - - vec_add2(km->supported_transforms, tr, 1); - tr->type = IKEV2_TRANSFORM_TYPE_DH; - tr->dh_type = IKEV2_TRANSFORM_DH_TYPE_MODP_2048; - tr->key_len = 2048/8; - tr->dh_p = (const char *) &modp_dh_2048_prime; - tr->dh_g = (const char *) &modp_dh_2048_generator; - tr->dh_group = IKEV2_DH_GROUP_MODP; - - vec_add2(km->supported_transforms, tr, 1); - tr->type = IKEV2_TRANSFORM_TYPE_DH; - tr->dh_type = IKEV2_TRANSFORM_DH_TYPE_MODP_1536; - tr->key_len = 1536/8; - tr->dh_p = (const char *) &modp_dh_1536_prime; - tr->dh_g = (const char *) &modp_dh_1536_generator; - tr->dh_group = IKEV2_DH_GROUP_MODP; - - vec_add2(km->supported_transforms, tr, 1); - tr->type = IKEV2_TRANSFORM_TYPE_DH; - tr->dh_type = IKEV2_TRANSFORM_DH_TYPE_MODP_1024; - tr->key_len = 1024/8; - tr->dh_p = (const char *) &modp_dh_1024_prime; - tr->dh_g = (const char *) &modp_dh_1024_generator; - tr->dh_group = IKEV2_DH_GROUP_MODP; - - vec_add2(km->supported_transforms, tr, 1); - tr->type = IKEV2_TRANSFORM_TYPE_DH; - tr->dh_type = IKEV2_TRANSFORM_DH_TYPE_MODP_768; - tr->key_len = 768/8; - tr->dh_p = (const char *) &modp_dh_768_prime; - tr->dh_g = (const char *) &modp_dh_768_generator; - tr->dh_group = IKEV2_DH_GROUP_MODP; - - vec_add2(km->supported_transforms, tr, 1); - tr->type = IKEV2_TRANSFORM_TYPE_ESN; - tr->esn_type = IKEV2_TRANSFORM_ESN_TYPE_ESN; - - vec_add2(km->supported_transforms, tr, 1); - tr->type = IKEV2_TRANSFORM_TYPE_ESN; - tr->esn_type = IKEV2_TRANSFORM_ESN_TYPE_NO_ESN; + vec_add2 (km->supported_transforms, tr, 1); + tr->type = IKEV2_TRANSFORM_TYPE_DH; + tr->dh_type = IKEV2_TRANSFORM_DH_TYPE_ECP_521; + tr->key_len = (528 * 2) / 8; + tr->nid = NID_secp521r1; + tr->dh_group = IKEV2_DH_GROUP_ECP; + + vec_add2 (km->supported_transforms, tr, 1); + tr->type = IKEV2_TRANSFORM_TYPE_DH; + tr->dh_type = IKEV2_TRANSFORM_DH_TYPE_ECP_384; + tr->key_len = (384 * 2) / 8; + tr->nid = NID_secp384r1; + tr->dh_group = IKEV2_DH_GROUP_ECP; + + vec_add2 (km->supported_transforms, tr, 1); + tr->type = IKEV2_TRANSFORM_TYPE_DH; + tr->dh_type = IKEV2_TRANSFORM_DH_TYPE_ECP_256; + tr->key_len = (256 * 2) / 8; + tr->nid = NID_X9_62_prime256v1; + tr->dh_group = IKEV2_DH_GROUP_ECP; + + vec_add2 (km->supported_transforms, tr, 1); + tr->type = IKEV2_TRANSFORM_TYPE_DH; + tr->dh_type = IKEV2_TRANSFORM_DH_TYPE_ECP_192; + tr->key_len = (192 * 2) / 8; + tr->nid = NID_X9_62_prime192v1; + tr->dh_group = IKEV2_DH_GROUP_ECP; + + vec_add2 (km->supported_transforms, tr, 1); + tr->type = IKEV2_TRANSFORM_TYPE_DH; + tr->dh_type = IKEV2_TRANSFORM_DH_TYPE_MODP_2048_256; + tr->key_len = 2048 / 8; + tr->dh_p = (const char *) &modp_dh_2048_256_prime; + tr->dh_g = (const char *) &modp_dh_2048_256_generator; + tr->dh_group = IKEV2_DH_GROUP_MODP; + + vec_add2 (km->supported_transforms, tr, 1); + tr->type = IKEV2_TRANSFORM_TYPE_DH; + tr->dh_type = IKEV2_TRANSFORM_DH_TYPE_MODP_2048_224; + tr->key_len = 2048 / 8; + tr->dh_p = (const char *) &modp_dh_2048_224_prime; + tr->dh_g = (const char *) &modp_dh_2048_224_generator; + tr->dh_group = IKEV2_DH_GROUP_MODP; + + vec_add2 (km->supported_transforms, tr, 1); + tr->type = IKEV2_TRANSFORM_TYPE_DH; + tr->dh_type = IKEV2_TRANSFORM_DH_TYPE_MODP_1024_160; + tr->key_len = 1024 / 8; + tr->dh_p = (const char *) &modp_dh_1024_160_prime; + tr->dh_g = (const char *) &modp_dh_1024_160_generator; + tr->dh_group = IKEV2_DH_GROUP_MODP; + + vec_add2 (km->supported_transforms, tr, 1); + tr->type = IKEV2_TRANSFORM_TYPE_DH; + tr->dh_type = IKEV2_TRANSFORM_DH_TYPE_MODP_8192; + tr->key_len = 8192 / 8; + tr->dh_p = (const char *) &modp_dh_8192_prime; + tr->dh_g = (const char *) &modp_dh_8192_generator; + tr->dh_group = IKEV2_DH_GROUP_MODP; + + vec_add2 (km->supported_transforms, tr, 1); + tr->type = IKEV2_TRANSFORM_TYPE_DH; + tr->dh_type = IKEV2_TRANSFORM_DH_TYPE_MODP_6144; + tr->key_len = 6144 / 8; + tr->dh_p = (const char *) &modp_dh_6144_prime; + tr->dh_g = (const char *) &modp_dh_6144_generator; + tr->dh_group = IKEV2_DH_GROUP_MODP; + + vec_add2 (km->supported_transforms, tr, 1); + tr->type = IKEV2_TRANSFORM_TYPE_DH; + tr->dh_type = IKEV2_TRANSFORM_DH_TYPE_MODP_4096; + tr->key_len = 4096 / 8; + tr->dh_p = (const char *) &modp_dh_4096_prime; + tr->dh_g = (const char *) &modp_dh_4096_generator; + tr->dh_group = IKEV2_DH_GROUP_MODP; + + vec_add2 (km->supported_transforms, tr, 1); + tr->type = IKEV2_TRANSFORM_TYPE_DH; + tr->dh_type = IKEV2_TRANSFORM_DH_TYPE_MODP_3072; + tr->key_len = 3072 / 8; + tr->dh_p = (const char *) &modp_dh_3072_prime; + tr->dh_g = (const char *) &modp_dh_3072_generator; + tr->dh_group = IKEV2_DH_GROUP_MODP; + + vec_add2 (km->supported_transforms, tr, 1); + tr->type = IKEV2_TRANSFORM_TYPE_DH; + tr->dh_type = IKEV2_TRANSFORM_DH_TYPE_MODP_2048; + tr->key_len = 2048 / 8; + tr->dh_p = (const char *) &modp_dh_2048_prime; + tr->dh_g = (const char *) &modp_dh_2048_generator; + tr->dh_group = IKEV2_DH_GROUP_MODP; + + vec_add2 (km->supported_transforms, tr, 1); + tr->type = IKEV2_TRANSFORM_TYPE_DH; + tr->dh_type = IKEV2_TRANSFORM_DH_TYPE_MODP_1536; + tr->key_len = 1536 / 8; + tr->dh_p = (const char *) &modp_dh_1536_prime; + tr->dh_g = (const char *) &modp_dh_1536_generator; + tr->dh_group = IKEV2_DH_GROUP_MODP; + + vec_add2 (km->supported_transforms, tr, 1); + tr->type = IKEV2_TRANSFORM_TYPE_DH; + tr->dh_type = IKEV2_TRANSFORM_DH_TYPE_MODP_1024; + tr->key_len = 1024 / 8; + tr->dh_p = (const char *) &modp_dh_1024_prime; + tr->dh_g = (const char *) &modp_dh_1024_generator; + tr->dh_group = IKEV2_DH_GROUP_MODP; + + vec_add2 (km->supported_transforms, tr, 1); + tr->type = IKEV2_TRANSFORM_TYPE_DH; + tr->dh_type = IKEV2_TRANSFORM_DH_TYPE_MODP_768; + tr->key_len = 768 / 8; + tr->dh_p = (const char *) &modp_dh_768_prime; + tr->dh_g = (const char *) &modp_dh_768_generator; + tr->dh_group = IKEV2_DH_GROUP_MODP; + + vec_add2 (km->supported_transforms, tr, 1); + tr->type = IKEV2_TRANSFORM_TYPE_ESN; + tr->esn_type = IKEV2_TRANSFORM_ESN_TYPE_ESN; + + vec_add2 (km->supported_transforms, tr, 1); + tr->type = IKEV2_TRANSFORM_TYPE_ESN; + tr->esn_type = IKEV2_TRANSFORM_ESN_TYPE_NO_ESN; } + +/* + * fd.io coding-style-patch-verification: ON + * + * Local Variables: + * eval: (c-set-style "gnu") + * End: + */ diff --git a/vnet/vnet/ipsec/ikev2_format.c b/vnet/vnet/ipsec/ikev2_format.c index b5f047f3f79..4d7a007f80d 100644 --- a/vnet/vnet/ipsec/ikev2_format.c +++ b/vnet/vnet/ipsec/ikev2_format.c @@ -21,9 +21,10 @@ #include <vnet/ipsec/ikev2.h> #include <vnet/ipsec/ikev2_priv.h> -u8 * format_ikev2_sa_transform(u8 * s, va_list * args) +u8 * +format_ikev2_sa_transform (u8 * s, va_list * args) { - ikev2_sa_transform_t * tr = va_arg (*args, ikev2_sa_transform_t *); + ikev2_sa_transform_t *tr = va_arg (*args, ikev2_sa_transform_t *); if (!tr) return s; @@ -31,37 +32,38 @@ u8 * format_ikev2_sa_transform(u8 * s, va_list * args) if (tr->type >= IKEV2_TRANSFORM_NUM_TYPES) return s; - s = format(s,"%U:", format_ikev2_transform_type, tr->type); + s = format (s, "%U:", format_ikev2_transform_type, tr->type); switch (tr->type) { - case IKEV2_TRANSFORM_TYPE_ENCR: - s = format(s, "%U", format_ikev2_transform_encr_type, tr->encr_type); - break; - case IKEV2_TRANSFORM_TYPE_PRF: - s = format(s, "%U", format_ikev2_transform_prf_type, tr->prf_type); - break; - case IKEV2_TRANSFORM_TYPE_INTEG: - s = format(s, "%U", format_ikev2_transform_integ_type, tr->integ_type); - break; - case IKEV2_TRANSFORM_TYPE_DH: - s = format(s, "%U", format_ikev2_transform_dh_type, tr->dh_type); - break; - case IKEV2_TRANSFORM_TYPE_ESN: - s = format(s, "%U", format_ikev2_transform_esn_type, tr->esn_type); - break; - default: - break; + case IKEV2_TRANSFORM_TYPE_ENCR: + s = format (s, "%U", format_ikev2_transform_encr_type, tr->encr_type); + break; + case IKEV2_TRANSFORM_TYPE_PRF: + s = format (s, "%U", format_ikev2_transform_prf_type, tr->prf_type); + break; + case IKEV2_TRANSFORM_TYPE_INTEG: + s = format (s, "%U", format_ikev2_transform_integ_type, tr->integ_type); + break; + case IKEV2_TRANSFORM_TYPE_DH: + s = format (s, "%U", format_ikev2_transform_dh_type, tr->dh_type); + break; + case IKEV2_TRANSFORM_TYPE_ESN: + s = format (s, "%U", format_ikev2_transform_esn_type, tr->esn_type); + break; + default: + break; } if (tr->type == IKEV2_TRANSFORM_TYPE_ENCR && tr->encr_type == IKEV2_TRANSFORM_ENCR_TYPE_AES_CBC && tr->key_len) - s = format(s, "-%u", tr->key_len * 8); - else if (vec_len(tr->attrs) == 4 && tr->attrs[0] == 0x80 && tr->attrs[1] == 0x0e) - s = format(s, "-%u", tr->attrs[2] * 256 + tr->attrs[3]); - else if (vec_len(tr->attrs)) - s = format(s, "(unknown attr %U)", format_hex_bytes, - tr->attrs, vec_len(tr->attrs)); + s = format (s, "-%u", tr->key_len * 8); + else if (vec_len (tr->attrs) == 4 && tr->attrs[0] == 0x80 + && tr->attrs[1] == 0x0e) + s = format (s, "-%u", tr->attrs[2] * 256 + tr->attrs[3]); + else if (vec_len (tr->attrs)) + s = format (s, "(unknown attr %U)", format_hex_bytes, + tr->attrs, vec_len (tr->attrs)); return s; } @@ -94,62 +96,60 @@ unformat_ikev2_##lc (unformat_input_t * input, \ } #define _(v,f,str) case IKEV2_AUTH_METHOD_##f: t = str; break; -MACRO_FORMAT(auth_method) +MACRO_FORMAT (auth_method) #undef _ #define _(v,f,str) else if (unformat (input, str)) *r = IKEV2_AUTH_METHOD_##f; -MACRO_UNFORMAT(auth_method) + MACRO_UNFORMAT (auth_method) #undef _ - #define _(v,f,str) case IKEV2_TRANSFORM_TYPE_##f: t = str; break; -MACRO_FORMAT(transform_type) + MACRO_FORMAT (transform_type) #undef _ #define _(v,f,str) else if (unformat (input, str)) *r = IKEV2_TRANSFORM_TYPE_##f; -MACRO_UNFORMAT(transform_type) + MACRO_UNFORMAT (transform_type) #undef _ - #define _(v,f) case IKEV2_NOTIFY_MSG_##f: t = #f; break; -MACRO_FORMAT(notify_msg_type) + MACRO_FORMAT (notify_msg_type) #undef _ - #define _(v,f,str) case IKEV2_ID_TYPE_##f: t = str; break; -MACRO_FORMAT(id_type) + MACRO_FORMAT (id_type) #undef _ #define _(v,f,str) else if (unformat (input, str)) *r = IKEV2_ID_TYPE_##f; -MACRO_UNFORMAT(id_type) + MACRO_UNFORMAT (id_type) #undef _ - #define _(v,f,str) case IKEV2_TRANSFORM_ENCR_TYPE_##f: t = str; break; -MACRO_FORMAT(transform_encr_type) + MACRO_FORMAT (transform_encr_type) #undef _ #define _(v,f,str) else if (unformat (input, str)) *r = IKEV2_TRANSFORM_ENCR_TYPE_##f; -MACRO_UNFORMAT(transform_encr_type) + MACRO_UNFORMAT (transform_encr_type) #undef _ - #define _(v,f,str) case IKEV2_TRANSFORM_PRF_TYPE_##f: t = str; break; -MACRO_FORMAT(transform_prf_type) + MACRO_FORMAT (transform_prf_type) #undef _ #define _(v,f,str) else if (unformat (input, str)) *r = IKEV2_TRANSFORM_PRF_TYPE_##f; -MACRO_UNFORMAT(transform_prf_type) + MACRO_UNFORMAT (transform_prf_type) #undef _ - #define _(v,f,str) case IKEV2_TRANSFORM_INTEG_TYPE_##f: t = str; break; -MACRO_FORMAT(transform_integ_type) + MACRO_FORMAT (transform_integ_type) #undef _ #define _(v,f,str) else if (unformat (input, str)) *r = IKEV2_TRANSFORM_INTEG_TYPE_##f; -MACRO_UNFORMAT(transform_integ_type) + MACRO_UNFORMAT (transform_integ_type) #undef _ - #define _(v,f,str) case IKEV2_TRANSFORM_DH_TYPE_##f: t = str; break; -MACRO_FORMAT(transform_dh_type) + MACRO_FORMAT (transform_dh_type) #undef _ #define _(v,f,str) else if (unformat (input, str)) *r = IKEV2_TRANSFORM_DH_TYPE_##f; -MACRO_UNFORMAT(transform_dh_type) + MACRO_UNFORMAT (transform_dh_type) #undef _ - #define _(v,f,str) case IKEV2_TRANSFORM_ESN_TYPE_##f: t = str; break; -MACRO_FORMAT(transform_esn_type) + MACRO_FORMAT (transform_esn_type) #undef _ #define _(v,f,str) else if (unformat (input, str)) *r = IKEV2_TRANSFORM_ESN_TYPE_##f; -MACRO_UNFORMAT(transform_esn_type) + MACRO_UNFORMAT (transform_esn_type) #undef _ - +/* + * fd.io coding-style-patch-verification: ON + * + * Local Variables: + * eval: (c-set-style "gnu") + * End: + */ diff --git a/vnet/vnet/ipsec/ikev2_payload.c b/vnet/vnet/ipsec/ikev2_payload.c index 4ad8699121d..dd14812b550 100644 --- a/vnet/vnet/ipsec/ikev2_payload.c +++ b/vnet/vnet/ipsec/ikev2_payload.c @@ -24,206 +24,232 @@ #include <vnet/ipsec/ikev2.h> #include <vnet/ipsec/ikev2_priv.h> +/* *INDENT-OFF* */ +typedef CLIB_PACKED (struct + { + u8 nextpayload; + u8 flags; + u16 length; + u8 protocol_id; + u8 spi_size; + u16 msg_type; + u8 payload[0];}) ike_notify_payload_header_t; +/* *INDENT-ON* */ + +/* *INDENT-OFF* */ +typedef CLIB_PACKED (struct + { + u8 ts_type; + u8 protocol_id; + u16 selector_len; + u16 start_port; + u16 end_port; + ip4_address_t start_addr; + ip4_address_t end_addr;}) ikev2_ts_payload_entry_t; +/* *INDENT-OFF* */ + +/* *INDENT-OFF* */ +typedef CLIB_PACKED (struct + { + u8 nextpayload; + u8 flags; + u16 length; + u8 num_ts; + u8 reserved[3]; + ikev2_ts_payload_entry_t ts[0];}) + ike_ts_payload_header_t; +/* *INDENT-OFF* */ + +/* *INDENT-OFF* */ typedef CLIB_PACKED (struct { - u8 nextpayload; - u8 flags; - u16 length; - u8 protocol_id; - u8 spi_size; - u16 msg_type; - u8 payload[0]; -}) ike_notify_payload_header_t; - -typedef CLIB_PACKED (struct { - u8 ts_type; - u8 protocol_id; - u16 selector_len; - u16 start_port; - u16 end_port; - ip4_address_t start_addr; - ip4_address_t end_addr; -}) ikev2_ts_payload_entry_t; - -typedef CLIB_PACKED (struct { - u8 nextpayload; - u8 flags; - u16 length; - u8 num_ts; - u8 reserved[3]; - ikev2_ts_payload_entry_t ts[0]; -}) ike_ts_payload_header_t; - -typedef CLIB_PACKED (struct { - u8 last_or_more; - u8 reserved; - u16 proposal_len; - u8 proposal_num; - u8 protocol_id; - u8 spi_size; - u8 num_transforms; - u32 spi[0]; + u8 last_or_more; + u8 reserved; + u16 proposal_len; + u8 proposal_num; + u8 protocol_id; + u8 spi_size; + u8 num_transforms; u32 spi[0]; }) ike_sa_proposal_data_t; +/* *INDENT-OFF* */ +/* *INDENT-OFF* */ typedef CLIB_PACKED (struct { - u8 last_or_more; - u8 reserved; - u16 transform_len; - u8 transform_type; - u8 reserved2; - u16 transform_id; - u8 attributes[0]; + u8 last_or_more; + u8 reserved; + u16 transform_len; + u8 transform_type; + u8 reserved2; + u16 transform_id; + u8 attributes[0]; }) ike_sa_transform_data_t; +/* *INDENT-OFF* */ +/* *INDENT-OFF* */ typedef CLIB_PACKED (struct { - u8 nextpayload; - u8 flags; - u16 length; - u8 protocol_id; - u8 spi_size; - u16 num_of_spi; - u32 spi[0]; + u8 nextpayload; + u8 flags; + u16 length; + u8 protocol_id; + u8 spi_size; + u16 num_of_spi; + u32 spi[0]; }) ike_delete_payload_header_t; +/* *INDENT-OFF* */ static ike_payload_header_t * -ikev2_payload_add_hdr(ikev2_payload_chain_t * c, u8 payload_type, int len) +ikev2_payload_add_hdr (ikev2_payload_chain_t * c, u8 payload_type, int len) { - ike_payload_header_t * hdr = (ike_payload_header_t *) &c->data[c->last_hdr_off]; - u8 * tmp; + ike_payload_header_t *hdr = + (ike_payload_header_t *) & c->data[c->last_hdr_off]; + u8 *tmp; if (c->data) hdr->nextpayload = payload_type; else c->first_payload_type = payload_type; - c->last_hdr_off = vec_len(c->data); - vec_add2(c->data, tmp, len); + c->last_hdr_off = vec_len (c->data); + vec_add2 (c->data, tmp, len); hdr = (ike_payload_header_t *) tmp; - memset(hdr, 0, len); + memset (hdr, 0, len); - hdr->length = clib_host_to_net_u16(len); + hdr->length = clib_host_to_net_u16 (len); return hdr; } static void -ikev2_payload_add_data(ikev2_payload_chain_t * c, u8 * data) +ikev2_payload_add_data (ikev2_payload_chain_t * c, u8 * data) { u16 len; - ike_payload_header_t * hdr; + ike_payload_header_t *hdr; - vec_append(c->data, data); - hdr = (ike_payload_header_t *) &c->data[c->last_hdr_off]; - len = clib_net_to_host_u16(hdr->length); - hdr->length = clib_host_to_net_u16(len + vec_len(data)); + vec_append (c->data, data); + hdr = (ike_payload_header_t *) & c->data[c->last_hdr_off]; + len = clib_net_to_host_u16 (hdr->length); + hdr->length = clib_host_to_net_u16 (len + vec_len (data)); } void -ikev2_payload_add_notify(ikev2_payload_chain_t * c, u16 msg_type, u8 * data) +ikev2_payload_add_notify (ikev2_payload_chain_t * c, u16 msg_type, u8 * data) { - ike_notify_payload_header_t * n; - - n = (ike_notify_payload_header_t *) ikev2_payload_add_hdr(c, IKEV2_PAYLOAD_NOTIFY, sizeof (*n)); - n->msg_type = clib_host_to_net_u16(msg_type); - ikev2_payload_add_data(c, data); + ike_notify_payload_header_t *n; + + n = + (ike_notify_payload_header_t *) ikev2_payload_add_hdr (c, + IKEV2_PAYLOAD_NOTIFY, + sizeof (*n)); + n->msg_type = clib_host_to_net_u16 (msg_type); + ikev2_payload_add_data (c, data); } void -ikev2_payload_add_sa(ikev2_payload_chain_t * c, ikev2_sa_proposal_t * proposals) +ikev2_payload_add_sa (ikev2_payload_chain_t * c, + ikev2_sa_proposal_t * proposals) { - ike_payload_header_t * ph; - ike_sa_proposal_data_t * prop; - ike_sa_transform_data_t * tr; - ikev2_sa_proposal_t * p; - ikev2_sa_transform_t * t; - - u8 * tmp; - u8 * pr_data = 0; - u8 * tr_data = 0; - - ikev2_payload_add_hdr(c, IKEV2_PAYLOAD_SA, sizeof (*ph)); - - vec_foreach(p, proposals) + ike_payload_header_t *ph; + ike_sa_proposal_data_t *prop; + ike_sa_transform_data_t *tr; + ikev2_sa_proposal_t *p; + ikev2_sa_transform_t *t; + + u8 *tmp; + u8 *pr_data = 0; + u8 *tr_data = 0; + + ikev2_payload_add_hdr (c, IKEV2_PAYLOAD_SA, sizeof (*ph)); + + vec_foreach (p, proposals) + { + int spi_size = (p->protocol_id == IKEV2_PROTOCOL_ESP) ? 4 : 0; + pr_data = vec_new (u8, sizeof (ike_sa_proposal_data_t) + spi_size); + prop = (ike_sa_proposal_data_t *) pr_data; + prop->last_or_more = proposals - p + 1 < vec_len (proposals) ? 2 : 0; + prop->protocol_id = p->protocol_id; + prop->proposal_num = p->proposal_num; + prop->spi_size = spi_size; + prop->num_transforms = vec_len (p->transforms); + + if (spi_size) + prop->spi[0] = clib_host_to_net_u32 (p->spi); + + DBG_PLD ("proposal num %u protocol_id %u last_or_more %u spi_size %u%s%U", + prop->proposal_num, prop->protocol_id, prop->last_or_more, + prop->spi_size, prop->spi_size ? " spi_data " : "", + format_hex_bytes, prop->spi, prop->spi_size); + + vec_foreach (t, p->transforms) { - int spi_size = (p->protocol_id == IKEV2_PROTOCOL_ESP) ? 4 : 0; - pr_data = vec_new(u8, sizeof(ike_sa_proposal_data_t) + spi_size); - prop = (ike_sa_proposal_data_t *) pr_data; - prop->last_or_more = proposals - p + 1 < vec_len(proposals) ? 2 : 0; - prop->protocol_id = p->protocol_id; - prop->proposal_num = p->proposal_num; - prop->spi_size = spi_size; - prop->num_transforms = vec_len(p->transforms); - - if (spi_size) - prop->spi[0] = clib_host_to_net_u32(p->spi); - - DBG_PLD("proposal num %u protocol_id %u last_or_more %u spi_size %u%s%U", - prop->proposal_num, prop->protocol_id, prop->last_or_more, - prop->spi_size, prop->spi_size ? " spi_data " : "", - format_hex_bytes, prop->spi, prop->spi_size); - - vec_foreach(t, p->transforms) - { - vec_add2(tr_data, tmp, sizeof(*tr) + vec_len(t->attrs)); - tr = (ike_sa_transform_data_t *) tmp; - tr->last_or_more = ((t - p->transforms) + 1 < vec_len(p->transforms)) ? 3 : 0; - tr->transform_type = t->type; - tr->transform_id = clib_host_to_net_u16(t->transform_id); - tr->transform_len = clib_host_to_net_u16(sizeof(*tr) + vec_len(t->attrs)); - - if (vec_len(t->attrs) > 0) - clib_memcpy(tr->attributes, t->attrs, vec_len(t->attrs)); - - DBG_PLD("transform type %U transform_id %u last_or_more %u attr_size %u%s%U", - format_ikev2_transform_type, tr->transform_type, - t->transform_id, tr->last_or_more, vec_len(t->attrs), - vec_len(t->attrs) ? " attrs " : "", - format_hex_bytes, tr->attributes, vec_len(t->attrs)); - } - - prop->proposal_len = clib_host_to_net_u16(vec_len(tr_data) + vec_len(pr_data)); - ikev2_payload_add_data(c, pr_data); - ikev2_payload_add_data(c, tr_data); - vec_free(pr_data); - vec_free(tr_data); + vec_add2 (tr_data, tmp, sizeof (*tr) + vec_len (t->attrs)); + tr = (ike_sa_transform_data_t *) tmp; + tr->last_or_more = + ((t - p->transforms) + 1 < vec_len (p->transforms)) ? 3 : 0; + tr->transform_type = t->type; + tr->transform_id = clib_host_to_net_u16 (t->transform_id); + tr->transform_len = + clib_host_to_net_u16 (sizeof (*tr) + vec_len (t->attrs)); + + if (vec_len (t->attrs) > 0) + clib_memcpy (tr->attributes, t->attrs, vec_len (t->attrs)); + + DBG_PLD + ("transform type %U transform_id %u last_or_more %u attr_size %u%s%U", + format_ikev2_transform_type, tr->transform_type, t->transform_id, + tr->last_or_more, vec_len (t->attrs), + vec_len (t->attrs) ? " attrs " : "", format_hex_bytes, + tr->attributes, vec_len (t->attrs)); } + + prop->proposal_len = + clib_host_to_net_u16 (vec_len (tr_data) + vec_len (pr_data)); + ikev2_payload_add_data (c, pr_data); + ikev2_payload_add_data (c, tr_data); + vec_free (pr_data); + vec_free (tr_data); + } } void -ikev2_payload_add_ke(ikev2_payload_chain_t * c, u16 dh_group, u8 * dh_data) +ikev2_payload_add_ke (ikev2_payload_chain_t * c, u16 dh_group, u8 * dh_data) { - ike_ke_payload_header_t * ke; - ke = (ike_ke_payload_header_t *) ikev2_payload_add_hdr(c, IKEV2_PAYLOAD_KE, - sizeof (*ke)); + ike_ke_payload_header_t *ke; + ke = (ike_ke_payload_header_t *) ikev2_payload_add_hdr (c, IKEV2_PAYLOAD_KE, + sizeof (*ke)); - ke->dh_group = clib_host_to_net_u16(dh_group); - ikev2_payload_add_data(c, dh_data); + ke->dh_group = clib_host_to_net_u16 (dh_group); + ikev2_payload_add_data (c, dh_data); } void -ikev2_payload_add_nonce(ikev2_payload_chain_t * c, u8 * nonce) +ikev2_payload_add_nonce (ikev2_payload_chain_t * c, u8 * nonce) { - ikev2_payload_add_hdr(c, IKEV2_PAYLOAD_NONCE, sizeof (ike_payload_header_t)); - ikev2_payload_add_data(c, nonce); + ikev2_payload_add_hdr (c, IKEV2_PAYLOAD_NONCE, + sizeof (ike_payload_header_t)); + ikev2_payload_add_data (c, nonce); } void -ikev2_payload_add_id(ikev2_payload_chain_t *c, ikev2_id_t * id, u8 type) +ikev2_payload_add_id (ikev2_payload_chain_t * c, ikev2_id_t * id, u8 type) { - ike_id_payload_header_t * idp; - idp = (ike_id_payload_header_t *) ikev2_payload_add_hdr(c, type, sizeof (*idp)); + ike_id_payload_header_t *idp; + idp = + (ike_id_payload_header_t *) ikev2_payload_add_hdr (c, type, + sizeof (*idp)); idp->id_type = id->type; - ikev2_payload_add_data(c, id->data); + ikev2_payload_add_data (c, id->data); } void -ikev2_payload_add_delete(ikev2_payload_chain_t *c, ikev2_delete_t * d) +ikev2_payload_add_delete (ikev2_payload_chain_t * c, ikev2_delete_t * d) { - ike_delete_payload_header_t * dp; - u16 num_of_spi = vec_len(d); - ikev2_delete_t * d2; - dp = (ike_delete_payload_header_t *) ikev2_payload_add_hdr(c, IKEV2_PAYLOAD_DELETE, - sizeof (*dp)); + ike_delete_payload_header_t *dp; + u16 num_of_spi = vec_len (d); + ikev2_delete_t *d2; + dp = + (ike_delete_payload_header_t *) ikev2_payload_add_hdr (c, + IKEV2_PAYLOAD_DELETE, + sizeof (*dp)); if (d[0].protocol_id == IKEV2_PROTOCOL_IKE) { @@ -233,198 +259,204 @@ ikev2_payload_add_delete(ikev2_payload_chain_t *c, ikev2_delete_t * d) { dp->protocol_id = d[0].protocol_id; dp->spi_size = 4; - dp->num_of_spi = clib_host_to_net_u16(num_of_spi); - vec_foreach(d2, d) - { - u8 * data = vec_new(u8, 4); - u32 spi = clib_host_to_net_u32(d2->spi); - clib_memcpy(data, &spi, 4); - ikev2_payload_add_data(c, data); - vec_free(data); - } + dp->num_of_spi = clib_host_to_net_u16 (num_of_spi); + vec_foreach (d2, d) + { + u8 *data = vec_new (u8, 4); + u32 spi = clib_host_to_net_u32 (d2->spi); + clib_memcpy (data, &spi, 4); + ikev2_payload_add_data (c, data); + vec_free (data); + } } } void -ikev2_payload_add_auth(ikev2_payload_chain_t *c, ikev2_auth_t * auth) +ikev2_payload_add_auth (ikev2_payload_chain_t * c, ikev2_auth_t * auth) { - ike_auth_payload_header_t * ap; - ap = (ike_auth_payload_header_t *) ikev2_payload_add_hdr(c, IKEV2_PAYLOAD_AUTH, - sizeof (*ap)); + ike_auth_payload_header_t *ap; + ap = + (ike_auth_payload_header_t *) ikev2_payload_add_hdr (c, + IKEV2_PAYLOAD_AUTH, + sizeof (*ap)); ap->auth_method = auth->method; - ikev2_payload_add_data(c, auth->data); + ikev2_payload_add_data (c, auth->data); } void -ikev2_payload_add_ts(ikev2_payload_chain_t * c, ikev2_ts_t * ts, u8 type) +ikev2_payload_add_ts (ikev2_payload_chain_t * c, ikev2_ts_t * ts, u8 type) { - ike_ts_payload_header_t * tsh; + ike_ts_payload_header_t *tsh; ikev2_ts_t *ts2; - u8 * data = 0, * tmp; - - tsh = (ike_ts_payload_header_t *) ikev2_payload_add_hdr(c, type, sizeof (*tsh)); - tsh->num_ts = vec_len(ts); - - vec_foreach(ts2, ts) - { - ASSERT(ts2->ts_type == 7); /*TS_IPV4_ADDR_RANGE */ - ikev2_ts_payload_entry_t * entry; - vec_add2(data, tmp, sizeof(*entry)); - entry = (ikev2_ts_payload_entry_t *) tmp; - entry->ts_type = ts2->ts_type; - entry->protocol_id = ts2->protocol_id; - entry->selector_len = clib_host_to_net_u16(16); - entry->start_port = clib_host_to_net_u16(ts2->start_port); - entry->end_port = clib_host_to_net_u16(ts2->end_port); - entry->start_addr.as_u32 = ts2->start_addr.as_u32; - entry->end_addr.as_u32 = ts2->end_addr.as_u32; - } - - ikev2_payload_add_data(c, data); - vec_free(data); + u8 *data = 0, *tmp; + + tsh = + (ike_ts_payload_header_t *) ikev2_payload_add_hdr (c, type, + sizeof (*tsh)); + tsh->num_ts = vec_len (ts); + + vec_foreach (ts2, ts) + { + ASSERT (ts2->ts_type == 7); /*TS_IPV4_ADDR_RANGE */ + ikev2_ts_payload_entry_t *entry; + vec_add2 (data, tmp, sizeof (*entry)); + entry = (ikev2_ts_payload_entry_t *) tmp; + entry->ts_type = ts2->ts_type; + entry->protocol_id = ts2->protocol_id; + entry->selector_len = clib_host_to_net_u16 (16); + entry->start_port = clib_host_to_net_u16 (ts2->start_port); + entry->end_port = clib_host_to_net_u16 (ts2->end_port); + entry->start_addr.as_u32 = ts2->start_addr.as_u32; + entry->end_addr.as_u32 = ts2->end_addr.as_u32; + } + + ikev2_payload_add_data (c, data); + vec_free (data); } void -ikev2_payload_chain_add_padding(ikev2_payload_chain_t * c, int bs) +ikev2_payload_chain_add_padding (ikev2_payload_chain_t * c, int bs) { - u8 * tmp __attribute__((unused)); - u8 pad_len = (vec_len(c->data) / bs + 1) * bs - vec_len(c->data); - vec_add2(c->data, tmp, pad_len); - c->data[vec_len(c->data)-1] = pad_len - 1; + u8 *tmp __attribute__ ((unused)); + u8 pad_len = (vec_len (c->data) / bs + 1) * bs - vec_len (c->data); + vec_add2 (c->data, tmp, pad_len); + c->data[vec_len (c->data) - 1] = pad_len - 1; } ikev2_sa_proposal_t * -ikev2_parse_sa_payload(ike_payload_header_t * ikep) +ikev2_parse_sa_payload (ike_payload_header_t * ikep) { - ikev2_sa_proposal_t * v = 0; - ikev2_sa_proposal_t * proposal; - ikev2_sa_transform_t * transform; + ikev2_sa_proposal_t *v = 0; + ikev2_sa_proposal_t *proposal; + ikev2_sa_transform_t *transform; - u32 plen = clib_net_to_host_u16(ikep->length); + u32 plen = clib_net_to_host_u16 (ikep->length); - ike_sa_proposal_data_t * sap; + ike_sa_proposal_data_t *sap; int proposal_ptr = 0; do { - sap = (ike_sa_proposal_data_t *) &ikep->payload[proposal_ptr]; + sap = (ike_sa_proposal_data_t *) & ikep->payload[proposal_ptr]; int i; int transform_ptr; - DBG_PLD("proposal num %u len %u last_or_more %u id %u " - "spi_size %u num_transforms %u", - sap->proposal_num, clib_net_to_host_u16(sap->proposal_len), - sap->last_or_more, sap->protocol_id, sap->spi_size, - sap->num_transforms); + DBG_PLD ("proposal num %u len %u last_or_more %u id %u " + "spi_size %u num_transforms %u", + sap->proposal_num, clib_net_to_host_u16 (sap->proposal_len), + sap->last_or_more, sap->protocol_id, sap->spi_size, + sap->num_transforms); /* IKE proposal should not have SPI */ if (sap->protocol_id == IKEV2_PROTOCOL_IKE && sap->spi_size != 0) - goto data_corrupted; + goto data_corrupted; /* IKE proposal should not have SPI */ if (sap->protocol_id == IKEV2_PROTOCOL_ESP && sap->spi_size != 4) - goto data_corrupted; + goto data_corrupted; - transform_ptr = proposal_ptr + sizeof(*sap) + sap->spi_size; + transform_ptr = proposal_ptr + sizeof (*sap) + sap->spi_size; - vec_add2(v, proposal, 1); + vec_add2 (v, proposal, 1); proposal->proposal_num = sap->proposal_num; proposal->protocol_id = sap->protocol_id; - if (sap->spi_size == 4) { - proposal->spi = clib_net_to_host_u32(sap->spi[0]); - } + if (sap->spi_size == 4) + { + proposal->spi = clib_net_to_host_u32 (sap->spi[0]); + } - for(i=0; i< sap->num_transforms; i++) - { - ike_sa_transform_data_t * tr = (ike_sa_transform_data_t *) &ikep->payload[transform_ptr]; - u16 tlen = clib_net_to_host_u16(tr->transform_len); + for (i = 0; i < sap->num_transforms; i++) + { + ike_sa_transform_data_t *tr = + (ike_sa_transform_data_t *) & ikep->payload[transform_ptr]; + u16 tlen = clib_net_to_host_u16 (tr->transform_len); - if (tlen < sizeof(*tr)) - goto data_corrupted; + if (tlen < sizeof (*tr)) + goto data_corrupted; - vec_add2(proposal->transforms, transform, 1); + vec_add2 (proposal->transforms, transform, 1); - transform->type = tr->transform_type; - transform->transform_id = clib_net_to_host_u16(tr->transform_id); - if (tlen > sizeof(*tr)) - vec_add(transform->attrs, tr->attributes, tlen - sizeof(*tr)); + transform->type = tr->transform_type; + transform->transform_id = clib_net_to_host_u16 (tr->transform_id); + if (tlen > sizeof (*tr)) + vec_add (transform->attrs, tr->attributes, tlen - sizeof (*tr)); - DBG_PLD("transform num %u len %u last_or_more %u type %U id %u%s%U", - i, tlen, tr->last_or_more, - format_ikev2_sa_transform, transform, - clib_net_to_host_u16(tr->transform_id), - tlen > sizeof(*tr) ? " attrs " : "", - format_hex_bytes, tr->attributes, tlen - sizeof (*tr)); + DBG_PLD + ("transform num %u len %u last_or_more %u type %U id %u%s%U", i, + tlen, tr->last_or_more, format_ikev2_sa_transform, transform, + clib_net_to_host_u16 (tr->transform_id), + tlen > sizeof (*tr) ? " attrs " : "", format_hex_bytes, + tr->attributes, tlen - sizeof (*tr)); - transform_ptr += tlen; - } + transform_ptr += tlen; + } - proposal_ptr += clib_net_to_host_u16(sap->proposal_len); + proposal_ptr += clib_net_to_host_u16 (sap->proposal_len); } - while (proposal_ptr < (plen - sizeof(*ikep)) && sap->last_or_more == 2); + while (proposal_ptr < (plen - sizeof (*ikep)) && sap->last_or_more == 2); /* data validation */ - if (proposal_ptr != (plen - sizeof(*ikep)) || sap->last_or_more) - goto data_corrupted; + if (proposal_ptr != (plen - sizeof (*ikep)) || sap->last_or_more) + goto data_corrupted; return v; data_corrupted: - DBG_PLD("SA payload data corrupted"); - ikev2_sa_free_proposal_vector(&v); + DBG_PLD ("SA payload data corrupted"); + ikev2_sa_free_proposal_vector (&v); return 0; } ikev2_ts_t * -ikev2_parse_ts_payload(ike_payload_header_t * ikep) +ikev2_parse_ts_payload (ike_payload_header_t * ikep) { - ike_ts_payload_header_t * tsp = (ike_ts_payload_header_t *) ikep; - ikev2_ts_t * r = 0, *ts; + ike_ts_payload_header_t *tsp = (ike_ts_payload_header_t *) ikep; + ikev2_ts_t *r = 0, *ts; u8 i; for (i = 0; i < tsp->num_ts; i++) { - if (tsp->ts[i].ts_type != 7) /* TS_IPV4_ADDR_RANGE */ - { - DBG_PLD("unsupported TS type received (%u)", tsp->ts[i].ts_type); - continue; - } - - vec_add2(r, ts, 1); - ts->ts_type = tsp->ts[i].ts_type; - ts->protocol_id = tsp->ts[i].protocol_id; - ts->start_port = tsp->ts[i].start_port; - ts->end_port = tsp->ts[i].end_port; + if (tsp->ts[i].ts_type != 7) /* TS_IPV4_ADDR_RANGE */ + { + DBG_PLD ("unsupported TS type received (%u)", tsp->ts[i].ts_type); + continue; + } + + vec_add2 (r, ts, 1); + ts->ts_type = tsp->ts[i].ts_type; + ts->protocol_id = tsp->ts[i].protocol_id; + ts->start_port = tsp->ts[i].start_port; + ts->end_port = tsp->ts[i].end_port; ts->start_addr.as_u32 = tsp->ts[i].start_addr.as_u32; - ts->end_addr.as_u32 = tsp->ts[i].end_addr.as_u32; + ts->end_addr.as_u32 = tsp->ts[i].end_addr.as_u32; } return r; } ikev2_notify_t * -ikev2_parse_notify_payload(ike_payload_header_t * ikep) +ikev2_parse_notify_payload (ike_payload_header_t * ikep) { - ike_notify_payload_header_t * n = (ike_notify_payload_header_t *) ikep; - u32 plen = clib_net_to_host_u16(ikep->length); - ikev2_notify_t * r = 0; + ike_notify_payload_header_t *n = (ike_notify_payload_header_t *) ikep; + u32 plen = clib_net_to_host_u16 (ikep->length); + ikev2_notify_t *r = 0; u32 spi; - DBG_PLD("msg_type %U len %u%s%U", - format_ikev2_notify_msg_type, clib_net_to_host_u16(n->msg_type), - plen, plen > sizeof(*n) ? " data ":"", - format_hex_bytes, n->payload, plen - sizeof(*n)); + DBG_PLD ("msg_type %U len %u%s%U", + format_ikev2_notify_msg_type, clib_net_to_host_u16 (n->msg_type), + plen, plen > sizeof (*n) ? " data " : "", + format_hex_bytes, n->payload, plen - sizeof (*n)); - r = vec_new(ikev2_notify_t, 1); - r->msg_type = clib_net_to_host_u16(n->msg_type); + r = vec_new (ikev2_notify_t, 1); + r->msg_type = clib_net_to_host_u16 (n->msg_type); r->protocol_id = n->protocol_id; if (n->spi_size == 4) { - clib_memcpy(&spi, n->payload, n->spi_size); - r->spi = clib_net_to_host_u32(spi); - DBG_PLD("spi %lx", r->spi); + clib_memcpy (&spi, n->payload, n->spi_size); + r->spi = clib_net_to_host_u32 (spi); + DBG_PLD ("spi %lx", r->spi); } else if (n->spi_size == 0) { @@ -432,63 +464,72 @@ ikev2_parse_notify_payload(ike_payload_header_t * ikep) } else { - clib_warning("invalid SPI Size %d", n->spi_size); + clib_warning ("invalid SPI Size %d", n->spi_size); } - if (plen > (sizeof(*n) + n->spi_size)) + if (plen > (sizeof (*n) + n->spi_size)) { - vec_add(r->data, n->payload + n->spi_size, plen - sizeof(*n) - n->spi_size); + vec_add (r->data, n->payload + n->spi_size, + plen - sizeof (*n) - n->spi_size); } return r; } void -ikev2_parse_vendor_payload(ike_payload_header_t * ikep) +ikev2_parse_vendor_payload (ike_payload_header_t * ikep) { - u32 plen = clib_net_to_host_u16(ikep->length); + u32 plen = clib_net_to_host_u16 (ikep->length); int i; int is_string = 1; - for(i=0; i < plen - 4; i++) - if (!isprint(ikep->payload[i])) + for (i = 0; i < plen - 4; i++) + if (!isprint (ikep->payload[i])) is_string = 0; - DBG_PLD("len %u data %s:%U", - plen, - is_string ? "string":"hex", - is_string ? format_ascii_bytes : format_hex_bytes, - ikep->payload, plen - sizeof(*ikep)); + DBG_PLD ("len %u data %s:%U", + plen, + is_string ? "string" : "hex", + is_string ? format_ascii_bytes : format_hex_bytes, + ikep->payload, plen - sizeof (*ikep)); } ikev2_delete_t * -ikev2_parse_delete_payload(ike_payload_header_t * ikep) +ikev2_parse_delete_payload (ike_payload_header_t * ikep) { - ike_delete_payload_header_t * d = (ike_delete_payload_header_t *) ikep; - u32 plen = clib_net_to_host_u16(ikep->length); - ikev2_delete_t * r = 0, * del; - u16 num_of_spi = clib_net_to_host_u16(d->num_of_spi); + ike_delete_payload_header_t *d = (ike_delete_payload_header_t *) ikep; + u32 plen = clib_net_to_host_u16 (ikep->length); + ikev2_delete_t *r = 0, *del; + u16 num_of_spi = clib_net_to_host_u16 (d->num_of_spi); u16 i = 0; - DBG_PLD("protocol_id %u spi_size %u num_of_spi %u len %u%s%U", - d->protocol_id, d->spi_size, num_of_spi, - plen, plen > sizeof(d) ? " data ":"", - format_hex_bytes, d->spi, plen - sizeof(*d)); + DBG_PLD ("protocol_id %u spi_size %u num_of_spi %u len %u%s%U", + d->protocol_id, d->spi_size, num_of_spi, + plen, plen > sizeof (d) ? " data " : "", + format_hex_bytes, d->spi, plen - sizeof (*d)); if (d->protocol_id == IKEV2_PROTOCOL_IKE) { - r = vec_new(ikev2_delete_t, 1); + r = vec_new (ikev2_delete_t, 1); r->protocol_id = 1; } else { - r = vec_new(ikev2_delete_t, num_of_spi); - vec_foreach(del, r) - { - del->protocol_id = d->protocol_id; - del->spi = clib_net_to_host_u32(d->spi[i++]); - } + r = vec_new (ikev2_delete_t, num_of_spi); + vec_foreach (del, r) + { + del->protocol_id = d->protocol_id; + del->spi = clib_net_to_host_u32 (d->spi[i++]); + } } return r; } + +/* + * fd.io coding-style-patch-verification: ON + * + * Local Variables: + * eval: (c-set-style "gnu") + * End: + */ diff --git a/vnet/vnet/ipsec/ikev2_priv.h b/vnet/vnet/ipsec/ikev2_priv.h index 731bb15e6b2..9f67ad2ae6f 100644 --- a/vnet/vnet/ipsec/ikev2_priv.h +++ b/vnet/vnet/ipsec/ikev2_priv.h @@ -38,7 +38,8 @@ #define DBG_PLD(my_args...) #endif -typedef enum { +typedef enum +{ IKEV2_STATE_UNKNOWN, IKEV2_STATE_SA_INIT, IKEV2_STATE_DELETED, @@ -49,101 +50,113 @@ typedef enum { IKEV2_STATE_NO_PROPOSAL_CHOSEN, } ikev2_state_t; -typedef struct { +typedef struct +{ ikev2_auth_method_t method:8; - u8 * data; - u8 hex; /* hex encoding of the shared secret */ - EVP_PKEY * key; + u8 *data; + u8 hex; /* hex encoding of the shared secret */ + EVP_PKEY *key; } ikev2_auth_t; -typedef enum { +typedef enum +{ IKEV2_DH_GROUP_MODP = 0, - IKEV2_DH_GROUP_ECP = 1, + IKEV2_DH_GROUP_ECP = 1, } ikev2_dh_group_t; -typedef struct { +typedef struct +{ ikev2_transform_type_t type; - union { - u16 transform_id; - ikev2_transform_encr_type_t encr_type:16; - ikev2_transform_prf_type_t prf_type:16; + union + { + u16 transform_id; + ikev2_transform_encr_type_t encr_type:16; + ikev2_transform_prf_type_t prf_type:16; ikev2_transform_integ_type_t integ_type:16; - ikev2_transform_dh_type_t dh_type:16; - ikev2_transform_esn_type_t esn_type:16; + ikev2_transform_dh_type_t dh_type:16; + ikev2_transform_esn_type_t esn_type:16; }; - u8 * attrs; + u8 *attrs; u16 key_len; u16 key_trunc; u16 block_size; u8 dh_group; int nid; - const char * dh_p; - const char * dh_g; - const void * md; - const void * cipher; + const char *dh_p; + const char *dh_g; + const void *md; + const void *cipher; } ikev2_sa_transform_t; -typedef struct { +typedef struct +{ u8 proposal_num; ikev2_protocol_id_t protocol_id:8; u32 spi; - ikev2_sa_transform_t * transforms; + ikev2_sa_transform_t *transforms; } ikev2_sa_proposal_t; -typedef struct { - u8 ts_type; - u8 protocol_id; - u16 selector_len; - u16 start_port; - u16 end_port; +typedef struct +{ + u8 ts_type; + u8 protocol_id; + u16 selector_len; + u16 start_port; + u16 end_port; ip4_address_t start_addr; ip4_address_t end_addr; } ikev2_ts_t; -typedef struct { +typedef struct +{ ikev2_id_type_t type:8; - u8 * data; + u8 *data; } ikev2_id_t; -typedef struct { +typedef struct +{ /* sa proposals vectors */ - ikev2_sa_proposal_t * i_proposals; - ikev2_sa_proposal_t * r_proposals; + ikev2_sa_proposal_t *i_proposals; + ikev2_sa_proposal_t *r_proposals; /* Traffic Selectors */ - ikev2_ts_t * tsi; - ikev2_ts_t * tsr; + ikev2_ts_t *tsi; + ikev2_ts_t *tsr; /* keys */ - u8 * sk_ai; - u8 * sk_ar; - u8 * sk_ei; - u8 * sk_er; + u8 *sk_ai; + u8 *sk_ar; + u8 *sk_ei; + u8 *sk_er; } ikev2_child_sa_t; -typedef struct { - u8 protocol_id; - u32 spi; /*for ESP and AH SPI size is 4, for IKE size is 0 */ +typedef struct +{ + u8 protocol_id; + u32 spi; /*for ESP and AH SPI size is 4, for IKE size is 0 */ } ikev2_delete_t; -typedef struct { +typedef struct +{ u8 protocol_id; u32 spi; - ikev2_sa_proposal_t * i_proposal; - ikev2_sa_proposal_t * r_proposal; - ikev2_ts_t * tsi; - ikev2_ts_t * tsr; + ikev2_sa_proposal_t *i_proposal; + ikev2_sa_proposal_t *r_proposal; + ikev2_ts_t *tsi; + ikev2_ts_t *tsr; } ikev2_rekey_t; -typedef struct { +typedef struct +{ u16 msg_type; u8 protocol_id; u32 spi; - u8 * data; + u8 *data; } ikev2_notify_t; -typedef struct { +typedef struct +{ ikev2_state_t state; u8 unsupported_cp; u8 initial_contact; @@ -151,27 +164,27 @@ typedef struct { ip4_address_t raddr; u64 ispi; u64 rspi; - u8 * i_nonce; - u8 * r_nonce; + u8 *i_nonce; + u8 *r_nonce; /* DH data */ - u16 dh_group; - u8 * dh_shared_key; - u8 * i_dh_data; - u8 * r_dh_data; + u16 dh_group; + u8 *dh_shared_key; + u8 *i_dh_data; + u8 *r_dh_data; /* sa proposals vectors */ - ikev2_sa_proposal_t * i_proposals; - ikev2_sa_proposal_t * r_proposals; + ikev2_sa_proposal_t *i_proposals; + ikev2_sa_proposal_t *r_proposals; /* keys */ - u8 * sk_d; - u8 * sk_ai; - u8 * sk_ar; - u8 * sk_ei; - u8 * sk_er; - u8 * sk_pi; - u8 * sk_pr; + u8 *sk_d; + u8 *sk_ai; + u8 *sk_ar; + u8 *sk_ei; + u8 *sk_er; + u8 *sk_pi; + u8 *sk_pr; /* auth */ ikev2_auth_t i_auth; @@ -182,24 +195,25 @@ typedef struct { ikev2_id_t r_id; /* pending deletes */ - ikev2_delete_t * del; + ikev2_delete_t *del; /* pending rekeyings */ - ikev2_rekey_t * rekey; + ikev2_rekey_t *rekey; /* packet data */ - u8 * last_sa_init_req_packet_data; - u8 * last_sa_init_res_packet_data; + u8 *last_sa_init_req_packet_data; + u8 *last_sa_init_res_packet_data; /* retransmit */ u32 last_msg_id; - u8 * last_res_packet_data; + u8 *last_res_packet_data; - ikev2_child_sa_t * childs; + ikev2_child_sa_t *childs; } ikev2_sa_t; -typedef struct { - u8 * name; +typedef struct +{ + u8 *name; u8 is_enabled; ikev2_auth_t auth; @@ -209,59 +223,64 @@ typedef struct { ikev2_ts_t rem_ts; } ikev2_profile_t; -typedef struct { - /* pool of IKEv2 Security Associations */ - ikev2_sa_t * sas; +typedef struct +{ + /* pool of IKEv2 Security Associations */ + ikev2_sa_t *sas; - /* hash */ - uword * sa_by_rspi; + /* hash */ + uword *sa_by_rspi; } ikev2_main_per_thread_data_t; -typedef struct { - /* pool of IKEv2 profiles */ - ikev2_profile_t * profiles; +typedef struct +{ + /* pool of IKEv2 profiles */ + ikev2_profile_t *profiles; - /* vector of supported transform types */ - ikev2_sa_transform_t * supported_transforms; + /* vector of supported transform types */ + ikev2_sa_transform_t *supported_transforms; - /* hash */ - mhash_t profile_index_by_name; + /* hash */ + mhash_t profile_index_by_name; - /* local private key */ - EVP_PKEY * pkey; + /* local private key */ + EVP_PKEY *pkey; - /* convenience */ - vlib_main_t * vlib_main; - vnet_main_t * vnet_main; + /* convenience */ + vlib_main_t *vlib_main; + vnet_main_t *vnet_main; - ikev2_main_per_thread_data_t * per_thread_data; + ikev2_main_per_thread_data_t *per_thread_data; } ikev2_main_t; ikev2_main_t ikev2_main; -void ikev2_sa_free_proposal_vector(ikev2_sa_proposal_t ** v); -ikev2_sa_transform_t * ikev2_sa_get_td_for_type(ikev2_sa_proposal_t * p, - ikev2_transform_type_t type); +void ikev2_sa_free_proposal_vector (ikev2_sa_proposal_t ** v); +ikev2_sa_transform_t *ikev2_sa_get_td_for_type (ikev2_sa_proposal_t * p, + ikev2_transform_type_t type); /* ikev2_crypto.c */ -v8 * ikev2_calc_prf(ikev2_sa_transform_t * tr, v8 * key, v8 * data); -u8 * ikev2_calc_prfplus(ikev2_sa_transform_t * tr, u8 * key, u8 * seed, int len); -v8 * ikev2_calc_integr(ikev2_sa_transform_t * tr, v8 * key, u8 * data, int len); -v8 * ikev2_decrypt_data(ikev2_sa_t * sa, u8 * data, int len); -int ikev2_encrypt_data(ikev2_sa_t * sa, v8 * src, u8 * dst); -void ikev2_generate_dh(ikev2_sa_t * sa, ikev2_sa_transform_t * t); -int ikev2_verify_sign(EVP_PKEY *pkey, u8 * sigbuf, u8 * data); -u8 * ikev2_calc_sign(EVP_PKEY *pkey, u8 * data); -EVP_PKEY * ikev2_load_cert_file(u8 * file); -EVP_PKEY * ikev2_load_key_file(u8 * file); +v8 *ikev2_calc_prf (ikev2_sa_transform_t * tr, v8 * key, v8 * data); +u8 *ikev2_calc_prfplus (ikev2_sa_transform_t * tr, u8 * key, u8 * seed, + int len); +v8 *ikev2_calc_integr (ikev2_sa_transform_t * tr, v8 * key, u8 * data, + int len); +v8 *ikev2_decrypt_data (ikev2_sa_t * sa, u8 * data, int len); +int ikev2_encrypt_data (ikev2_sa_t * sa, v8 * src, u8 * dst); +void ikev2_generate_dh (ikev2_sa_t * sa, ikev2_sa_transform_t * t); +int ikev2_verify_sign (EVP_PKEY * pkey, u8 * sigbuf, u8 * data); +u8 *ikev2_calc_sign (EVP_PKEY * pkey, u8 * data); +EVP_PKEY *ikev2_load_cert_file (u8 * file); +EVP_PKEY *ikev2_load_key_file (u8 * file); void ikev2_crypto_init (ikev2_main_t * km); /* ikev2_payload.c */ -typedef struct { +typedef struct +{ u8 first_payload_type; u16 last_hdr_off; - u8 * data; + u8 *data; } ikev2_payload_chain_t; #define ikev2_payload_new_chain(V) vec_validate (V, 0) @@ -270,20 +289,33 @@ typedef struct { vec_free(V); \ } while (0) -void ikev2_payload_add_notify(ikev2_payload_chain_t * c, u16 msg_type, u8 * data); -void ikev2_payload_add_sa(ikev2_payload_chain_t * c, ikev2_sa_proposal_t * proposals); -void ikev2_payload_add_ke(ikev2_payload_chain_t * c, u16 dh_group, u8 * dh_data); -void ikev2_payload_add_nonce(ikev2_payload_chain_t * c, u8 * nonce); -void ikev2_payload_add_id(ikev2_payload_chain_t *c, ikev2_id_t * id, u8 type); -void ikev2_payload_add_auth(ikev2_payload_chain_t *c, ikev2_auth_t * auth); -void ikev2_payload_add_ts(ikev2_payload_chain_t * c, ikev2_ts_t * ts, u8 type); -void ikev2_payload_add_delete(ikev2_payload_chain_t *c, ikev2_delete_t * d); -void ikev2_payload_chain_add_padding(ikev2_payload_chain_t * c, int bs); -void ikev2_parse_vendor_payload(ike_payload_header_t * ikep); -ikev2_sa_proposal_t * ikev2_parse_sa_payload(ike_payload_header_t * ikep); -ikev2_ts_t * ikev2_parse_ts_payload(ike_payload_header_t * ikep); -ikev2_delete_t * ikev2_parse_delete_payload(ike_payload_header_t * ikep); -ikev2_notify_t * ikev2_parse_notify_payload(ike_payload_header_t * ikep); +void ikev2_payload_add_notify (ikev2_payload_chain_t * c, u16 msg_type, + u8 * data); +void ikev2_payload_add_sa (ikev2_payload_chain_t * c, + ikev2_sa_proposal_t * proposals); +void ikev2_payload_add_ke (ikev2_payload_chain_t * c, u16 dh_group, + u8 * dh_data); +void ikev2_payload_add_nonce (ikev2_payload_chain_t * c, u8 * nonce); +void ikev2_payload_add_id (ikev2_payload_chain_t * c, ikev2_id_t * id, + u8 type); +void ikev2_payload_add_auth (ikev2_payload_chain_t * c, ikev2_auth_t * auth); +void ikev2_payload_add_ts (ikev2_payload_chain_t * c, ikev2_ts_t * ts, + u8 type); +void ikev2_payload_add_delete (ikev2_payload_chain_t * c, ikev2_delete_t * d); +void ikev2_payload_chain_add_padding (ikev2_payload_chain_t * c, int bs); +void ikev2_parse_vendor_payload (ike_payload_header_t * ikep); +ikev2_sa_proposal_t *ikev2_parse_sa_payload (ike_payload_header_t * ikep); +ikev2_ts_t *ikev2_parse_ts_payload (ike_payload_header_t * ikep); +ikev2_delete_t *ikev2_parse_delete_payload (ike_payload_header_t * ikep); +ikev2_notify_t *ikev2_parse_notify_payload (ike_payload_header_t * ikep); #endif /* __included_ikev2_priv_h__ */ + +/* + * fd.io coding-style-patch-verification: ON + * + * Local Variables: + * eval: (c-set-style "gnu") + * End: + */ diff --git a/vnet/vnet/ipsec/ipsec.c b/vnet/vnet/ipsec/ipsec.c index 1c9d57b1a24..b3075bf7598 100644 --- a/vnet/vnet/ipsec/ipsec.c +++ b/vnet/vnet/ipsec/ipsec.c @@ -25,11 +25,12 @@ #include <vnet/ipsec/ikev2.h> int -ipsec_set_interface_spd(vlib_main_t * vm, u32 sw_if_index, u32 spd_id, int is_add) +ipsec_set_interface_spd (vlib_main_t * vm, u32 sw_if_index, u32 spd_id, + int is_add) { ipsec_main_t *im = &ipsec_main; - ip_lookup_main_t * lm; - ip_config_main_t * rx_cm; + ip_lookup_main_t *lm; + ip_config_main_t *rx_cm; ip4_ipsec_config_t config; u32 spd_index, ci; @@ -37,13 +38,13 @@ ipsec_set_interface_spd(vlib_main_t * vm, u32 sw_if_index, u32 spd_id, int is_ad p = hash_get (im->spd_index_by_spd_id, spd_id); if (!p) - return VNET_API_ERROR_SYSCALL_ERROR_1; /* no such spd-id */ + return VNET_API_ERROR_SYSCALL_ERROR_1; /* no such spd-id */ spd_index = p[0]; p = hash_get (im->spd_index_by_sw_if_index, sw_if_index); if (p && is_add) - return VNET_API_ERROR_SYSCALL_ERROR_1; /* spd already assigned */ + return VNET_API_ERROR_SYSCALL_ERROR_1; /* spd already assigned */ if (is_add) { @@ -54,12 +55,12 @@ ipsec_set_interface_spd(vlib_main_t * vm, u32 sw_if_index, u32 spd_id, int is_ad hash_unset (im->spd_index_by_sw_if_index, sw_if_index); } - clib_warning("sw_if_index %u spd_id %u spd_index %u", - sw_if_index, spd_id, spd_index); + clib_warning ("sw_if_index %u spd_id %u spd_index %u", + sw_if_index, spd_id, spd_index); /* enable IPsec on TX */ - vnet_interface_add_del_feature(im->vnet_main, vm, sw_if_index, - INTF_OUTPUT_FEAT_IPSEC, is_add); + vnet_interface_add_del_feature (im->vnet_main, vm, sw_if_index, + INTF_OUTPUT_FEAT_IPSEC, is_add); /* enable IPsec on RX */ config.spd_index = spd_index; @@ -72,10 +73,7 @@ ipsec_set_interface_spd(vlib_main_t * vm, u32 sw_if_index, u32 spd_id, int is_ad ci = (is_add ? vnet_config_add_feature : vnet_config_del_feature) (vm, &rx_cm->config_main, - ci, - ip4_main.ip4_unicast_rx_feature_ipsec, - &config, - sizeof (config)); + ci, ip4_main.ip4_unicast_rx_feature_ipsec, &config, sizeof (config)); rx_cm->config_index_by_sw_if_index[sw_if_index] = ci; /* IPv6 */ @@ -86,20 +84,17 @@ ipsec_set_interface_spd(vlib_main_t * vm, u32 sw_if_index, u32 spd_id, int is_ad ci = (is_add ? vnet_config_add_feature : vnet_config_del_feature) (vm, &rx_cm->config_main, - ci, - ip6_main.ip6_unicast_rx_feature_ipsec, - &config, - sizeof (config)); + ci, ip6_main.ip6_unicast_rx_feature_ipsec, &config, sizeof (config)); rx_cm->config_index_by_sw_if_index[sw_if_index] = ci; return 0; } int -ipsec_add_del_spd(vlib_main_t * vm, u32 spd_id, int is_add) +ipsec_add_del_spd (vlib_main_t * vm, u32 spd_id, int is_add) { ipsec_main_t *im = &ipsec_main; - ipsec_spd_t * spd = 0; + ipsec_spd_t *spd = 0; uword *p; u32 spd_index, k, v; @@ -109,16 +104,18 @@ ipsec_add_del_spd(vlib_main_t * vm, u32 spd_id, int is_add) if (!p && !is_add) return VNET_API_ERROR_INVALID_VALUE; - if (!is_add) /* delete */ + if (!is_add) /* delete */ { spd_index = p[0]; - spd = pool_elt_at_index(im->spds, spd_index); + spd = pool_elt_at_index (im->spds, spd_index); if (!spd) - return VNET_API_ERROR_INVALID_VALUE; + return VNET_API_ERROR_INVALID_VALUE; + /* *INDENT-OFF* */ hash_foreach (k, v, im->spd_index_by_sw_if_index, ({ if (v == spd_index) ipsec_set_interface_spd(vm, k, spd_id, 0); })); + /* *INDENT-ON* */ hash_unset (im->spd_index_by_spd_id, spd_id); pool_free (spd->policies); vec_free (spd->ipv4_outbound_policies); @@ -127,7 +124,7 @@ ipsec_add_del_spd(vlib_main_t * vm, u32 spd_id, int is_add) vec_free (spd->ipv4_inbound_policy_discard_and_bypass_indices); pool_put (im->spds, spd); } - else /* create new SPD */ + else /* create new SPD */ { pool_get (im->spds, spd); memset (spd, 0, sizeof (*spd)); @@ -139,40 +136,43 @@ ipsec_add_del_spd(vlib_main_t * vm, u32 spd_id, int is_add) } static int -ipsec_spd_entry_sort(void * a1, void * a2) +ipsec_spd_entry_sort (void *a1, void *a2) { ipsec_main_t *im = &ipsec_main; - u32 * id1 = a1; - u32 * id2 = a2; - ipsec_spd_t * spd; - ipsec_policy_t * p1, * p2; + u32 *id1 = a1; + u32 *id2 = a2; + ipsec_spd_t *spd; + ipsec_policy_t *p1, *p2; + /* *INDENT-OFF* */ pool_foreach (spd, im->spds, ({ p1 = pool_elt_at_index(spd->policies, *id1); p2 = pool_elt_at_index(spd->policies, *id2); if (p1 && p2) return p2->priority - p1->priority; })); + /* *INDENT-ON* */ return 0; } int -ipsec_add_del_policy(vlib_main_t * vm, ipsec_policy_t * policy, int is_add) +ipsec_add_del_policy (vlib_main_t * vm, ipsec_policy_t * policy, int is_add) { ipsec_main_t *im = &ipsec_main; - ipsec_spd_t * spd = 0; - ipsec_policy_t * vp; + ipsec_spd_t *spd = 0; + ipsec_policy_t *vp; uword *p; u32 spd_index; - clib_warning("policy-id %u priority %d is_outbound %u",policy->id, policy->priority, policy->is_outbound); + clib_warning ("policy-id %u priority %d is_outbound %u", policy->id, + policy->priority, policy->is_outbound); if (policy->policy == IPSEC_POLICY_ACTION_PROTECT) { - p = hash_get(im->sa_index_by_sa_id, policy->sa_id); + p = hash_get (im->sa_index_by_sa_id, policy->sa_id); if (!p) - return VNET_API_ERROR_SYSCALL_ERROR_1; + return VNET_API_ERROR_SYSCALL_ERROR_1; policy->sa_index = p[0]; } @@ -182,7 +182,7 @@ ipsec_add_del_policy(vlib_main_t * vm, ipsec_policy_t * policy, int is_add) return VNET_API_ERROR_SYSCALL_ERROR_1; spd_index = p[0]; - spd = pool_elt_at_index(im->spds, spd_index); + spd = pool_elt_at_index (im->spds, spd_index); if (!spd) return VNET_API_ERROR_SYSCALL_ERROR_1; @@ -195,72 +195,75 @@ ipsec_add_del_policy(vlib_main_t * vm, ipsec_policy_t * policy, int is_add) policy_index = vp - spd->policies; if (policy->is_outbound) - { - if (policy->is_ipv6) - { - vec_add1 (spd->ipv6_outbound_policies, policy_index); - clib_memcpy(vp, policy, sizeof(ipsec_policy_t)); - vec_sort_with_function (spd->ipv6_outbound_policies, - ipsec_spd_entry_sort); - } - else - { - vec_add1 (spd->ipv4_outbound_policies, policy_index); - clib_memcpy(vp, policy, sizeof(ipsec_policy_t)); - vec_sort_with_function (spd->ipv4_outbound_policies, - ipsec_spd_entry_sort); - } - } + { + if (policy->is_ipv6) + { + vec_add1 (spd->ipv6_outbound_policies, policy_index); + clib_memcpy (vp, policy, sizeof (ipsec_policy_t)); + vec_sort_with_function (spd->ipv6_outbound_policies, + ipsec_spd_entry_sort); + } + else + { + vec_add1 (spd->ipv4_outbound_policies, policy_index); + clib_memcpy (vp, policy, sizeof (ipsec_policy_t)); + vec_sort_with_function (spd->ipv4_outbound_policies, + ipsec_spd_entry_sort); + } + } else - { - if (policy->is_ipv6) - { - if (policy->policy == IPSEC_POLICY_ACTION_PROTECT) - { - vec_add1 (spd->ipv6_inbound_protect_policy_indices, - policy_index); - clib_memcpy(vp, policy, sizeof(ipsec_policy_t)); - vec_sort_with_function ( - spd->ipv6_inbound_protect_policy_indices, - ipsec_spd_entry_sort); - } - else - { - vec_add1 (spd->ipv6_inbound_policy_discard_and_bypass_indices, - policy_index); - clib_memcpy(vp, policy, sizeof(ipsec_policy_t)); - vec_sort_with_function ( - spd->ipv6_inbound_policy_discard_and_bypass_indices, - ipsec_spd_entry_sort); - } - } - else - { - if (policy->policy == IPSEC_POLICY_ACTION_PROTECT) - { - vec_add1 (spd->ipv4_inbound_protect_policy_indices, - policy_index); - clib_memcpy(vp, policy, sizeof(ipsec_policy_t)); - vec_sort_with_function ( - spd->ipv4_inbound_protect_policy_indices, - ipsec_spd_entry_sort); - } - else - { - vec_add1 (spd->ipv4_inbound_policy_discard_and_bypass_indices, - policy_index); - clib_memcpy(vp, policy, sizeof(ipsec_policy_t)); - vec_sort_with_function ( - spd->ipv4_inbound_policy_discard_and_bypass_indices, - ipsec_spd_entry_sort); - } - } - } + { + if (policy->is_ipv6) + { + if (policy->policy == IPSEC_POLICY_ACTION_PROTECT) + { + vec_add1 (spd->ipv6_inbound_protect_policy_indices, + policy_index); + clib_memcpy (vp, policy, sizeof (ipsec_policy_t)); + vec_sort_with_function (spd-> + ipv6_inbound_protect_policy_indices, + ipsec_spd_entry_sort); + } + else + { + vec_add1 (spd-> + ipv6_inbound_policy_discard_and_bypass_indices, + policy_index); + clib_memcpy (vp, policy, sizeof (ipsec_policy_t)); + vec_sort_with_function (spd-> + ipv6_inbound_policy_discard_and_bypass_indices, + ipsec_spd_entry_sort); + } + } + else + { + if (policy->policy == IPSEC_POLICY_ACTION_PROTECT) + { + vec_add1 (spd->ipv4_inbound_protect_policy_indices, + policy_index); + clib_memcpy (vp, policy, sizeof (ipsec_policy_t)); + vec_sort_with_function (spd-> + ipv4_inbound_protect_policy_indices, + ipsec_spd_entry_sort); + } + else + { + vec_add1 (spd-> + ipv4_inbound_policy_discard_and_bypass_indices, + policy_index); + clib_memcpy (vp, policy, sizeof (ipsec_policy_t)); + vec_sort_with_function (spd-> + ipv4_inbound_policy_discard_and_bypass_indices, + ipsec_spd_entry_sort); + } + } + } } else { u32 i, j; + /* *INDENT-OFF* */ pool_foreach_index(i, spd->policies, ({ vp = pool_elt_at_index(spd->policies, i); if (vp->priority != policy->priority) @@ -376,18 +379,20 @@ ipsec_add_del_policy(vlib_main_t * vm, ipsec_policy_t * policy, int is_add) break; } })); + /* *INDENT-ON* */ } return 0; } static u8 -ipsec_is_sa_used(u32 sa_index) +ipsec_is_sa_used (u32 sa_index) { - ipsec_main_t * im = &ipsec_main; - ipsec_spd_t * spd; - ipsec_policy_t * p; + ipsec_main_t *im = &ipsec_main; + ipsec_spd_t *spd; + ipsec_policy_t *p; + /* *INDENT-OFF* */ pool_foreach(spd, im->spds, ({ pool_foreach(p, spd->policies, ({ if (p->policy == IPSEC_POLICY_ACTION_PROTECT) @@ -397,39 +402,40 @@ ipsec_is_sa_used(u32 sa_index) } })); })); + /* *INDENT-ON* */ return 0; } int -ipsec_add_del_sa(vlib_main_t * vm, ipsec_sa_t * new_sa, int is_add) +ipsec_add_del_sa (vlib_main_t * vm, ipsec_sa_t * new_sa, int is_add) { ipsec_main_t *im = &ipsec_main; - ipsec_sa_t * sa = 0; + ipsec_sa_t *sa = 0; uword *p; u32 sa_index; - clib_warning("id %u spi %u", new_sa->id, new_sa->spi); + clib_warning ("id %u spi %u", new_sa->id, new_sa->spi); p = hash_get (im->sa_index_by_sa_id, new_sa->id); if (p && is_add) - return VNET_API_ERROR_SYSCALL_ERROR_1; /* already exists */ + return VNET_API_ERROR_SYSCALL_ERROR_1; /* already exists */ if (!p && !is_add) return VNET_API_ERROR_SYSCALL_ERROR_1; - if (!is_add) /* delete */ + if (!is_add) /* delete */ { sa_index = p[0]; - sa = pool_elt_at_index(im->sad, sa_index); - if (ipsec_is_sa_used(sa_index)) - { - clib_warning("sa_id %u used in policy", sa->id); - return VNET_API_ERROR_SYSCALL_ERROR_1; /* sa used in policy */ - } + sa = pool_elt_at_index (im->sad, sa_index); + if (ipsec_is_sa_used (sa_index)) + { + clib_warning ("sa_id %u used in policy", sa->id); + return VNET_API_ERROR_SYSCALL_ERROR_1; /* sa used in policy */ + } hash_unset (im->sa_index_by_sa_id, sa->id); pool_put (im->sad, sa); } - else /* create new SA */ + else /* create new SA */ { pool_get (im->sad, sa); clib_memcpy (sa, new_sa, sizeof (*sa)); @@ -440,31 +446,33 @@ ipsec_add_del_sa(vlib_main_t * vm, ipsec_sa_t * new_sa, int is_add) } int -ipsec_set_sa_key(vlib_main_t * vm, ipsec_sa_t * sa_update) +ipsec_set_sa_key (vlib_main_t * vm, ipsec_sa_t * sa_update) { ipsec_main_t *im = &ipsec_main; uword *p; u32 sa_index; - ipsec_sa_t * sa = 0; + ipsec_sa_t *sa = 0; p = hash_get (im->sa_index_by_sa_id, sa_update->id); if (!p) - return VNET_API_ERROR_SYSCALL_ERROR_1; /* no such sa-id */ + return VNET_API_ERROR_SYSCALL_ERROR_1; /* no such sa-id */ sa_index = p[0]; - sa = pool_elt_at_index(im->sad, sa_index); + sa = pool_elt_at_index (im->sad, sa_index); /* new crypto key */ if (0 < sa_update->crypto_key_len) { - clib_memcpy(sa->crypto_key, sa_update->crypto_key, sa_update->crypto_key_len); + clib_memcpy (sa->crypto_key, sa_update->crypto_key, + sa_update->crypto_key_len); sa->crypto_key_len = sa_update->crypto_key_len; } /* new integ key */ if (0 < sa_update->integ_key_len) { - clib_memcpy(sa->integ_key, sa_update->integ_key, sa_update->integ_key_len); + clib_memcpy (sa->integ_key, sa_update->integ_key, + sa_update->integ_key_len); sa->integ_key_len = sa_update->integ_key_len; } @@ -472,52 +480,54 @@ ipsec_set_sa_key(vlib_main_t * vm, ipsec_sa_t * sa_update) } static void -ipsec_rand_seed(void) +ipsec_rand_seed (void) { - struct { + struct + { time_t time; pid_t pid; - void * p; + void *p; } seed_data; - seed_data.time = time(NULL); - seed_data.pid = getpid(); - seed_data.p = (void *)&seed_data; + seed_data.time = time (NULL); + seed_data.pid = getpid (); + seed_data.p = (void *) &seed_data; - RAND_seed((const void *)&seed_data, sizeof(seed_data)); + RAND_seed ((const void *) &seed_data, sizeof (seed_data)); } static clib_error_t * ipsec_init (vlib_main_t * vm) { - clib_error_t * error; - ipsec_main_t * im = &ipsec_main; - vlib_thread_main_t * tm = vlib_get_thread_main(); - vlib_node_t * node; + clib_error_t *error; + ipsec_main_t *im = &ipsec_main; + vlib_thread_main_t *tm = vlib_get_thread_main (); + vlib_node_t *node; - ipsec_rand_seed(); + ipsec_rand_seed (); memset (im, 0, sizeof (im[0])); - im->vnet_main = vnet_get_main(); + im->vnet_main = vnet_get_main (); im->vlib_main = vm; - im->spd_index_by_spd_id = hash_create (0, sizeof (uword)); - im->sa_index_by_sa_id = hash_create (0, sizeof (uword)); + im->spd_index_by_spd_id = hash_create (0, sizeof (uword)); + im->sa_index_by_sa_id = hash_create (0, sizeof (uword)); im->spd_index_by_sw_if_index = hash_create (0, sizeof (uword)); - vec_validate_aligned(im->empty_buffers, tm->n_vlib_mains-1, CLIB_CACHE_LINE_BYTES); + vec_validate_aligned (im->empty_buffers, tm->n_vlib_mains - 1, + CLIB_CACHE_LINE_BYTES); node = vlib_get_node_by_name (vm, (u8 *) "error-drop"); - ASSERT(node); + ASSERT (node); im->error_drop_node_index = node->index; node = vlib_get_node_by_name (vm, (u8 *) "esp-encrypt"); - ASSERT(node); + ASSERT (node); im->esp_encrypt_node_index = node->index; node = vlib_get_node_by_name (vm, (u8 *) "ip4-lookup"); - ASSERT(node); + ASSERT (node); im->ip4_lookup_node_index = node->index; @@ -527,7 +537,7 @@ ipsec_init (vlib_main_t * vm) if ((error = vlib_call_init_function (vm, ipsec_tunnel_if_init))) return error; - esp_init(); + esp_init (); if ((error = ikev2_init (vm))) return error; @@ -536,3 +546,11 @@ ipsec_init (vlib_main_t * vm) } VLIB_INIT_FUNCTION (ipsec_init); + +/* + * fd.io coding-style-patch-verification: ON + * + * Local Variables: + * eval: (c-set-style "gnu") + * End: + */ diff --git a/vnet/vnet/ipsec/ipsec.h b/vnet/vnet/ipsec/ipsec.h index 564a8e12fb8..5c43bf51ce7 100644 --- a/vnet/vnet/ipsec/ipsec.h +++ b/vnet/vnet/ipsec/ipsec.h @@ -22,11 +22,12 @@ _(2, RESOLVE, "resolve") \ _(3, PROTECT, "protect") -typedef enum { +typedef enum +{ #define _(v,f,s) IPSEC_POLICY_ACTION_##f = v, foreach_ipsec_policy_action #undef _ - IPSEC_POLICY_N_ACTION, + IPSEC_POLICY_N_ACTION, } ipsec_policy_action_t; #define foreach_ipsec_crypto_alg \ @@ -35,11 +36,12 @@ typedef enum { _(2, AES_CBC_192, "aes-cbc-192") \ _(3, AES_CBC_256, "aes-cbc-256") -typedef enum { +typedef enum +{ #define _(v,f,s) IPSEC_CRYPTO_ALG_##f = v, foreach_ipsec_crypto_alg #undef _ - IPSEC_CRYPTO_N_ALG, + IPSEC_CRYPTO_N_ALG, } ipsec_crypto_alg_t; #define foreach_ipsec_integ_alg \ @@ -49,58 +51,64 @@ 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 */ + _(6, SHA_512_256, "sha-512-256") /* RFC4868 */ -typedef enum { +typedef enum +{ #define _(v,f,s) IPSEC_INTEG_ALG_##f = v, foreach_ipsec_integ_alg #undef _ - IPSEC_INTEG_N_ALG, + IPSEC_INTEG_N_ALG, } ipsec_integ_alg_t; -typedef enum { - IPSEC_PROTOCOL_AH = 0, - IPSEC_PROTOCOL_ESP = 1 +typedef enum +{ + IPSEC_PROTOCOL_AH = 0, + IPSEC_PROTOCOL_ESP = 1 } ipsec_protocol_t; -typedef struct { - u32 id; - u32 spi; - ipsec_protocol_t protocol; - - ipsec_crypto_alg_t crypto_alg; - u8 crypto_key_len; - u8 crypto_key[128]; - - ipsec_integ_alg_t integ_alg; - u8 integ_key_len; - u8 integ_key[128]; - - u8 use_esn; - u8 use_anti_replay; - - u8 is_tunnel; - u8 is_tunnel_ip6; - ip46_address_t tunnel_src_addr; - ip46_address_t tunnel_dst_addr; - - /* runtime */ - u32 seq; - u32 seq_hi; - u32 last_seq; - u32 last_seq_hi; - u64 replay_window; +typedef struct +{ + u32 id; + u32 spi; + ipsec_protocol_t protocol; + + ipsec_crypto_alg_t crypto_alg; + u8 crypto_key_len; + u8 crypto_key[128]; + + ipsec_integ_alg_t integ_alg; + u8 integ_key_len; + u8 integ_key[128]; + + u8 use_esn; + u8 use_anti_replay; + + u8 is_tunnel; + u8 is_tunnel_ip6; + ip46_address_t tunnel_src_addr; + ip46_address_t tunnel_dst_addr; + + /* runtime */ + u32 seq; + u32 seq_hi; + u32 last_seq; + u32 last_seq_hi; + u64 replay_window; } ipsec_sa_t; -typedef struct { +typedef struct +{ ip46_address_t start, stop; } ip46_address_range_t; -typedef struct { +typedef struct +{ u16 start, stop; } port_range_t; -typedef struct { +typedef struct +{ u8 is_add; u8 esn; u8 anti_replay; @@ -119,7 +127,8 @@ typedef struct { u8 remote_integ_key[128]; } ipsec_add_del_tunnel_args_t; -typedef enum { +typedef enum +{ IPSEC_IF_SET_KEY_TYPE_NONE, IPSEC_IF_SET_KEY_TYPE_LOCAL_CRYPTO, IPSEC_IF_SET_KEY_TYPE_REMOTE_CRYPTO, @@ -127,67 +136,73 @@ typedef enum { IPSEC_IF_SET_KEY_TYPE_REMOTE_INTEG, } ipsec_if_set_key_type_t; -typedef struct { - u32 id; - i32 priority; - u8 is_outbound; - - // Selector - u8 is_ipv6; - ip46_address_range_t laddr; - ip46_address_range_t raddr; - u8 protocol; - port_range_t lport; - port_range_t rport; - - // Policy - u8 policy; - u32 sa_id; - u32 sa_index; - - // Counter - vlib_counter_t counter; +typedef struct +{ + u32 id; + i32 priority; + u8 is_outbound; + + // Selector + u8 is_ipv6; + ip46_address_range_t laddr; + ip46_address_range_t raddr; + u8 protocol; + port_range_t lport; + port_range_t rport; + + // Policy + u8 policy; + u32 sa_id; + u32 sa_index; + + // Counter + vlib_counter_t counter; } ipsec_policy_t; -typedef struct { - u32 id; - /* pool of policies */ - ipsec_policy_t * policies; - /* vectors of policy indices */ - u32 * ipv4_outbound_policies; - u32 * ipv6_outbound_policies; - u32 * ipv4_inbound_protect_policy_indices; - u32 * ipv4_inbound_policy_discard_and_bypass_indices; - u32 * ipv6_inbound_protect_policy_indices; - u32 * ipv6_inbound_policy_discard_and_bypass_indices; +typedef struct +{ + u32 id; + /* pool of policies */ + ipsec_policy_t *policies; + /* vectors of policy indices */ + u32 *ipv4_outbound_policies; + u32 *ipv6_outbound_policies; + u32 *ipv4_inbound_protect_policy_indices; + u32 *ipv4_inbound_policy_discard_and_bypass_indices; + u32 *ipv6_inbound_protect_policy_indices; + u32 *ipv6_inbound_policy_discard_and_bypass_indices; } ipsec_spd_t; -typedef struct { +typedef struct +{ u32 spd_index; } ip4_ipsec_config_t; -typedef struct { +typedef struct +{ u32 spd_index; } ip6_ipsec_config_t; -typedef struct { +typedef struct +{ u32 input_sa_index; u32 output_sa_index; u32 hw_if_index; } ipsec_tunnel_if_t; -typedef struct { +typedef struct +{ /* pool of tunnel instances */ - ipsec_spd_t * spds; - ipsec_sa_t * sad; + ipsec_spd_t *spds; + ipsec_sa_t *sad; /* pool of tunnel interfaces */ - ipsec_tunnel_if_t * tunnel_interfaces; - u32 * free_tunnel_if_indices; + ipsec_tunnel_if_t *tunnel_interfaces; + u32 *free_tunnel_if_indices; - u32 ** empty_buffers; + u32 **empty_buffers; - uword * tunnel_index_by_key; + uword *tunnel_index_by_key; /* convenience */ vlib_main_t *vlib_main; @@ -197,10 +212,10 @@ typedef struct { u32 feature_next_node_index[32]; /* hashes */ - uword * spd_index_by_spd_id; - uword * spd_index_by_sw_if_index; - uword * sa_index_by_sa_id; - uword * ipsec_if_pool_index_by_key; + uword *spd_index_by_spd_id; + uword *spd_index_by_sw_if_index; + uword *sa_index_by_sa_id; + uword *ipsec_if_pool_index_by_key; /* node indexes */ u32 error_drop_node_index; @@ -220,24 +235,27 @@ extern vlib_node_registration_t ipsec_if_input_node; /* * functions */ -int ipsec_set_interface_spd(vlib_main_t * vm, u32 sw_if_index, u32 spd_id, int is_add); -int ipsec_add_del_spd(vlib_main_t * vm, u32 spd_id, int is_add); -int ipsec_add_del_policy(vlib_main_t * vm, ipsec_policy_t * policy, int is_add); -int ipsec_add_del_sa(vlib_main_t * vm, ipsec_sa_t * new_sa, int is_add); -int ipsec_set_sa_key(vlib_main_t * vm, ipsec_sa_t * sa_update); - -u8 * format_ipsec_if_output_trace (u8 * s, va_list * args); -u8 * format_ipsec_policy_action (u8 * s, va_list * args); -u8 * format_ipsec_crypto_alg (u8 * s, va_list * args); -u8 * format_ipsec_integ_alg (u8 * s, va_list * args); -u8 * format_ipsec_replay_window(u8 * s, va_list * args); +int ipsec_set_interface_spd (vlib_main_t * vm, u32 sw_if_index, u32 spd_id, + int is_add); +int ipsec_add_del_spd (vlib_main_t * vm, u32 spd_id, int is_add); +int ipsec_add_del_policy (vlib_main_t * vm, ipsec_policy_t * policy, + int is_add); +int ipsec_add_del_sa (vlib_main_t * vm, ipsec_sa_t * new_sa, int is_add); +int ipsec_set_sa_key (vlib_main_t * vm, ipsec_sa_t * sa_update); + +u8 *format_ipsec_if_output_trace (u8 * s, va_list * args); +u8 *format_ipsec_policy_action (u8 * s, va_list * args); +u8 *format_ipsec_crypto_alg (u8 * s, va_list * args); +u8 *format_ipsec_integ_alg (u8 * s, va_list * args); +u8 *format_ipsec_replay_window (u8 * s, va_list * args); uword unformat_ipsec_policy_action (unformat_input_t * input, va_list * args); uword unformat_ipsec_crypto_alg (unformat_input_t * input, va_list * args); uword unformat_ipsec_integ_alg (unformat_input_t * input, va_list * args); /*u32 ipsec_add_del_tunnel_if (vnet_main_t * vnm, ipsec_add_del_tunnel_args_t * args); */ int ipsec_add_del_tunnel_if (ipsec_add_del_tunnel_args_t * args); -int ipsec_set_interface_key(vnet_main_t * vnm, u32 hw_if_index, ipsec_if_set_key_type_t type, u8 alg, u8 * key); +int ipsec_set_interface_key (vnet_main_t * vnm, u32 hw_if_index, + ipsec_if_set_key_type_t type, u8 alg, u8 * key); /* @@ -245,63 +263,73 @@ int ipsec_set_interface_key(vnet_main_t * vnm, u32 hw_if_index, ipsec_if_set_key */ always_inline void -ipsec_alloc_empty_buffers(vlib_main_t * vm, ipsec_main_t *im) +ipsec_alloc_empty_buffers (vlib_main_t * vm, ipsec_main_t * im) { #if DPDK==1 - dpdk_main_t * dm = &dpdk_main; + dpdk_main_t *dm = &dpdk_main; u32 free_list_index = dm->vlib_buffer_free_list_index; #else u32 free_list_index = VLIB_BUFFER_DEFAULT_FREE_LIST_INDEX; #endif - u32 cpu_index = os_get_cpu_number(); + u32 cpu_index = os_get_cpu_number (); uword l = vec_len (im->empty_buffers[cpu_index]); uword n_alloc = 0; - if (PREDICT_FALSE(l < VLIB_FRAME_SIZE)) + if (PREDICT_FALSE (l < VLIB_FRAME_SIZE)) { - if (!im->empty_buffers[cpu_index]) { - vec_alloc (im->empty_buffers[cpu_index], 2 * VLIB_FRAME_SIZE ); - } + if (!im->empty_buffers[cpu_index]) + { + vec_alloc (im->empty_buffers[cpu_index], 2 * VLIB_FRAME_SIZE); + } n_alloc = vlib_buffer_alloc_from_free_list (vm, - im->empty_buffers[cpu_index] + l, - 2 * VLIB_FRAME_SIZE - l, - free_list_index); + im-> + empty_buffers[cpu_index] + + l, 2 * VLIB_FRAME_SIZE - l, + free_list_index); _vec_len (im->empty_buffers[cpu_index]) = l + n_alloc; } } -static_always_inline u32 /* FIXME move to interface???.h */ -get_next_output_feature_node_index( vnet_main_t * vnm, - vlib_buffer_t * b) +static_always_inline u32 /* FIXME move to interface???.h */ +get_next_output_feature_node_index (vnet_main_t * vnm, vlib_buffer_t * b) { - vlib_main_t * vm = vlib_get_main(); - vlib_node_t * node; + vlib_main_t *vm = vlib_get_main (); + vlib_node_t *node; u32 r; intf_output_feat_t next_feature; - u8 * node_names[] = { + u8 *node_names[] = { #define _(sym, str) (u8 *) str, foreach_intf_output_feat #undef _ }; - count_trailing_zeros(next_feature, vnet_buffer(b)->output_features.bitmap); + count_trailing_zeros (next_feature, + vnet_buffer (b)->output_features.bitmap); if (next_feature >= INTF_OUTPUT_FEAT_DONE) { - u32 sw_if_index = vnet_buffer(b)->sw_if_index[VLIB_TX]; - vnet_hw_interface_t * hw = vnet_get_sup_hw_interface(vnm, sw_if_index); + u32 sw_if_index = vnet_buffer (b)->sw_if_index[VLIB_TX]; + vnet_hw_interface_t *hw = vnet_get_sup_hw_interface (vnm, sw_if_index); r = hw->output_node_index; } else { - vnet_buffer(b)->output_features.bitmap &= ~(1 << next_feature); + vnet_buffer (b)->output_features.bitmap &= ~(1 << next_feature); /* FIXME */ - node = vlib_get_node_by_name(vm, node_names[next_feature]); + node = vlib_get_node_by_name (vm, node_names[next_feature]); r = node->index; } return r; } + +/* + * fd.io coding-style-patch-verification: ON + * + * Local Variables: + * eval: (c-set-style "gnu") + * End: + */ diff --git a/vnet/vnet/ipsec/ipsec_cli.c b/vnet/vnet/ipsec/ipsec_cli.c index 7150dcff154..f25547003b6 100644 --- a/vnet/vnet/ipsec/ipsec_cli.c +++ b/vnet/vnet/ipsec/ipsec_cli.c @@ -24,327 +24,363 @@ static clib_error_t * set_interface_spd_command_fn (vlib_main_t * vm, - unformat_input_t * input, - vlib_cli_command_t * cmd) + unformat_input_t * input, + vlib_cli_command_t * cmd) { - unformat_input_t _line_input, * line_input = &_line_input; + unformat_input_t _line_input, *line_input = &_line_input; ipsec_main_t *im = &ipsec_main; - u32 sw_if_index = (u32) ~0; + u32 sw_if_index = (u32) ~ 0; u32 spd_id; int is_add = 1; - if (! unformat_user (input, unformat_line_input, line_input)) + if (!unformat_user (input, unformat_line_input, line_input)) return 0; - if (unformat (line_input, "%U %u", unformat_vnet_sw_interface, im->vnet_main, - &sw_if_index, &spd_id)) + if (unformat + (line_input, "%U %u", unformat_vnet_sw_interface, im->vnet_main, + &sw_if_index, &spd_id)) ; else if (unformat (line_input, "del")) is_add = 0; else return clib_error_return (0, "parse error: '%U'", - format_unformat_error, line_input); + format_unformat_error, line_input); unformat_free (line_input); - ipsec_set_interface_spd(vm, sw_if_index, spd_id, is_add); + ipsec_set_interface_spd (vm, sw_if_index, spd_id, is_add); return 0; } +/* *INDENT-OFF* */ VLIB_CLI_COMMAND (set_interface_spd_command, static) = { .path = "set interface ipsec spd", .short_help = "set interface ipsec spd <int> <id>", .function = set_interface_spd_command_fn, }; +/* *INDENT-ON* */ static clib_error_t * ipsec_sa_add_del_command_fn (vlib_main_t * vm, - unformat_input_t * input, - vlib_cli_command_t * cmd) + unformat_input_t * input, + vlib_cli_command_t * cmd) { - unformat_input_t _line_input, * line_input = &_line_input; + unformat_input_t _line_input, *line_input = &_line_input; ipsec_sa_t sa; int is_add = ~0; - u8 * ck = 0, * ik = 0; + u8 *ck = 0, *ik = 0; - memset(&sa, 0, sizeof(sa)); + memset (&sa, 0, sizeof (sa)); - if (! unformat_user (input, unformat_line_input, line_input)) + if (!unformat_user (input, unformat_line_input, line_input)) return 0; - while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT) { - if (unformat (line_input, "add %u", &sa.id)) - is_add = 1; - else if (unformat (line_input, "del %u", &sa.id)) - is_add = 0; - else if (unformat (line_input, "spi %u", &sa.spi)) - ; - else if (unformat (line_input, "esp")) - sa.protocol = IPSEC_PROTOCOL_ESP; - else if (unformat (line_input, "ah")) - //sa.protocol = IPSEC_PROTOCOL_AH; - return clib_error_return(0, "unsupported security protocol 'AH'"); - else if (unformat (line_input, "crypto-key %U", unformat_hex_string, &ck)) - sa.crypto_key_len = vec_len (ck); - else if (unformat (line_input, "crypto-alg %U", unformat_ipsec_crypto_alg, - &sa.crypto_alg)) - { - if (sa.crypto_alg < IPSEC_CRYPTO_ALG_AES_CBC_128 || - sa.crypto_alg > IPSEC_CRYPTO_ALG_AES_CBC_256) - return clib_error_return(0, "unsupported crypto-alg: '%U'", - format_ipsec_crypto_alg, sa.crypto_alg); - } - else if (unformat (line_input, "integ-key %U", unformat_hex_string, &ik)) - sa.integ_key_len = vec_len (ik); - else if (unformat (line_input, "integ-alg %U", unformat_ipsec_integ_alg, - &sa.integ_alg)) - { - if (sa.integ_alg < IPSEC_INTEG_ALG_SHA1_96 || - sa.integ_alg > IPSEC_INTEG_ALG_SHA_512_256) - return clib_error_return(0, "unsupported integ-alg: '%U'", - format_ipsec_integ_alg, sa.integ_alg); - } - else if (unformat (line_input, "tunnel-src %U", - unformat_ip4_address, &sa.tunnel_src_addr.ip4)) - sa.is_tunnel = 1; - else if (unformat (line_input, "tunnel-dst %U", - unformat_ip4_address, &sa.tunnel_dst_addr.ip4)) - sa.is_tunnel = 1; - else if (unformat (line_input, "tunnel-src %U", - unformat_ip6_address, &sa.tunnel_src_addr.ip6)) - { sa.is_tunnel = 1; sa.is_tunnel_ip6 = 1; } - else if (unformat (line_input, "tunnel-dst %U", - unformat_ip6_address, &sa.tunnel_dst_addr.ip6)) - { sa.is_tunnel = 1; sa.is_tunnel_ip6 = 1; } - else - return clib_error_return (0, "parse error: '%U'", - format_unformat_error, line_input); - } + while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT) + { + if (unformat (line_input, "add %u", &sa.id)) + is_add = 1; + else if (unformat (line_input, "del %u", &sa.id)) + is_add = 0; + else if (unformat (line_input, "spi %u", &sa.spi)) + ; + else if (unformat (line_input, "esp")) + sa.protocol = IPSEC_PROTOCOL_ESP; + else if (unformat (line_input, "ah")) + //sa.protocol = IPSEC_PROTOCOL_AH; + return clib_error_return (0, "unsupported security protocol 'AH'"); + else + if (unformat (line_input, "crypto-key %U", unformat_hex_string, &ck)) + sa.crypto_key_len = vec_len (ck); + else + if (unformat + (line_input, "crypto-alg %U", unformat_ipsec_crypto_alg, + &sa.crypto_alg)) + { + if (sa.crypto_alg < IPSEC_CRYPTO_ALG_AES_CBC_128 || + sa.crypto_alg > IPSEC_CRYPTO_ALG_AES_CBC_256) + return clib_error_return (0, "unsupported crypto-alg: '%U'", + format_ipsec_crypto_alg, sa.crypto_alg); + } + else + if (unformat (line_input, "integ-key %U", unformat_hex_string, &ik)) + sa.integ_key_len = vec_len (ik); + else if (unformat (line_input, "integ-alg %U", unformat_ipsec_integ_alg, + &sa.integ_alg)) + { + if (sa.integ_alg < IPSEC_INTEG_ALG_SHA1_96 || + sa.integ_alg > IPSEC_INTEG_ALG_SHA_512_256) + return clib_error_return (0, "unsupported integ-alg: '%U'", + format_ipsec_integ_alg, sa.integ_alg); + } + else if (unformat (line_input, "tunnel-src %U", + unformat_ip4_address, &sa.tunnel_src_addr.ip4)) + sa.is_tunnel = 1; + else if (unformat (line_input, "tunnel-dst %U", + unformat_ip4_address, &sa.tunnel_dst_addr.ip4)) + sa.is_tunnel = 1; + else if (unformat (line_input, "tunnel-src %U", + unformat_ip6_address, &sa.tunnel_src_addr.ip6)) + { + sa.is_tunnel = 1; + sa.is_tunnel_ip6 = 1; + } + else if (unformat (line_input, "tunnel-dst %U", + unformat_ip6_address, &sa.tunnel_dst_addr.ip6)) + { + sa.is_tunnel = 1; + sa.is_tunnel_ip6 = 1; + } + else + return clib_error_return (0, "parse error: '%U'", + format_unformat_error, line_input); + } unformat_free (line_input); - if (sa.crypto_key_len > sizeof(sa.crypto_key)) - sa.crypto_key_len = sizeof(sa.crypto_key); + if (sa.crypto_key_len > sizeof (sa.crypto_key)) + sa.crypto_key_len = sizeof (sa.crypto_key); - if (sa.integ_key_len > sizeof(sa.integ_key)) - sa.integ_key_len = sizeof(sa.integ_key); + if (sa.integ_key_len > sizeof (sa.integ_key)) + sa.integ_key_len = sizeof (sa.integ_key); if (ck) - strncpy((char *) sa.crypto_key, (char *) ck, sa.crypto_key_len); + strncpy ((char *) sa.crypto_key, (char *) ck, sa.crypto_key_len); if (ik) - strncpy((char *) sa.integ_key, (char *) ik, sa.integ_key_len); + strncpy ((char *) sa.integ_key, (char *) ik, sa.integ_key_len); - ipsec_add_del_sa(vm, &sa, is_add); + ipsec_add_del_sa (vm, &sa, is_add); return 0; } +/* *INDENT-OFF* */ VLIB_CLI_COMMAND (ipsec_sa_add_del_command, static) = { .path = "ipsec sa", .short_help = "ipsec sa [add|del]", .function = ipsec_sa_add_del_command_fn, }; +/* *INDENT-ON* */ static clib_error_t * ipsec_spd_add_del_command_fn (vlib_main_t * vm, - unformat_input_t * input, - vlib_cli_command_t * cmd) + unformat_input_t * input, + vlib_cli_command_t * cmd) { - unformat_input_t _line_input, * line_input = &_line_input; + unformat_input_t _line_input, *line_input = &_line_input; u32 spd_id; int is_add = ~0; - if (! unformat_user (input, unformat_line_input, line_input)) + if (!unformat_user (input, unformat_line_input, line_input)) return 0; - while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT) { - if (unformat (line_input, "add")) - is_add = 1; - else if (unformat (line_input, "del")) - is_add = 0; - else if (unformat (line_input, "%u", &spd_id)) - ; - else - return clib_error_return (0, "parse error: '%U'", - format_unformat_error, line_input); - } + while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT) + { + if (unformat (line_input, "add")) + is_add = 1; + else if (unformat (line_input, "del")) + is_add = 0; + else if (unformat (line_input, "%u", &spd_id)) + ; + else + return clib_error_return (0, "parse error: '%U'", + format_unformat_error, line_input); + } unformat_free (line_input); - ipsec_add_del_spd(vm, spd_id, is_add); + ipsec_add_del_spd (vm, spd_id, is_add); return 0; } +/* *INDENT-OFF* */ VLIB_CLI_COMMAND (ipsec_spd_add_del_command, static) = { .path = "ipsec spd", .short_help = "ipsec spd [add|del] <id>", .function = ipsec_spd_add_del_command_fn, }; +/* *INDENT-ON* */ static clib_error_t * ipsec_policy_add_del_command_fn (vlib_main_t * vm, - unformat_input_t * input, - vlib_cli_command_t * cmd) + unformat_input_t * input, + vlib_cli_command_t * cmd) { - unformat_input_t _line_input, * line_input = &_line_input; + unformat_input_t _line_input, *line_input = &_line_input; ipsec_policy_t p; int is_add = 0; int is_ip_any = 1; u32 tmp, tmp2; - memset(&p, 0, sizeof(p)); + memset (&p, 0, sizeof (p)); p.lport.stop = p.rport.stop = ~0; - p.laddr.stop.ip4.as_u32 = p.raddr.stop.ip4.as_u32 = (u32) ~0; - p.laddr.stop.ip6.as_u64[0] = p.laddr.stop.ip6.as_u64[1] = (u64) ~0; - p.raddr.stop.ip6.as_u64[0] = p.raddr.stop.ip6.as_u64[1] = (u64) ~0; + p.laddr.stop.ip4.as_u32 = p.raddr.stop.ip4.as_u32 = (u32) ~ 0; + p.laddr.stop.ip6.as_u64[0] = p.laddr.stop.ip6.as_u64[1] = (u64) ~ 0; + p.raddr.stop.ip6.as_u64[0] = p.raddr.stop.ip6.as_u64[1] = (u64) ~ 0; - if (! unformat_user (input, unformat_line_input, line_input)) + if (!unformat_user (input, unformat_line_input, line_input)) return 0; - while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT) { - if (unformat (line_input, "add")) - is_add = 1; - else if (unformat (line_input, "del")) - is_add = 0; - else if (unformat (line_input, "spd %u", &p.id)) - ; - else if (unformat (line_input, "inbound")) - p.is_outbound = 0; - else if (unformat (line_input, "outbound")) - p.is_outbound = 1; - else if (unformat (line_input, "priority %d", &p.priority)) - ; - else if (unformat (line_input, "protocol %u", &tmp)) - p.protocol = (u8) tmp; - else if (unformat (line_input, "action %U", unformat_ipsec_policy_action, - &p.policy)) - { - if (p.policy == IPSEC_POLICY_ACTION_RESOLVE) - return clib_error_return(0, "unsupported action: 'resolve'"); - } - else if (unformat (line_input, "sa %u", &p.sa_id)) - ; - else if (unformat (line_input, "local-ip-range %U - %U", - unformat_ip4_address, &p.laddr.start.ip4, - unformat_ip4_address, &p.laddr.stop.ip4)) - is_ip_any = 0; - else if (unformat (line_input, "remote-ip-range %U - %U", - unformat_ip4_address, &p.raddr.start.ip4, - unformat_ip4_address, &p.raddr.stop.ip4)) - is_ip_any = 0; - else if (unformat (line_input, "local-ip-range %U - %U", - unformat_ip6_address, &p.laddr.start.ip6, - unformat_ip6_address, &p.laddr.stop.ip6)) - { - p.is_ipv6 = 1; - is_ip_any = 0; - } - else if (unformat (line_input, "remote-ip-range %U - %U", - unformat_ip6_address, &p.raddr.start.ip6, - unformat_ip6_address, &p.raddr.stop.ip6)) - { - p.is_ipv6 = 1; - is_ip_any = 0; - } - else if (unformat (line_input, "local-port-range %u - %u", &tmp, &tmp2)) - { p.lport.start = tmp; p.lport.stop = tmp2; } - else if (unformat (line_input, "remote-port-range %u - %u", &tmp, &tmp2)) - { p.rport.start = tmp; p.rport.stop = tmp2; } - else - return clib_error_return (0, "parse error: '%U'", - format_unformat_error, line_input); - } + while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT) + { + if (unformat (line_input, "add")) + is_add = 1; + else if (unformat (line_input, "del")) + is_add = 0; + else if (unformat (line_input, "spd %u", &p.id)) + ; + else if (unformat (line_input, "inbound")) + p.is_outbound = 0; + else if (unformat (line_input, "outbound")) + p.is_outbound = 1; + else if (unformat (line_input, "priority %d", &p.priority)) + ; + else if (unformat (line_input, "protocol %u", &tmp)) + p.protocol = (u8) tmp; + else + if (unformat + (line_input, "action %U", unformat_ipsec_policy_action, + &p.policy)) + { + if (p.policy == IPSEC_POLICY_ACTION_RESOLVE) + return clib_error_return (0, "unsupported action: 'resolve'"); + } + else if (unformat (line_input, "sa %u", &p.sa_id)) + ; + else if (unformat (line_input, "local-ip-range %U - %U", + unformat_ip4_address, &p.laddr.start.ip4, + unformat_ip4_address, &p.laddr.stop.ip4)) + is_ip_any = 0; + else if (unformat (line_input, "remote-ip-range %U - %U", + unformat_ip4_address, &p.raddr.start.ip4, + unformat_ip4_address, &p.raddr.stop.ip4)) + is_ip_any = 0; + else if (unformat (line_input, "local-ip-range %U - %U", + unformat_ip6_address, &p.laddr.start.ip6, + unformat_ip6_address, &p.laddr.stop.ip6)) + { + p.is_ipv6 = 1; + is_ip_any = 0; + } + else if (unformat (line_input, "remote-ip-range %U - %U", + unformat_ip6_address, &p.raddr.start.ip6, + unformat_ip6_address, &p.raddr.stop.ip6)) + { + p.is_ipv6 = 1; + is_ip_any = 0; + } + else if (unformat (line_input, "local-port-range %u - %u", &tmp, &tmp2)) + { + p.lport.start = tmp; + p.lport.stop = tmp2; + } + else + if (unformat (line_input, "remote-port-range %u - %u", &tmp, &tmp2)) + { + p.rport.start = tmp; + p.rport.stop = tmp2; + } + else + return clib_error_return (0, "parse error: '%U'", + format_unformat_error, line_input); + } unformat_free (line_input); - ipsec_add_del_policy(vm, &p, is_add); + ipsec_add_del_policy (vm, &p, is_add); if (is_ip_any) { p.is_ipv6 = 1; - ipsec_add_del_policy(vm, &p, is_add); + ipsec_add_del_policy (vm, &p, is_add); } return 0; } +/* *INDENT-OFF* */ VLIB_CLI_COMMAND (ipsec_policy_add_del_command, static) = { .path = "ipsec policy", .short_help = "ipsec policy [add|del] spd <id> priority <n> ", .function = ipsec_policy_add_del_command_fn, }; +/* *INDENT-ON* */ static clib_error_t * set_ipsec_sa_key_command_fn (vlib_main_t * vm, - unformat_input_t * input, - vlib_cli_command_t * cmd) + unformat_input_t * input, + vlib_cli_command_t * cmd) { - unformat_input_t _line_input, * line_input = &_line_input; + unformat_input_t _line_input, *line_input = &_line_input; ipsec_sa_t sa; - u8 * ck = 0, * ik = 0; + u8 *ck = 0, *ik = 0; - memset(&sa, 0, sizeof(sa)); + memset (&sa, 0, sizeof (sa)); - if (! unformat_user (input, unformat_line_input, line_input)) + if (!unformat_user (input, unformat_line_input, line_input)) return 0; - while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT) { - if (unformat (line_input, "%u", &sa.id)) - ; - else if (unformat (line_input, "crypto-key %U", unformat_hex_string, &ck)) - sa.crypto_key_len = vec_len (ck); - else if (unformat (line_input, "integ-key %U", unformat_hex_string, &ik)) - sa.integ_key_len = vec_len (ik); - else - return clib_error_return (0, "parse error: '%U'", format_unformat_error, - line_input); - } + while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT) + { + if (unformat (line_input, "%u", &sa.id)) + ; + else + if (unformat (line_input, "crypto-key %U", unformat_hex_string, &ck)) + sa.crypto_key_len = vec_len (ck); + else + if (unformat (line_input, "integ-key %U", unformat_hex_string, &ik)) + sa.integ_key_len = vec_len (ik); + else + return clib_error_return (0, "parse error: '%U'", + format_unformat_error, line_input); + } unformat_free (line_input); - if (sa.crypto_key_len > sizeof(sa.crypto_key)) - sa.crypto_key_len = sizeof(sa.crypto_key); + if (sa.crypto_key_len > sizeof (sa.crypto_key)) + sa.crypto_key_len = sizeof (sa.crypto_key); - if (sa.integ_key_len > sizeof(sa.integ_key)) - sa.integ_key_len = sizeof(sa.integ_key); + if (sa.integ_key_len > sizeof (sa.integ_key)) + sa.integ_key_len = sizeof (sa.integ_key); if (ck) - strncpy((char *) sa.crypto_key, (char *) ck, sa.crypto_key_len); + strncpy ((char *) sa.crypto_key, (char *) ck, sa.crypto_key_len); if (ik) - strncpy((char *) sa.integ_key, (char *) ik, sa.integ_key_len); + strncpy ((char *) sa.integ_key, (char *) ik, sa.integ_key_len); - ipsec_set_sa_key(vm, &sa); + ipsec_set_sa_key (vm, &sa); return 0; } +/* *INDENT-OFF* */ VLIB_CLI_COMMAND (set_ipsec_sa_key_command, static) = { .path = "set ipsec sa", .short_help = "set ipsec sa <id> crypto-key <key> integ-key <key>", .function = set_ipsec_sa_key_command_fn, }; +/* *INDENT-ON* */ static clib_error_t * show_ipsec_command_fn (vlib_main_t * vm, - unformat_input_t * input, - vlib_cli_command_t * cmd) + unformat_input_t * input, vlib_cli_command_t * cmd) { - ipsec_spd_t * spd; - ipsec_sa_t * sa; - ipsec_policy_t * p; - ipsec_main_t * im = &ipsec_main; - u32 * i; - ipsec_tunnel_if_t * t; - vnet_hw_interface_t * hi; + ipsec_spd_t *spd; + ipsec_sa_t *sa; + ipsec_policy_t *p; + ipsec_main_t *im = &ipsec_main; + u32 *i; + ipsec_tunnel_if_t *t; + vnet_hw_interface_t *hi; + /* *INDENT-OFF* */ pool_foreach (sa, im->sad, ({ if (sa->id) { vlib_cli_output(vm, "sa %u spi %u mode %s protocol %s", sa->id, sa->spi, @@ -370,7 +406,9 @@ show_ipsec_command_fn (vlib_main_t * vm, } } })); + /* *INDENT-ON* */ + /* *INDENT-OFF* */ pool_foreach (spd, im->spds, ({ vlib_cli_output(vm, "spd %u", spd->id); @@ -515,8 +553,10 @@ show_ipsec_command_fn (vlib_main_t * vm, p->counter.bytes); }; })); + /* *INDENT-ON* */ - vlib_cli_output(vm, "tunnel interfaces"); + vlib_cli_output (vm, "tunnel interfaces"); + /* *INDENT-OFF* */ pool_foreach (t, im->tunnel_interfaces, ({ hi = vnet_get_hw_interface (im->vnet_main, t->hw_if_index); vlib_cli_output(vm, " %s seq", hi->name); @@ -545,158 +585,183 @@ show_ipsec_command_fn (vlib_main_t * vm, format_ipsec_integ_alg, sa->integ_alg, format_hex_bytes, sa->integ_key, sa->integ_key_len); })); + /* *INDENT-ON* */ return 0; } +/* *INDENT-OFF* */ VLIB_CLI_COMMAND (show_ipsec_command, static) = { .path = "show ipsec", .short_help = "show ipsec", .function = show_ipsec_command_fn, }; +/* *INDENT-ON* */ static clib_error_t * clear_ipsec_counters_command_fn (vlib_main_t * vm, - unformat_input_t * input, - vlib_cli_command_t * cmd) + unformat_input_t * input, + vlib_cli_command_t * cmd) { - ipsec_main_t * im = &ipsec_main; - ipsec_spd_t * spd; - ipsec_policy_t * p; + ipsec_main_t *im = &ipsec_main; + ipsec_spd_t *spd; + ipsec_policy_t *p; + /* *INDENT-OFF* */ pool_foreach (spd, im->spds, ({ pool_foreach(p, spd->policies, ({ p->counter.packets = p->counter.bytes = 0; })); })); + /* *INDENT-ON* */ return 0; } +/* *INDENT-OFF* */ VLIB_CLI_COMMAND (clear_ipsec_counters_command, static) = { .path = "clear ipsec counters", .short_help = "clear ipsec counters", .function = clear_ipsec_counters_command_fn, }; +/* *INDENT-ON* */ static clib_error_t * create_ipsec_tunnel_command_fn (vlib_main_t * vm, - unformat_input_t * input, - vlib_cli_command_t * cmd) + unformat_input_t * input, + vlib_cli_command_t * cmd) { - unformat_input_t _line_input, * line_input = &_line_input; + unformat_input_t _line_input, *line_input = &_line_input; ipsec_add_del_tunnel_args_t a; int rv; u32 num_m_args = 0; - memset(&a, 0, sizeof(a)); + memset (&a, 0, sizeof (a)); a.is_add = 1; /* Get a line of input. */ - if (! unformat_user (input, unformat_line_input, line_input)) + if (!unformat_user (input, unformat_line_input, line_input)) return 0; - while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT) { - if (unformat (line_input, "local-ip %U", unformat_ip4_address, &a.local_ip)) - num_m_args++; - else if (unformat (line_input, "remote-ip %U", unformat_ip4_address, &a.remote_ip)) - num_m_args++; - else if (unformat (line_input, "local-spi %u", &a.local_spi)) - num_m_args++; - else if (unformat (line_input, "remote-spi %u", &a.remote_spi)) - num_m_args++; - else if (unformat (line_input, "del")) - a.is_add = 0; - else - return clib_error_return (0, "unknown input `%U'", - format_unformat_error, input); - } + while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT) + { + if (unformat + (line_input, "local-ip %U", unformat_ip4_address, &a.local_ip)) + num_m_args++; + else + if (unformat + (line_input, "remote-ip %U", unformat_ip4_address, &a.remote_ip)) + num_m_args++; + else if (unformat (line_input, "local-spi %u", &a.local_spi)) + num_m_args++; + else if (unformat (line_input, "remote-spi %u", &a.remote_spi)) + num_m_args++; + else if (unformat (line_input, "del")) + a.is_add = 0; + else + return clib_error_return (0, "unknown input `%U'", + format_unformat_error, input); + } unformat_free (line_input); if (num_m_args < 4) - return clib_error_return (0, "mandatory argument(s) missing"); + return clib_error_return (0, "mandatory argument(s) missing"); rv = ipsec_add_del_tunnel_if (&a); - switch(rv) + switch (rv) { case 0: break; case VNET_API_ERROR_INVALID_VALUE: if (a.is_add) - return clib_error_return (0, "IPSec tunnel interface already exists..."); + return clib_error_return (0, + "IPSec tunnel interface already exists..."); else - return clib_error_return (0, "IPSec tunnel interface not exists..."); + return clib_error_return (0, "IPSec tunnel interface not exists..."); default: - return clib_error_return (0, "ipsec_register_interface returned %d", rv); + return clib_error_return (0, "ipsec_register_interface returned %d", + rv); } return 0; } +/* *INDENT-OFF* */ VLIB_CLI_COMMAND (create_ipsec_tunnel_command, static) = { .path = "create ipsec tunnel", .short_help = "create ipsec tunnel local-ip <addr> local-spi <spi> remote-ip <addr> remote-spi <spi>", .function = create_ipsec_tunnel_command_fn, }; +/* *INDENT-ON* */ static clib_error_t * set_interface_key_command_fn (vlib_main_t * vm, - unformat_input_t * input, - vlib_cli_command_t * cmd) + unformat_input_t * input, + vlib_cli_command_t * cmd) { - unformat_input_t _line_input, * line_input = &_line_input; + unformat_input_t _line_input, *line_input = &_line_input; ipsec_main_t *im = &ipsec_main; ipsec_if_set_key_type_t type = IPSEC_IF_SET_KEY_TYPE_NONE; - u32 hw_if_index = (u32) ~0; + u32 hw_if_index = (u32) ~ 0; u32 alg; - u8 * key = 0; + u8 *key = 0; - if (! unformat_user (input, unformat_line_input, line_input)) + if (!unformat_user (input, unformat_line_input, line_input)) return 0; while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT) { if (unformat (line_input, "%U", - unformat_vnet_hw_interface, im->vnet_main, &hw_if_index)) - ; - else if (unformat (line_input, "local crypto %U", unformat_ipsec_crypto_alg, &alg)) - type = IPSEC_IF_SET_KEY_TYPE_LOCAL_CRYPTO; - else if (unformat (line_input, "remote crypto %U", unformat_ipsec_crypto_alg, &alg)) - type = IPSEC_IF_SET_KEY_TYPE_REMOTE_CRYPTO; - else if (unformat (line_input, "local integ %U", unformat_ipsec_integ_alg, &alg)) - type = IPSEC_IF_SET_KEY_TYPE_LOCAL_INTEG; - else if (unformat (line_input, "remote integ %U", unformat_ipsec_integ_alg, &alg)) - type = IPSEC_IF_SET_KEY_TYPE_REMOTE_INTEG; + unformat_vnet_hw_interface, im->vnet_main, &hw_if_index)) + ; + else + if (unformat + (line_input, "local crypto %U", unformat_ipsec_crypto_alg, &alg)) + type = IPSEC_IF_SET_KEY_TYPE_LOCAL_CRYPTO; + else + if (unformat + (line_input, "remote crypto %U", unformat_ipsec_crypto_alg, &alg)) + type = IPSEC_IF_SET_KEY_TYPE_REMOTE_CRYPTO; + else + if (unformat + (line_input, "local integ %U", unformat_ipsec_integ_alg, &alg)) + type = IPSEC_IF_SET_KEY_TYPE_LOCAL_INTEG; + else + if (unformat + (line_input, "remote integ %U", unformat_ipsec_integ_alg, &alg)) + type = IPSEC_IF_SET_KEY_TYPE_REMOTE_INTEG; else if (unformat (line_input, "%U", unformat_hex_string, &key)) - ; + ; else - return clib_error_return (0, "parse error: '%U'", - format_unformat_error, line_input); + return clib_error_return (0, "parse error: '%U'", + format_unformat_error, line_input); } unformat_free (line_input); if (type == IPSEC_IF_SET_KEY_TYPE_NONE) - return clib_error_return (0, "unknown key type"); + return clib_error_return (0, "unknown key type"); - if (alg > 0 && vec_len(key)==0) - return clib_error_return (0, "key is not specified"); + if (alg > 0 && vec_len (key) == 0) + return clib_error_return (0, "key is not specified"); - if (hw_if_index == (u32) ~0) - return clib_error_return (0, "interface not specified"); + if (hw_if_index == (u32) ~ 0) + return clib_error_return (0, "interface not specified"); - ipsec_set_interface_key(im->vnet_main, hw_if_index, type, alg, key); - vec_free(key); + ipsec_set_interface_key (im->vnet_main, hw_if_index, type, alg, key); + vec_free (key); return 0; } +/* *INDENT-OFF* */ VLIB_CLI_COMMAND (set_interface_key_command, static) = { .path = "set interface ipsec key", .short_help = "set interface ipsec key <int> <local|remote> <crypto|integ> <key type> <key>", .function = set_interface_key_command_fn, }; +/* *INDENT-ON* */ clib_error_t * @@ -707,3 +772,11 @@ ipsec_cli_init (vlib_main_t * vm) VLIB_INIT_FUNCTION (ipsec_cli_init); + +/* + * fd.io coding-style-patch-verification: ON + * + * Local Variables: + * eval: (c-set-style "gnu") + * End: + */ diff --git a/vnet/vnet/ipsec/ipsec_format.c b/vnet/vnet/ipsec/ipsec_format.c index f3720abf6c3..38aed79a155 100644 --- a/vnet/vnet/ipsec/ipsec_format.c +++ b/vnet/vnet/ipsec/ipsec_format.c @@ -26,15 +26,15 @@ u8 * format_ipsec_policy_action (u8 * s, va_list * args) { u32 i = va_arg (*args, u32); - char * t = 0; + char *t = 0; switch (i) { #define _(v,f,str) case IPSEC_POLICY_ACTION_##f: t = str; break; - foreach_ipsec_policy_action + foreach_ipsec_policy_action #undef _ - default: - s = format (s, "unknown"); + default: + s = format (s, "unknown"); } s = format (s, "%s", t); return s; @@ -43,13 +43,13 @@ format_ipsec_policy_action (u8 * s, va_list * args) uword unformat_ipsec_policy_action (unformat_input_t * input, va_list * args) { - u32 * r = va_arg (*args, u32 *); + u32 *r = va_arg (*args, u32 *); - if (0) ; + if (0); #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_POLICY_ACTION_##f; foreach_ipsec_policy_action #undef _ - else + else return 0; return 1; } @@ -58,15 +58,15 @@ u8 * format_ipsec_crypto_alg (u8 * s, va_list * args) { u32 i = va_arg (*args, u32); - u8 * t = 0; + u8 *t = 0; switch (i) { #define _(v,f,str) case IPSEC_CRYPTO_ALG_##f: t = (u8 *) str; break; - foreach_ipsec_crypto_alg + foreach_ipsec_crypto_alg #undef _ - default: - s = format (s, "unknown"); + default: + s = format (s, "unknown"); } s = format (s, "%s", t); return s; @@ -75,13 +75,13 @@ format_ipsec_crypto_alg (u8 * s, va_list * args) uword unformat_ipsec_crypto_alg (unformat_input_t * input, va_list * args) { - u32 * r = va_arg (*args, u32 *); + u32 *r = va_arg (*args, u32 *); - if (0) ; + if (0); #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_CRYPTO_ALG_##f; foreach_ipsec_crypto_alg #undef _ - else + else return 0; return 1; } @@ -90,15 +90,15 @@ u8 * format_ipsec_integ_alg (u8 * s, va_list * args) { u32 i = va_arg (*args, u32); - u8 * t = 0; + u8 *t = 0; switch (i) { #define _(v,f,str) case IPSEC_INTEG_ALG_##f: t = (u8 *) str; break; - foreach_ipsec_integ_alg + foreach_ipsec_integ_alg #undef _ - default: - s = format (s, "unknown"); + default: + s = format (s, "unknown"); } s = format (s, "%s", t); return s; @@ -107,27 +107,35 @@ format_ipsec_integ_alg (u8 * s, va_list * args) uword unformat_ipsec_integ_alg (unformat_input_t * input, va_list * args) { - u32 * r = va_arg (*args, u32 *); + u32 *r = va_arg (*args, u32 *); - if (0) ; + if (0); #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_INTEG_ALG_##f; foreach_ipsec_integ_alg #undef _ - else + else return 0; return 1; } u8 * -format_ipsec_replay_window(u8 * s, va_list * args) +format_ipsec_replay_window (u8 * s, va_list * args) { u64 w = va_arg (*args, u64); u8 i; for (i = 0; i < 64; i++) { - s = format (s, "%u", w & (1ULL<<i) ? 1 : 0); + s = format (s, "%u", w & (1ULL << i) ? 1 : 0); } return s; } + +/* + * fd.io coding-style-patch-verification: ON + * + * Local Variables: + * eval: (c-set-style "gnu") + * End: + */ diff --git a/vnet/vnet/ipsec/ipsec_if.c b/vnet/vnet/ipsec/ipsec_if.c index 7a85fb16781..475b7bda2bc 100644 --- a/vnet/vnet/ipsec/ipsec_if.c +++ b/vnet/vnet/ipsec/ipsec_if.c @@ -23,62 +23,62 @@ void vl_api_rpc_call_main_thread (void *fp, u8 * data, u32 data_length); -static u8 * format_ipsec_name (u8 * s, va_list * args) +static u8 * +format_ipsec_name (u8 * s, va_list * args) { u32 dev_instance = va_arg (*args, u32); return format (s, "ipsec%d", dev_instance); } -static uword dummy_interface_tx (vlib_main_t * vm, - vlib_node_runtime_t * node, - vlib_frame_t * frame) +static uword +dummy_interface_tx (vlib_main_t * vm, + vlib_node_runtime_t * node, vlib_frame_t * frame) { clib_warning ("you shouldn't be here, leaking buffers..."); return frame->n_vectors; } -VNET_DEVICE_CLASS (ipsec_device_class,static) = { - .name = "IPSec", - .format_device_name = format_ipsec_name, - .format_tx_trace = format_ipsec_if_output_trace, - .tx_function = dummy_interface_tx, -}; +VNET_DEVICE_CLASS (ipsec_device_class, static) = +{ +.name = "IPSec",.format_device_name = format_ipsec_name,.format_tx_trace = + format_ipsec_if_output_trace,.tx_function = dummy_interface_tx,}; -VNET_HW_INTERFACE_CLASS (ipsec_hw_class) = { - .name = "IPSec", -}; +VNET_HW_INTERFACE_CLASS (ipsec_hw_class) = +{ +.name = "IPSec",}; static int ipsec_add_del_tunnel_if_internal (vnet_main_t * vnm, - ipsec_add_del_tunnel_args_t * args); + ipsec_add_del_tunnel_args_t * args); static int -ipsec_add_del_tunnel_if_rpc_callback (ipsec_add_del_tunnel_args_t *a) +ipsec_add_del_tunnel_if_rpc_callback (ipsec_add_del_tunnel_args_t * a) { - vnet_main_t * vnm = vnet_get_main(); - ASSERT(os_get_cpu_number() == 0); + vnet_main_t *vnm = vnet_get_main (); + ASSERT (os_get_cpu_number () == 0); - return ipsec_add_del_tunnel_if_internal(vnm, a); + return ipsec_add_del_tunnel_if_internal (vnm, a); } int ipsec_add_del_tunnel_if (ipsec_add_del_tunnel_args_t * args) { vl_api_rpc_call_main_thread (ipsec_add_del_tunnel_if_rpc_callback, - (u8 *) args, sizeof(*args)); + (u8 *) args, sizeof (*args)); return 0; } int -ipsec_add_del_tunnel_if_internal (vnet_main_t * vnm, ipsec_add_del_tunnel_args_t * args) +ipsec_add_del_tunnel_if_internal (vnet_main_t * vnm, + ipsec_add_del_tunnel_args_t * args) { - ipsec_tunnel_if_t * t; - ipsec_main_t * im = &ipsec_main; - vnet_hw_interface_t * hi; + ipsec_tunnel_if_t *t; + ipsec_main_t *im = &ipsec_main; + vnet_hw_interface_t *hi; u32 hw_if_index = ~0; uword *p; - ipsec_sa_t * sa; + ipsec_sa_t *sa; u64 key = (u64) args->remote_ip.as_u32 << 32 | (u64) args->remote_spi; p = hash_get (im->ipsec_if_pool_index_by_key, key); @@ -87,7 +87,7 @@ ipsec_add_del_tunnel_if_internal (vnet_main_t * vnm, ipsec_add_del_tunnel_args_t { /* check if same src/dst pair exists */ if (p) - return VNET_API_ERROR_INVALID_VALUE; + return VNET_API_ERROR_INVALID_VALUE; pool_get_aligned (im->tunnel_interfaces, t, CLIB_CACHE_LINE_BYTES); memset (t, 0, sizeof (*t)); @@ -102,17 +102,19 @@ ipsec_add_del_tunnel_if_internal (vnet_main_t * vnm, ipsec_add_del_tunnel_args_t sa->use_esn = args->esn; sa->use_anti_replay = args->anti_replay; sa->integ_alg = args->integ_alg; - if (args->remote_integ_key_len <= sizeof(args->remote_integ_key)) - { - sa->integ_key_len = args->remote_integ_key_len; - clib_memcpy(sa->integ_key, args->remote_integ_key, args->remote_integ_key_len); - } + if (args->remote_integ_key_len <= sizeof (args->remote_integ_key)) + { + sa->integ_key_len = args->remote_integ_key_len; + clib_memcpy (sa->integ_key, args->remote_integ_key, + args->remote_integ_key_len); + } sa->crypto_alg = args->crypto_alg; - if (args->remote_crypto_key_len <= sizeof(args->remote_crypto_key)) - { - sa->crypto_key_len = args->remote_crypto_key_len; - clib_memcpy(sa->crypto_key, args->remote_crypto_key, args->remote_crypto_key_len); - } + if (args->remote_crypto_key_len <= sizeof (args->remote_crypto_key)) + { + sa->crypto_key_len = args->remote_crypto_key_len; + clib_memcpy (sa->crypto_key, args->remote_crypto_key, + args->remote_crypto_key_len); + } pool_get (im->sad, sa); memset (sa, 0, sizeof (*sa)); @@ -125,41 +127,47 @@ ipsec_add_del_tunnel_if_internal (vnet_main_t * vnm, ipsec_add_del_tunnel_args_t sa->use_esn = args->esn; sa->use_anti_replay = args->anti_replay; sa->integ_alg = args->integ_alg; - if (args->local_integ_key_len <= sizeof(args->local_integ_key)) - { - sa->integ_key_len = args->local_integ_key_len; - clib_memcpy(sa->integ_key, args->local_integ_key, args->local_integ_key_len); - } + if (args->local_integ_key_len <= sizeof (args->local_integ_key)) + { + sa->integ_key_len = args->local_integ_key_len; + clib_memcpy (sa->integ_key, args->local_integ_key, + args->local_integ_key_len); + } sa->crypto_alg = args->crypto_alg; - if (args->local_crypto_key_len <= sizeof(args->local_crypto_key)) - { - sa->crypto_key_len = args->local_crypto_key_len; - clib_memcpy(sa->crypto_key, args->local_crypto_key, args->local_crypto_key_len); - } + if (args->local_crypto_key_len <= sizeof (args->local_crypto_key)) + { + sa->crypto_key_len = args->local_crypto_key_len; + clib_memcpy (sa->crypto_key, args->local_crypto_key, + args->local_crypto_key_len); + } - hash_set (im->ipsec_if_pool_index_by_key, key, t - im->tunnel_interfaces); + hash_set (im->ipsec_if_pool_index_by_key, key, + t - im->tunnel_interfaces); if (vec_len (im->free_tunnel_if_indices) > 0) - { - hw_if_index = - im->free_tunnel_if_indices[vec_len(im->free_tunnel_if_indices)-1]; - _vec_len (im->free_tunnel_if_indices) -= 1; - } + { + hw_if_index = + im->free_tunnel_if_indices[vec_len (im->free_tunnel_if_indices) - + 1]; + _vec_len (im->free_tunnel_if_indices) -= 1; + } else - { - hw_if_index = vnet_register_interface(vnm, ipsec_device_class.index, - t - im->tunnel_interfaces, - ipsec_hw_class.index, - t - im->tunnel_interfaces); - - hi = vnet_get_hw_interface (vnm, hw_if_index); - hi->output_node_index = ipsec_if_output_node.index; - } + { + hw_if_index = + vnet_register_interface (vnm, ipsec_device_class.index, + t - im->tunnel_interfaces, + ipsec_hw_class.index, + t - im->tunnel_interfaces); + + hi = vnet_get_hw_interface (vnm, hw_if_index); + hi->output_node_index = ipsec_if_output_node.index; + } t->hw_if_index = hw_if_index; /*1st interface, register protocol */ - if (pool_elts(im->tunnel_interfaces) == 1) - ip4_register_protocol(IP_PROTOCOL_IPSEC_ESP, ipsec_if_input_node.index); + if (pool_elts (im->tunnel_interfaces) == 1) + ip4_register_protocol (IP_PROTOCOL_IPSEC_ESP, + ipsec_if_input_node.index); return hw_if_index; } @@ -167,17 +175,17 @@ ipsec_add_del_tunnel_if_internal (vnet_main_t * vnm, ipsec_add_del_tunnel_args_t { /* check if exists */ if (!p) - return VNET_API_ERROR_INVALID_VALUE; + return VNET_API_ERROR_INVALID_VALUE; - t = pool_elt_at_index(im->tunnel_interfaces, p[0]); + t = pool_elt_at_index (im->tunnel_interfaces, p[0]); hi = vnet_get_hw_interface (vnm, t->hw_if_index); - vnet_sw_interface_set_flags (vnm, hi->sw_if_index, 0); /* admin down */ + vnet_sw_interface_set_flags (vnm, hi->sw_if_index, 0); /* admin down */ vec_add1 (im->free_tunnel_if_indices, t->hw_if_index); /* delete input and output SA */ - sa = pool_elt_at_index(im->sad, t->input_sa_index); + sa = pool_elt_at_index (im->sad, t->input_sa_index); pool_put (im->sad, sa); - sa = pool_elt_at_index(im->sad, t->output_sa_index); + sa = pool_elt_at_index (im->sad, t->output_sa_index); pool_put (im->sad, sa); hash_unset (im->ipsec_if_pool_index_by_key, key); @@ -187,44 +195,44 @@ ipsec_add_del_tunnel_if_internal (vnet_main_t * vnm, ipsec_add_del_tunnel_args_t } int -ipsec_set_interface_key(vnet_main_t * vnm, u32 hw_if_index, - ipsec_if_set_key_type_t type, u8 alg, u8 * key) +ipsec_set_interface_key (vnet_main_t * vnm, u32 hw_if_index, + ipsec_if_set_key_type_t type, u8 alg, u8 * key) { - ipsec_main_t * im = &ipsec_main; - vnet_hw_interface_t * hi; - ipsec_tunnel_if_t * t; - ipsec_sa_t * sa; + ipsec_main_t *im = &ipsec_main; + vnet_hw_interface_t *hi; + ipsec_tunnel_if_t *t; + ipsec_sa_t *sa; hi = vnet_get_hw_interface (vnm, hw_if_index); t = pool_elt_at_index (im->tunnel_interfaces, hi->dev_instance); if (type == IPSEC_IF_SET_KEY_TYPE_LOCAL_CRYPTO) { - sa = pool_elt_at_index(im->sad, t->output_sa_index); + 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)); + sa->crypto_key_len = vec_len (key); + clib_memcpy (sa->crypto_key, key, vec_len (key)); } else if (type == IPSEC_IF_SET_KEY_TYPE_LOCAL_INTEG) { - sa = pool_elt_at_index(im->sad, t->output_sa_index); + sa = pool_elt_at_index (im->sad, t->output_sa_index); sa->integ_alg = alg; - sa->integ_key_len = vec_len(key); - clib_memcpy(sa->integ_key, key, vec_len(key)); + sa->integ_key_len = vec_len (key); + clib_memcpy (sa->integ_key, key, vec_len (key)); } else if (type == IPSEC_IF_SET_KEY_TYPE_REMOTE_CRYPTO) { - sa = pool_elt_at_index(im->sad, t->input_sa_index); + sa = pool_elt_at_index (im->sad, t->input_sa_index); sa->crypto_alg = alg; - sa->crypto_key_len = vec_len(key); - clib_memcpy(sa->crypto_key, key, vec_len(key)); + sa->crypto_key_len = vec_len (key); + clib_memcpy (sa->crypto_key, key, vec_len (key)); } else if (type == IPSEC_IF_SET_KEY_TYPE_REMOTE_INTEG) { - sa = pool_elt_at_index(im->sad, t->input_sa_index); + sa = pool_elt_at_index (im->sad, t->input_sa_index); sa->integ_alg = alg; - sa->integ_key_len = vec_len(key); - clib_memcpy(sa->integ_key, key, vec_len(key)); + sa->integ_key_len = vec_len (key); + clib_memcpy (sa->integ_key, key, vec_len (key)); } else return VNET_API_ERROR_INVALID_VALUE; @@ -236,7 +244,7 @@ ipsec_set_interface_key(vnet_main_t * vnm, u32 hw_if_index, clib_error_t * ipsec_tunnel_if_init (vlib_main_t * vm) { - ipsec_main_t * im = &ipsec_main; + ipsec_main_t *im = &ipsec_main; im->ipsec_if_pool_index_by_key = hash_create (0, sizeof (uword)); @@ -245,3 +253,11 @@ ipsec_tunnel_if_init (vlib_main_t * vm) VLIB_INIT_FUNCTION (ipsec_tunnel_if_init); + +/* + * fd.io coding-style-patch-verification: ON + * + * Local Variables: + * eval: (c-set-style "gnu") + * End: + */ diff --git a/vnet/vnet/ipsec/ipsec_if_in.c b/vnet/vnet/ipsec/ipsec_if_in.c index 5a8a685807b..e5574421cfa 100644 --- a/vnet/vnet/ipsec/ipsec_if_in.c +++ b/vnet/vnet/ipsec/ipsec_if_in.c @@ -26,37 +26,40 @@ #define foreach_ipsec_if_input_error \ _(RX, "good packets received") -static char * ipsec_if_input_error_strings[] = { +static char *ipsec_if_input_error_strings[] = { #define _(sym,string) string, foreach_ipsec_if_input_error #undef _ }; -typedef enum { +typedef enum +{ #define _(sym,str) IPSEC_IF_INPUT_ERROR_##sym, - foreach_ipsec_if_input_error + foreach_ipsec_if_input_error #undef _ IPSEC_IF_INPUT_N_ERROR, } ipsec_if_input_error_t; -typedef enum { - IPSEC_IF_INPUT_NEXT_ESP_DECRYPT, - IPSEC_IF_INPUT_NEXT_DROP, - IPSEC_IF_INPUT_N_NEXT, +typedef enum +{ + IPSEC_IF_INPUT_NEXT_ESP_DECRYPT, + IPSEC_IF_INPUT_NEXT_DROP, + IPSEC_IF_INPUT_N_NEXT, } ipsec_if_input_next_t; -typedef struct { +typedef struct +{ u32 spi; u32 seq; } ipsec_if_input_trace_t; -u8 * format_ipsec_if_input_trace (u8 * s, va_list * args) +u8 * +format_ipsec_if_input_trace (u8 * s, va_list * args) { CLIB_UNUSED (vlib_main_t * vm) = va_arg (*args, vlib_main_t *); CLIB_UNUSED (vlib_node_t * node) = va_arg (*args, vlib_node_t *); - ipsec_if_input_trace_t * t - = va_arg (*args, ipsec_if_input_trace_t *); + ipsec_if_input_trace_t *t = va_arg (*args, ipsec_if_input_trace_t *); s = format (s, "IPSec: spi %u seq %u", t->spi, t->seq); return s; @@ -64,10 +67,10 @@ u8 * format_ipsec_if_input_trace (u8 * s, va_list * args) static uword ipsec_if_input_node_fn (vlib_main_t * vm, vlib_node_runtime_t * node, - vlib_frame_t * from_frame) + vlib_frame_t * from_frame) { ipsec_main_t *im = &ipsec_main; - u32 * from, * to_next = 0, next_index; + u32 *from, *to_next = 0, next_index; u32 n_left_from; from = vlib_frame_vector_args (from_frame); @@ -81,57 +84,61 @@ ipsec_if_input_node_fn (vlib_main_t * vm, vlib_node_runtime_t * node, vlib_get_next_frame (vm, node, next_index, to_next, n_left_to_next); while (n_left_from > 0 && n_left_to_next > 0) - { - u32 bi0, next0; - vlib_buffer_t * b0; - ip4_header_t *ip0; - esp_header_t *esp0; - uword * p; - - bi0 = to_next[0] = from[0]; - from += 1; - n_left_from -= 1; - to_next +=1; - n_left_to_next -= 1; - b0 = vlib_get_buffer (vm, bi0); - ip0 = vlib_buffer_get_current (b0); - esp0 = (esp_header_t *) ((u8 *) ip0 + ip4_header_bytes (ip0)); - - next0 = IPSEC_IF_INPUT_NEXT_DROP; - - u64 key = (u64) ip0->src_address.as_u32 << 32 | - (u64) clib_net_to_host_u32(esp0->spi); - - p = hash_get (im->ipsec_if_pool_index_by_key, key); - - if (p) - { - ipsec_tunnel_if_t * t; - t = pool_elt_at_index(im->tunnel_interfaces, p[0]); - vnet_buffer(b0)->output_features.ipsec_sad_index = t->input_sa_index; - vlib_buffer_advance(b0, ip4_header_bytes (ip0)); - next0 = IPSEC_IF_INPUT_NEXT_ESP_DECRYPT; - } - - if (PREDICT_FALSE(b0->flags & VLIB_BUFFER_IS_TRACED)) { - ipsec_if_input_trace_t *tr = vlib_add_trace (vm, node, b0, sizeof (*tr)); - tr->spi = clib_host_to_net_u32(esp0->spi); - tr->seq = clib_host_to_net_u32(esp0->seq); - } - - vlib_validate_buffer_enqueue_x1 (vm, node, next_index, to_next, - n_left_to_next, bi0, next0); - } + { + u32 bi0, next0; + vlib_buffer_t *b0; + ip4_header_t *ip0; + esp_header_t *esp0; + uword *p; + + bi0 = to_next[0] = from[0]; + from += 1; + n_left_from -= 1; + to_next += 1; + n_left_to_next -= 1; + b0 = vlib_get_buffer (vm, bi0); + ip0 = vlib_buffer_get_current (b0); + esp0 = (esp_header_t *) ((u8 *) ip0 + ip4_header_bytes (ip0)); + + next0 = IPSEC_IF_INPUT_NEXT_DROP; + + u64 key = (u64) ip0->src_address.as_u32 << 32 | + (u64) clib_net_to_host_u32 (esp0->spi); + + p = hash_get (im->ipsec_if_pool_index_by_key, key); + + if (p) + { + ipsec_tunnel_if_t *t; + t = pool_elt_at_index (im->tunnel_interfaces, p[0]); + vnet_buffer (b0)->output_features.ipsec_sad_index = + t->input_sa_index; + vlib_buffer_advance (b0, ip4_header_bytes (ip0)); + next0 = IPSEC_IF_INPUT_NEXT_ESP_DECRYPT; + } + + if (PREDICT_FALSE (b0->flags & VLIB_BUFFER_IS_TRACED)) + { + ipsec_if_input_trace_t *tr = + vlib_add_trace (vm, node, b0, sizeof (*tr)); + tr->spi = clib_host_to_net_u32 (esp0->spi); + tr->seq = clib_host_to_net_u32 (esp0->seq); + } + + vlib_validate_buffer_enqueue_x1 (vm, node, next_index, to_next, + n_left_to_next, bi0, next0); + } vlib_put_next_frame (vm, node, next_index, n_left_to_next); } vlib_node_increment_counter (vm, ipsec_if_input_node.index, - IPSEC_IF_INPUT_ERROR_RX, - from_frame->n_vectors); + IPSEC_IF_INPUT_ERROR_RX, + from_frame->n_vectors); return from_frame->n_vectors; } +/* *INDENT-OFF* */ VLIB_REGISTER_NODE (ipsec_if_input_node) = { .function = ipsec_if_input_node_fn, .name = "ipsec-if-input", @@ -149,6 +156,13 @@ VLIB_REGISTER_NODE (ipsec_if_input_node) = { [IPSEC_IF_INPUT_NEXT_DROP] = "error-drop", }, }; +/* *INDENT-ON* */ VLIB_NODE_FUNCTION_MULTIARCH (ipsec_if_input_node, ipsec_if_input_node_fn) - +/* + * fd.io coding-style-patch-verification: ON + * + * Local Variables: + * eval: (c-set-style "gnu") + * End: + */ diff --git a/vnet/vnet/ipsec/ipsec_if_out.c b/vnet/vnet/ipsec/ipsec_if_out.c index 9573c4f6f8c..8b82795980d 100644 --- a/vnet/vnet/ipsec/ipsec_if_out.c +++ b/vnet/vnet/ipsec/ipsec_if_out.c @@ -26,37 +26,40 @@ #define foreach_ipsec_if_output_error \ _(TX, "good packets transmitted") -static char * ipsec_if_output_error_strings[] = { +static char *ipsec_if_output_error_strings[] = { #define _(sym,string) string, foreach_ipsec_if_output_error #undef _ }; -typedef enum { +typedef enum +{ #define _(sym,str) IPSEC_IF_OUTPUT_ERROR_##sym, - foreach_ipsec_if_output_error + foreach_ipsec_if_output_error #undef _ IPSEC_IF_OUTPUT_N_ERROR, } ipsec_if_output_error_t; -typedef enum { - IPSEC_IF_OUTPUT_NEXT_ESP_ENCRYPT, - IPSEC_IF_OUTPUT_NEXT_DROP, - IPSEC_IF_OUTPUT_N_NEXT, +typedef enum +{ + IPSEC_IF_OUTPUT_NEXT_ESP_ENCRYPT, + IPSEC_IF_OUTPUT_NEXT_DROP, + IPSEC_IF_OUTPUT_N_NEXT, } ipsec_if_output_next_t; -typedef struct { +typedef struct +{ u32 spi; u32 seq; } ipsec_if_output_trace_t; -u8 * format_ipsec_if_output_trace (u8 * s, va_list * args) +u8 * +format_ipsec_if_output_trace (u8 * s, va_list * args) { CLIB_UNUSED (vlib_main_t * vm) = va_arg (*args, vlib_main_t *); CLIB_UNUSED (vlib_node_t * node) = va_arg (*args, vlib_node_t *); - ipsec_if_output_trace_t * t - = va_arg (*args, ipsec_if_output_trace_t *); + ipsec_if_output_trace_t *t = va_arg (*args, ipsec_if_output_trace_t *); s = format (s, "IPSec: spi %u seq %u", t->spi, t->seq); return s; @@ -64,11 +67,11 @@ u8 * format_ipsec_if_output_trace (u8 * s, va_list * args) static uword ipsec_if_output_node_fn (vlib_main_t * vm, vlib_node_runtime_t * node, - vlib_frame_t * from_frame) + vlib_frame_t * from_frame) { ipsec_main_t *im = &ipsec_main; - vnet_main_t * vnm = im->vnet_main; - u32 * from, * to_next = 0, next_index; + vnet_main_t *vnm = im->vnet_main; + u32 *from, *to_next = 0, next_index; u32 n_left_from, sw_if_index0; from = vlib_frame_vector_args (from_frame); @@ -82,44 +85,49 @@ ipsec_if_output_node_fn (vlib_main_t * vm, vlib_node_runtime_t * node, vlib_get_next_frame (vm, node, next_index, to_next, n_left_to_next); while (n_left_from > 0 && n_left_to_next > 0) - { - u32 bi0, next0; - vlib_buffer_t * b0; - ipsec_tunnel_if_t * t0; - vnet_hw_interface_t * hi0; - - bi0 = to_next[0] = from[0]; - from += 1; - n_left_from -= 1; - to_next +=1; - n_left_to_next -= 1; - b0 = vlib_get_buffer (vm, bi0); - sw_if_index0 = vnet_buffer(b0)->sw_if_index[VLIB_TX]; - hi0 = vnet_get_sup_hw_interface (vnm, sw_if_index0); - t0 = pool_elt_at_index (im->tunnel_interfaces, hi0->dev_instance); - vnet_buffer(b0)->output_features.ipsec_sad_index = t0->output_sa_index; - next0 = IPSEC_IF_OUTPUT_NEXT_ESP_ENCRYPT; - - if (PREDICT_FALSE(b0->flags & VLIB_BUFFER_IS_TRACED)) { - ipsec_if_output_trace_t *tr = vlib_add_trace (vm, node, b0, sizeof (*tr)); - ipsec_sa_t * sa0 = pool_elt_at_index(im->sad, t0->output_sa_index); - tr->spi = sa0->spi; - tr->seq = sa0->seq; - } - - vlib_validate_buffer_enqueue_x1 (vm, node, next_index, to_next, - n_left_to_next, bi0, next0); - } + { + u32 bi0, next0; + vlib_buffer_t *b0; + ipsec_tunnel_if_t *t0; + vnet_hw_interface_t *hi0; + + bi0 = to_next[0] = from[0]; + from += 1; + n_left_from -= 1; + to_next += 1; + n_left_to_next -= 1; + b0 = vlib_get_buffer (vm, bi0); + sw_if_index0 = vnet_buffer (b0)->sw_if_index[VLIB_TX]; + hi0 = vnet_get_sup_hw_interface (vnm, sw_if_index0); + t0 = pool_elt_at_index (im->tunnel_interfaces, hi0->dev_instance); + vnet_buffer (b0)->output_features.ipsec_sad_index = + t0->output_sa_index; + next0 = IPSEC_IF_OUTPUT_NEXT_ESP_ENCRYPT; + + if (PREDICT_FALSE (b0->flags & VLIB_BUFFER_IS_TRACED)) + { + ipsec_if_output_trace_t *tr = + vlib_add_trace (vm, node, b0, sizeof (*tr)); + ipsec_sa_t *sa0 = + pool_elt_at_index (im->sad, t0->output_sa_index); + tr->spi = sa0->spi; + tr->seq = sa0->seq; + } + + vlib_validate_buffer_enqueue_x1 (vm, node, next_index, to_next, + n_left_to_next, bi0, next0); + } vlib_put_next_frame (vm, node, next_index, n_left_to_next); } vlib_node_increment_counter (vm, ipsec_if_output_node.index, - IPSEC_IF_OUTPUT_ERROR_TX, - from_frame->n_vectors); + IPSEC_IF_OUTPUT_ERROR_TX, + from_frame->n_vectors); return from_frame->n_vectors; } +/* *INDENT-OFF* */ VLIB_REGISTER_NODE (ipsec_if_output_node) = { .function = ipsec_if_output_node_fn, .name = "ipsec-if-output", @@ -137,6 +145,13 @@ VLIB_REGISTER_NODE (ipsec_if_output_node) = { [IPSEC_IF_OUTPUT_NEXT_DROP] = "error-drop", }, }; +/* *INDENT-ON* */ VLIB_NODE_FUNCTION_MULTIARCH (ipsec_if_output_node, ipsec_if_output_node_fn) - +/* + * fd.io coding-style-patch-verification: ON + * + * Local Variables: + * eval: (c-set-style "gnu") + * End: + */ diff --git a/vnet/vnet/ipsec/ipsec_input.c b/vnet/vnet/ipsec/ipsec_input.c index e7011177a33..2bc4e2b4999 100644 --- a/vnet/vnet/ipsec/ipsec_input.c +++ b/vnet/vnet/ipsec/ipsec_input.c @@ -27,10 +27,11 @@ _(DROP, "error-drop") \ _(ESP_DECRYPT, "esp-decrypt") #define _(v, s) IPSEC_INPUT_NEXT_##v, -typedef enum { +typedef enum +{ foreach_ipsec_input_next #undef _ - IPSEC_INPUT_N_NEXT, + IPSEC_INPUT_N_NEXT, } ipsec_input_next_t; @@ -39,147 +40,152 @@ typedef enum { _(DECRYPTION_FAILED, "IPSEC decryption failed") -typedef enum { +typedef enum +{ #define _(sym,str) IPSEC_INPUT_ERROR_##sym, foreach_ipsec_input_error #undef _ - IPSEC_INPUT_N_ERROR, + IPSEC_INPUT_N_ERROR, } ipsec_input_error_t; -static char * ipsec_input_error_strings[] = { +static char *ipsec_input_error_strings[] = { #define _(sym,string) string, foreach_ipsec_input_error #undef _ }; -typedef struct { +typedef struct +{ u32 tunnel_index; u32 spi; u32 seq; } ipsec_input_trace_t; /* packet trace format function */ -static u8 * format_ipsec_input_trace (u8 * s, va_list * args) +static u8 * +format_ipsec_input_trace (u8 * s, va_list * args) { CLIB_UNUSED (vlib_main_t * vm) = va_arg (*args, vlib_main_t *); CLIB_UNUSED (vlib_node_t * node) = va_arg (*args, vlib_node_t *); - ipsec_input_trace_t * t = va_arg (*args, ipsec_input_trace_t *); + ipsec_input_trace_t *t = va_arg (*args, ipsec_input_trace_t *); if (t->tunnel_index != ~0) - { - s = format (s, "esp: tunnel %u spi %u seq %u", t->tunnel_index, t->spi, t->seq); - } + { + s = + format (s, "esp: tunnel %u spi %u seq %u", t->tunnel_index, t->spi, + t->seq); + } else - { - s = format (s, "esp: no tunnel spi %u seq %u",t->spi, t->seq); - } + { + s = format (s, "esp: no tunnel spi %u seq %u", t->spi, t->seq); + } return s; } always_inline ipsec_policy_t * -ipsec_input_protect_policy_match(ipsec_spd_t * spd, u32 sa, u32 da, u32 spi) +ipsec_input_protect_policy_match (ipsec_spd_t * spd, u32 sa, u32 da, u32 spi) { ipsec_main_t *im = &ipsec_main; - ipsec_policy_t * p; - ipsec_sa_t * s; - u32 * i; + ipsec_policy_t *p; + ipsec_sa_t *s; + u32 *i; - vec_foreach(i, spd->ipv4_inbound_protect_policy_indices) - { - p = pool_elt_at_index(spd->policies, *i); - s = pool_elt_at_index(im->sad, p->sa_index); + vec_foreach (i, spd->ipv4_inbound_protect_policy_indices) + { + p = pool_elt_at_index (spd->policies, *i); + s = pool_elt_at_index (im->sad, p->sa_index); - if (spi != s->spi) - continue; + if (spi != s->spi) + continue; - if (s->is_tunnel) - { - if (da != clib_net_to_host_u32(s->tunnel_dst_addr.ip4.as_u32)) - continue; + if (s->is_tunnel) + { + if (da != clib_net_to_host_u32 (s->tunnel_dst_addr.ip4.as_u32)) + continue; - if (sa != clib_net_to_host_u32(s->tunnel_src_addr.ip4.as_u32)) - continue; + if (sa != clib_net_to_host_u32 (s->tunnel_src_addr.ip4.as_u32)) + continue; - return p; - } + return p; + } - if (da < clib_net_to_host_u32(p->laddr.start.ip4.as_u32)) - continue; + if (da < clib_net_to_host_u32 (p->laddr.start.ip4.as_u32)) + continue; - if (da > clib_net_to_host_u32(p->laddr.stop.ip4.as_u32)) - continue; + if (da > clib_net_to_host_u32 (p->laddr.stop.ip4.as_u32)) + continue; - if (sa < clib_net_to_host_u32(p->raddr.start.ip4.as_u32)) - continue; + if (sa < clib_net_to_host_u32 (p->raddr.start.ip4.as_u32)) + continue; - if (sa > clib_net_to_host_u32(p->raddr.stop.ip4.as_u32)) - continue; + if (sa > clib_net_to_host_u32 (p->raddr.stop.ip4.as_u32)) + continue; - return p; - } - return 0; + return p; + } + return 0; } always_inline uword -ip6_addr_match_range (ip6_address_t * a, ip6_address_t * la, ip6_address_t * ua) +ip6_addr_match_range (ip6_address_t * a, ip6_address_t * la, + ip6_address_t * ua) { - if ((memcmp(a->as_u64, la->as_u64, 2 * sizeof(u64)) >= 0) && - (memcmp(a->as_u64, ua->as_u64, 2 * sizeof(u64)) <= 0)) + if ((memcmp (a->as_u64, la->as_u64, 2 * sizeof (u64)) >= 0) && + (memcmp (a->as_u64, ua->as_u64, 2 * sizeof (u64)) <= 0)) return 1; return 0; } always_inline ipsec_policy_t * ipsec_input_ip6_protect_policy_match (ipsec_spd_t * spd, - ip6_address_t * sa, - ip6_address_t * da, - u32 spi) + ip6_address_t * sa, + ip6_address_t * da, u32 spi) { ipsec_main_t *im = &ipsec_main; - ipsec_policy_t * p; - ipsec_sa_t * s; - u32 * i; + ipsec_policy_t *p; + ipsec_sa_t *s; + u32 *i; - vec_foreach(i, spd->ipv6_inbound_protect_policy_indices) - { - p = pool_elt_at_index(spd->policies, *i); - s = pool_elt_at_index(im->sad, p->sa_index); + vec_foreach (i, spd->ipv6_inbound_protect_policy_indices) + { + p = pool_elt_at_index (spd->policies, *i); + s = pool_elt_at_index (im->sad, p->sa_index); - if (spi != s->spi) - continue; + if (spi != s->spi) + continue; - if (s->is_tunnel) - { - if (!ip6_address_is_equal(sa, &s->tunnel_src_addr.ip6)) - continue; + if (s->is_tunnel) + { + if (!ip6_address_is_equal (sa, &s->tunnel_src_addr.ip6)) + continue; - if (!ip6_address_is_equal(da, &s->tunnel_dst_addr.ip6)) - continue; + if (!ip6_address_is_equal (da, &s->tunnel_dst_addr.ip6)) + continue; - return p; - } + return p; + } - if (!ip6_addr_match_range(sa, &p->raddr.start.ip6, &p->raddr.stop.ip6)) - continue; + if (!ip6_addr_match_range (sa, &p->raddr.start.ip6, &p->raddr.stop.ip6)) + continue; - if (!ip6_addr_match_range(da, &p->laddr.start.ip6, &p->laddr.stop.ip6)) - continue; + if (!ip6_addr_match_range (da, &p->laddr.start.ip6, &p->laddr.stop.ip6)) + continue; - return p; - } - return 0; + return p; + } + return 0; } static vlib_node_registration_t ipsec_input_ip4_node; static uword ipsec_input_ip4_node_fn (vlib_main_t * vm, - vlib_node_runtime_t * node, - vlib_frame_t * from_frame) + vlib_node_runtime_t * node, + vlib_frame_t * from_frame) { - ip4_main_t * i4m = &ip4_main; - ip_lookup_main_t * lm = &i4m->lookup_main; - ip_config_main_t * cm = &lm->rx_config_mains[VNET_UNICAST]; + ip4_main_t *i4m = &ip4_main; + ip_lookup_main_t *lm = &i4m->lookup_main; + ip_config_main_t *cm = &lm->rx_config_mains[VNET_UNICAST]; u32 n_left_from, *from, next_index, *to_next; ipsec_main_t *im = &ipsec_main; @@ -195,81 +201,91 @@ ipsec_input_ip4_node_fn (vlib_main_t * vm, vlib_get_next_frame (vm, node, next_index, to_next, n_left_to_next); while (n_left_from > 0 && n_left_to_next > 0) - { - u32 bi0, next0; - vlib_buffer_t * b0; - ip4_header_t *ip0; - esp_header_t *esp0; - ip4_ipsec_config_t * c0; - u32 tunnel_index0 = ~0; - ipsec_spd_t * spd0; - - bi0 = to_next[0] = from[0]; - from += 1; - n_left_from -= 1; - to_next +=1; - n_left_to_next -= 1; - - b0 = vlib_get_buffer (vm, bi0); - c0 = vnet_get_config_data (&cm->config_main, - &b0->current_config_index, - &next0, sizeof (c0[0])); - - spd0 = pool_elt_at_index(im->spds, c0->spd_index); - - ip0 = vlib_buffer_get_current (b0); - esp0 = (esp_header_t *) ((u8 *) ip0 + ip4_header_bytes (ip0)); - - if (PREDICT_TRUE(ip0->protocol == IP_PROTOCOL_IPSEC_ESP)) - { + { + u32 bi0, next0; + vlib_buffer_t *b0; + ip4_header_t *ip0; + esp_header_t *esp0; + ip4_ipsec_config_t *c0; + u32 tunnel_index0 = ~0; + ipsec_spd_t *spd0; + + bi0 = to_next[0] = from[0]; + from += 1; + n_left_from -= 1; + to_next += 1; + n_left_to_next -= 1; + + b0 = vlib_get_buffer (vm, bi0); + c0 = vnet_get_config_data (&cm->config_main, + &b0->current_config_index, + &next0, sizeof (c0[0])); + + spd0 = pool_elt_at_index (im->spds, c0->spd_index); + + ip0 = vlib_buffer_get_current (b0); + esp0 = (esp_header_t *) ((u8 *) ip0 + ip4_header_bytes (ip0)); + + if (PREDICT_TRUE (ip0->protocol == IP_PROTOCOL_IPSEC_ESP)) + { #if 0 - clib_warning("packet received from %U to %U spi %u size %u spd_id %u", - format_ip4_address, ip0->src_address.as_u8, - format_ip4_address, ip0->dst_address.as_u8, - clib_net_to_host_u32(esp0->spi), - clib_net_to_host_u16(ip0->length), - spd0->id); + clib_warning + ("packet received from %U to %U spi %u size %u spd_id %u", + format_ip4_address, ip0->src_address.as_u8, + format_ip4_address, ip0->dst_address.as_u8, + clib_net_to_host_u32 (esp0->spi), + clib_net_to_host_u16 (ip0->length), spd0->id); #endif - ipsec_policy_t * p0; - p0 = ipsec_input_protect_policy_match(spd0, - clib_net_to_host_u32(ip0->src_address.as_u32), - clib_net_to_host_u32(ip0->dst_address.as_u32), - clib_net_to_host_u32(esp0->spi)); - - if (PREDICT_TRUE(p0 != 0)) - { - p0->counter.packets++; - p0->counter.bytes += clib_net_to_host_u16(ip0->length); - vnet_buffer(b0)->output_features.ipsec_sad_index = p0->sa_index; - next0 = IPSEC_INPUT_NEXT_ESP_DECRYPT; - vlib_buffer_advance(b0, ip4_header_bytes (ip0)); - goto trace0; - } - } - - /* FIXME bypass and discard */ - -trace0: - if (PREDICT_FALSE(b0->flags & VLIB_BUFFER_IS_TRACED)) { - ipsec_input_trace_t *tr = vlib_add_trace (vm, node, b0, sizeof (*tr)); - tr->tunnel_index = tunnel_index0; - tr->spi = clib_host_to_net_u32(esp0->spi); - tr->seq = clib_host_to_net_u32(esp0->seq); - } - - vlib_validate_buffer_enqueue_x1 (vm, node, next_index, - to_next, n_left_to_next, bi0, next0); - } + ipsec_policy_t *p0; + p0 = ipsec_input_protect_policy_match (spd0, + clib_net_to_host_u32 + (ip0->src_address. + as_u32), + clib_net_to_host_u32 + (ip0->dst_address. + as_u32), + clib_net_to_host_u32 + (esp0->spi)); + + if (PREDICT_TRUE (p0 != 0)) + { + p0->counter.packets++; + p0->counter.bytes += clib_net_to_host_u16 (ip0->length); + vnet_buffer (b0)->output_features.ipsec_sad_index = + p0->sa_index; + next0 = IPSEC_INPUT_NEXT_ESP_DECRYPT; + vlib_buffer_advance (b0, ip4_header_bytes (ip0)); + goto trace0; + } + } + + /* FIXME bypass and discard */ + + trace0: + if (PREDICT_FALSE (b0->flags & VLIB_BUFFER_IS_TRACED)) + { + ipsec_input_trace_t *tr = + vlib_add_trace (vm, node, b0, sizeof (*tr)); + tr->tunnel_index = tunnel_index0; + tr->spi = clib_host_to_net_u32 (esp0->spi); + tr->seq = clib_host_to_net_u32 (esp0->seq); + } + + vlib_validate_buffer_enqueue_x1 (vm, node, next_index, + to_next, n_left_to_next, bi0, + next0); + } vlib_put_next_frame (vm, node, next_index, n_left_to_next); } vlib_node_increment_counter (vm, ipsec_input_ip4_node.index, - IPSEC_INPUT_ERROR_RX_PKTS, - from_frame->n_vectors); + IPSEC_INPUT_ERROR_RX_PKTS, + from_frame->n_vectors); return from_frame->n_vectors; } +/* *INDENT-OFF* */ VLIB_REGISTER_NODE (ipsec_input_ip4_node,static) = { .function = ipsec_input_ip4_node_fn, .name = "ipsec-input-ip4", @@ -287,21 +303,19 @@ VLIB_REGISTER_NODE (ipsec_input_ip4_node,static) = { #undef _ }, }; +/* *INDENT-ON* */ -VLIB_NODE_FUNCTION_MULTIARCH (ipsec_input_ip4_node, - ipsec_input_ip4_node_fn) +VLIB_NODE_FUNCTION_MULTIARCH (ipsec_input_ip4_node, ipsec_input_ip4_node_fn) + static vlib_node_registration_t ipsec_input_ip6_node; - -static vlib_node_registration_t ipsec_input_ip6_node; - -static uword -ipsec_input_ip6_node_fn (vlib_main_t * vm, - vlib_node_runtime_t * node, - vlib_frame_t * from_frame) + static uword + ipsec_input_ip6_node_fn (vlib_main_t * vm, + vlib_node_runtime_t * node, + vlib_frame_t * from_frame) { - ip6_main_t * i6m = &ip6_main; - ip_lookup_main_t * lm = &i6m->lookup_main; - ip_config_main_t * cm = &lm->rx_config_mains[VNET_UNICAST]; + ip6_main_t *i6m = &ip6_main; + ip_lookup_main_t *lm = &i6m->lookup_main; + ip_config_main_t *cm = &lm->rx_config_mains[VNET_UNICAST]; u32 n_left_from, *from, next_index, *to_next; ipsec_main_t *im = &ipsec_main; @@ -317,81 +331,87 @@ ipsec_input_ip6_node_fn (vlib_main_t * vm, vlib_get_next_frame (vm, node, next_index, to_next, n_left_to_next); while (n_left_from > 0 && n_left_to_next > 0) - { - u32 bi0, next0; - vlib_buffer_t * b0; - ip6_header_t *ip0; - esp_header_t *esp0; - ip4_ipsec_config_t * c0; - u32 tunnel_index0 = ~0; - ipsec_spd_t * spd0; - u32 header_size = sizeof(ip0[0]); - - bi0 = to_next[0] = from[0]; - from += 1; - n_left_from -= 1; - to_next +=1; - n_left_to_next -= 1; - - b0 = vlib_get_buffer (vm, bi0); - c0 = vnet_get_config_data (&cm->config_main, - &b0->current_config_index, - &next0, sizeof (c0[0])); - - spd0 = pool_elt_at_index(im->spds, c0->spd_index); - - ip0 = vlib_buffer_get_current (b0); - esp0 = (esp_header_t *) ((u8 *) ip0 + header_size); - - if (PREDICT_TRUE(ip0->protocol == IP_PROTOCOL_IPSEC_ESP)) - { + { + u32 bi0, next0; + vlib_buffer_t *b0; + ip6_header_t *ip0; + esp_header_t *esp0; + ip4_ipsec_config_t *c0; + u32 tunnel_index0 = ~0; + ipsec_spd_t *spd0; + u32 header_size = sizeof (ip0[0]); + + bi0 = to_next[0] = from[0]; + from += 1; + n_left_from -= 1; + to_next += 1; + n_left_to_next -= 1; + + b0 = vlib_get_buffer (vm, bi0); + c0 = vnet_get_config_data (&cm->config_main, + &b0->current_config_index, + &next0, sizeof (c0[0])); + + spd0 = pool_elt_at_index (im->spds, c0->spd_index); + + ip0 = vlib_buffer_get_current (b0); + esp0 = (esp_header_t *) ((u8 *) ip0 + header_size); + + if (PREDICT_TRUE (ip0->protocol == IP_PROTOCOL_IPSEC_ESP)) + { #if 0 - clib_warning("packet received from %U to %U spi %u size %u spd_id %u", - format_ip6_address, &ip0->src_address, - format_ip6_address, &ip0->dst_address, - clib_net_to_host_u32(esp0->spi), - clib_net_to_host_u16(ip0->payload_length) + header_size, - spd0->id); + clib_warning + ("packet received from %U to %U spi %u size %u spd_id %u", + format_ip6_address, &ip0->src_address, format_ip6_address, + &ip0->dst_address, clib_net_to_host_u32 (esp0->spi), + clib_net_to_host_u16 (ip0->payload_length) + header_size, + spd0->id); #endif - ipsec_policy_t * p0; - p0 = ipsec_input_ip6_protect_policy_match(spd0, - &ip0->src_address, - &ip0->dst_address, - clib_net_to_host_u32(esp0->spi)); - - if (PREDICT_TRUE(p0 != 0)) - { - p0->counter.packets++; - p0->counter.bytes += clib_net_to_host_u16(ip0->payload_length); - p0->counter.bytes += header_size; - vnet_buffer(b0)->output_features.ipsec_sad_index = p0->sa_index; - next0 = IPSEC_INPUT_NEXT_ESP_DECRYPT; - vlib_buffer_advance(b0, header_size); - goto trace0; - } - } - -trace0: - if (PREDICT_FALSE(b0->flags & VLIB_BUFFER_IS_TRACED)) { - ipsec_input_trace_t *tr = vlib_add_trace (vm, node, b0, sizeof (*tr)); - tr->tunnel_index = tunnel_index0; - tr->spi = clib_host_to_net_u32(esp0->spi); - tr->seq = clib_host_to_net_u32(esp0->seq); - } - - vlib_validate_buffer_enqueue_x1 (vm, node, next_index, to_next, - n_left_to_next, bi0, next0); - } + ipsec_policy_t *p0; + p0 = ipsec_input_ip6_protect_policy_match (spd0, + &ip0->src_address, + &ip0->dst_address, + clib_net_to_host_u32 + (esp0->spi)); + + if (PREDICT_TRUE (p0 != 0)) + { + p0->counter.packets++; + p0->counter.bytes += + clib_net_to_host_u16 (ip0->payload_length); + p0->counter.bytes += header_size; + vnet_buffer (b0)->output_features.ipsec_sad_index = + p0->sa_index; + next0 = IPSEC_INPUT_NEXT_ESP_DECRYPT; + vlib_buffer_advance (b0, header_size); + goto trace0; + } + } + + trace0: + if (PREDICT_FALSE (b0->flags & VLIB_BUFFER_IS_TRACED)) + { + ipsec_input_trace_t *tr = + vlib_add_trace (vm, node, b0, sizeof (*tr)); + tr->tunnel_index = tunnel_index0; + tr->spi = clib_host_to_net_u32 (esp0->spi); + tr->seq = clib_host_to_net_u32 (esp0->seq); + } + + vlib_validate_buffer_enqueue_x1 (vm, node, next_index, to_next, + n_left_to_next, bi0, next0); + } vlib_put_next_frame (vm, node, next_index, n_left_to_next); } vlib_node_increment_counter (vm, ipsec_input_ip6_node.index, - IPSEC_INPUT_ERROR_RX_PKTS, - from_frame->n_vectors); + IPSEC_INPUT_ERROR_RX_PKTS, + from_frame->n_vectors); return from_frame->n_vectors; } +/* *INDENT-OFF* */ VLIB_REGISTER_NODE (ipsec_input_ip6_node,static) = { .function = ipsec_input_ip6_node_fn, .name = "ipsec-input-ip6", @@ -409,7 +429,13 @@ VLIB_REGISTER_NODE (ipsec_input_ip6_node,static) = { #undef _ }, }; +/* *INDENT-ON* */ -VLIB_NODE_FUNCTION_MULTIARCH (ipsec_input_ip6_node, - ipsec_input_ip6_node_fn) - +VLIB_NODE_FUNCTION_MULTIARCH (ipsec_input_ip6_node, ipsec_input_ip6_node_fn) +/* + * fd.io coding-style-patch-verification: ON + * + * Local Variables: + * eval: (c-set-style "gnu") + * End: + */ diff --git a/vnet/vnet/ipsec/ipsec_output.c b/vnet/vnet/ipsec/ipsec_output.c index ca82a24479f..278dddc360e 100644 --- a/vnet/vnet/ipsec/ipsec_output.c +++ b/vnet/vnet/ipsec/ipsec_output.c @@ -28,11 +28,11 @@ _(DROP, "error-drop") \ _(ESP_ENCRYPT, "esp-encrypt") #define _(v, s) IPSEC_OUTPUT_NEXT_##v, -typedef enum { - foreach_intf_output_feat - foreach_ipsec_output_next +typedef enum +{ + foreach_intf_output_feat foreach_ipsec_output_next #undef _ - IPSEC_OUTPUT_N_NEXT, + IPSEC_OUTPUT_N_NEXT, } ipsec_output_next_t; @@ -45,14 +45,15 @@ typedef enum { _(ENCAPS_FAILED, "IPSec encapsulation failed") -typedef enum { +typedef enum +{ #define _(sym,str) IPSEC_OUTPUT_ERROR_##sym, foreach_ipsec_output_error #undef _ - IPSEC_DECAP_N_ERROR, + IPSEC_DECAP_N_ERROR, } ipsec_output_error_t; -static char * ipsec_output_error_strings[] = { +static char *ipsec_output_error_strings[] = { #define _(sym,string) string, foreach_ipsec_output_error #undef _ @@ -60,148 +61,150 @@ static char * ipsec_output_error_strings[] = { static vlib_node_registration_t ipsec_output_node; -typedef struct { +typedef struct +{ u32 spd_id; } ipsec_output_trace_t; /* packet trace format function */ -static u8 * format_ipsec_output_trace (u8 * s, va_list * args) +static u8 * +format_ipsec_output_trace (u8 * s, va_list * args) { CLIB_UNUSED (vlib_main_t * vm) = va_arg (*args, vlib_main_t *); CLIB_UNUSED (vlib_node_t * node) = va_arg (*args, vlib_node_t *); - ipsec_output_trace_t * t = va_arg (*args, ipsec_output_trace_t *); + ipsec_output_trace_t *t = va_arg (*args, ipsec_output_trace_t *); if (t->spd_id != ~0) - { - s = format (s, "spd %u ", t->spd_id); - } + { + s = format (s, "spd %u ", t->spd_id); + } else - { - s = format (s, "no spd"); - } + { + s = format (s, "no spd"); + } return s; } -always_inline intf_output_feat_t __attribute__((unused)) -get_next_intf_output_feature_and_reset_bit(vlib_buffer_t *b) +always_inline intf_output_feat_t __attribute__ ((unused)) +get_next_intf_output_feature_and_reset_bit (vlib_buffer_t * b) { u32 next_feature; - count_trailing_zeros(next_feature, vnet_buffer(b)->output_features.bitmap); + count_trailing_zeros (next_feature, + vnet_buffer (b)->output_features.bitmap); if (next_feature != INTF_OUTPUT_FEAT_DONE) - vnet_buffer(b)->output_features.bitmap &= ~(1 << next_feature); + vnet_buffer (b)->output_features.bitmap &= ~(1 << next_feature); return next_feature; } always_inline ipsec_policy_t * -ipsec_output_policy_match(ipsec_spd_t * spd, u8 pr, u32 la, u32 ra, u16 lp, u16 rp) +ipsec_output_policy_match (ipsec_spd_t * spd, u8 pr, u32 la, u32 ra, u16 lp, + u16 rp) { - ipsec_policy_t * p; - u32 * i; + ipsec_policy_t *p; + u32 *i; - vec_foreach(i, spd->ipv4_outbound_policies) - { - p = pool_elt_at_index(spd->policies, *i); - if (PREDICT_FALSE(p->protocol && (p->protocol != pr))) - continue; + vec_foreach (i, spd->ipv4_outbound_policies) + { + p = pool_elt_at_index (spd->policies, *i); + if (PREDICT_FALSE (p->protocol && (p->protocol != pr))) + continue; - if (la < clib_net_to_host_u32(p->laddr.start.ip4.as_u32)) - continue; + if (la < clib_net_to_host_u32 (p->laddr.start.ip4.as_u32)) + continue; - if (la > clib_net_to_host_u32(p->laddr.stop.ip4.as_u32)) - continue; + if (la > clib_net_to_host_u32 (p->laddr.stop.ip4.as_u32)) + continue; - if (ra < clib_net_to_host_u32(p->raddr.start.ip4.as_u32)) - continue; + if (ra < clib_net_to_host_u32 (p->raddr.start.ip4.as_u32)) + continue; - if (ra > clib_net_to_host_u32(p->raddr.stop.ip4.as_u32)) - continue; + if (ra > clib_net_to_host_u32 (p->raddr.stop.ip4.as_u32)) + continue; - if (PREDICT_FALSE((pr != IP_PROTOCOL_TCP) && (pr != IP_PROTOCOL_UDP))) - return p; + if (PREDICT_FALSE ((pr != IP_PROTOCOL_TCP) && (pr != IP_PROTOCOL_UDP))) + return p; - if (lp < p->lport.start) - continue; + if (lp < p->lport.start) + continue; - if (lp > p->lport.stop) - continue; + if (lp > p->lport.stop) + continue; - if (rp < p->rport.start) - continue; + if (rp < p->rport.start) + continue; - if (rp > p->rport.stop) - continue; + if (rp > p->rport.stop) + continue; - return p; - } - return 0; + return p; + } + return 0; } always_inline uword -ip6_addr_match_range (ip6_address_t * a, ip6_address_t * la, ip6_address_t * ua) +ip6_addr_match_range (ip6_address_t * a, ip6_address_t * la, + ip6_address_t * ua) { - if ((memcmp(a->as_u64, la->as_u64, 2 * sizeof(u64)) >= 0) && - (memcmp(a->as_u64, ua->as_u64, 2 * sizeof(u64)) <= 0)) + if ((memcmp (a->as_u64, la->as_u64, 2 * sizeof (u64)) >= 0) && + (memcmp (a->as_u64, ua->as_u64, 2 * sizeof (u64)) <= 0)) return 1; return 0; } always_inline ipsec_policy_t * ipsec_output_ip6_policy_match (ipsec_spd_t * spd, - ip6_address_t * la, - ip6_address_t * ra, - u16 lp, - u16 rp, - u8 pr) + ip6_address_t * la, + ip6_address_t * ra, u16 lp, u16 rp, u8 pr) { - ipsec_policy_t * p; - u32 * i; + ipsec_policy_t *p; + u32 *i; - vec_foreach(i, spd->ipv6_outbound_policies) - { - p = pool_elt_at_index(spd->policies, *i); - if (PREDICT_FALSE(p->protocol && (p->protocol != pr))) - continue; + vec_foreach (i, spd->ipv6_outbound_policies) + { + p = pool_elt_at_index (spd->policies, *i); + if (PREDICT_FALSE (p->protocol && (p->protocol != pr))) + continue; - if (!ip6_addr_match_range(ra, &p->raddr.start.ip6, &p->raddr.stop.ip6)) - continue; + if (!ip6_addr_match_range (ra, &p->raddr.start.ip6, &p->raddr.stop.ip6)) + continue; - if (!ip6_addr_match_range(la, &p->laddr.start.ip6, &p->laddr.stop.ip6)) - continue; + if (!ip6_addr_match_range (la, &p->laddr.start.ip6, &p->laddr.stop.ip6)) + continue; - if (PREDICT_FALSE((pr != IP_PROTOCOL_TCP) && (pr != IP_PROTOCOL_UDP))) - return p; + if (PREDICT_FALSE ((pr != IP_PROTOCOL_TCP) && (pr != IP_PROTOCOL_UDP))) + return p; - if (lp < p->lport.start) - continue; + if (lp < p->lport.start) + continue; - if (lp > p->lport.stop) - continue; + if (lp > p->lport.stop) + continue; - if (rp < p->rport.start) - continue; + if (rp < p->rport.start) + continue; - if (rp > p->rport.stop) - continue; + if (rp > p->rport.stop) + continue; - return p; - } + return p; + } return 0; } + static uword ipsec_output_node_fn (vlib_main_t * vm, - vlib_node_runtime_t * node, - vlib_frame_t * from_frame) + vlib_node_runtime_t * node, vlib_frame_t * from_frame) { ipsec_main_t *im = &ipsec_main; - vnet_main_t * vnm = im->vnet_main; + vnet_main_t *vnm = im->vnet_main; - u32 * from, * to_next = 0; - u32 n_left_from, sw_if_index0, last_sw_if_index = (u32) ~0; - u32 next_node_index = (u32)~0, last_next_node_index = (u32) ~0; + u32 *from, *to_next = 0; + u32 n_left_from, sw_if_index0, last_sw_if_index = (u32) ~ 0; + u32 next_node_index = (u32) ~ 0, last_next_node_index = (u32) ~ 0; vlib_frame_t *f = 0; u32 spd_index0 = ~0; - ipsec_spd_t * spd0 = 0; + ipsec_spd_t *spd0 = 0; u64 nc_protect = 0, nc_bypass = 0, nc_discard = 0, nc_nomatch = 0; from = vlib_frame_vector_args (from_frame); @@ -210,182 +213,199 @@ ipsec_output_node_fn (vlib_main_t * vm, while (n_left_from > 0) { u32 bi0; - vlib_buffer_t * b0; - ipsec_policy_t * p0; - ip4_header_t * ip0; - ip6_header_t * ip6_0 = 0; - udp_header_t * udp0; + vlib_buffer_t *b0; + ipsec_policy_t *p0; + ip4_header_t *ip0; + ip6_header_t *ip6_0 = 0; + udp_header_t *udp0; u8 is_ipv6 = 0; bi0 = from[0]; b0 = vlib_get_buffer (vm, bi0); - sw_if_index0 = vnet_buffer(b0)->sw_if_index[VLIB_TX]; + sw_if_index0 = vnet_buffer (b0)->sw_if_index[VLIB_TX]; ip0 = (ip4_header_t *) ((u8 *) vlib_buffer_get_current (b0) + - sizeof(ethernet_header_t)); + sizeof (ethernet_header_t)); /* just forward non ipv4 packets */ - if (PREDICT_FALSE((ip0->ip_version_and_header_length & 0xF0 ) != 0x40)) - { - /* ipv6 packets */ - if (PREDICT_TRUE((ip0->ip_version_and_header_length & 0xF0 ) == 0x60)) - { - is_ipv6 = 1; - ip6_0 = (ip6_header_t *) ((u8 *) vlib_buffer_get_current (b0) + - sizeof(ethernet_header_t)); - } - else - { - next_node_index = get_next_output_feature_node_index(vnm, b0); - goto dispatch0; - } - } + if (PREDICT_FALSE ((ip0->ip_version_and_header_length & 0xF0) != 0x40)) + { + /* ipv6 packets */ + if (PREDICT_TRUE + ((ip0->ip_version_and_header_length & 0xF0) == 0x60)) + { + is_ipv6 = 1; + ip6_0 = (ip6_header_t *) ((u8 *) vlib_buffer_get_current (b0) + + sizeof (ethernet_header_t)); + } + else + { + next_node_index = get_next_output_feature_node_index (vnm, b0); + goto dispatch0; + } + } /* lookup for SPD only if sw_if_index is changed */ - if (PREDICT_FALSE(last_sw_if_index != sw_if_index0)) - { - uword * p = hash_get (im->spd_index_by_sw_if_index, sw_if_index0); - ASSERT(p); - spd_index0 = p[0]; - spd0 = pool_elt_at_index(im->spds, spd_index0); - last_sw_if_index = sw_if_index0; - } - - if (is_ipv6) - { - udp0 = ip6_next_header(ip6_0); + if (PREDICT_FALSE (last_sw_if_index != sw_if_index0)) + { + uword *p = hash_get (im->spd_index_by_sw_if_index, sw_if_index0); + ASSERT (p); + spd_index0 = p[0]; + spd0 = pool_elt_at_index (im->spds, spd_index0); + last_sw_if_index = sw_if_index0; + } + + if (is_ipv6) + { + udp0 = ip6_next_header (ip6_0); #if 0 - clib_warning("packet received from %U port %u to %U port %u spd_id %u", - format_ip6_address, &ip6_0->src_address, - clib_net_to_host_u16(udp0->src_port), - format_ip6_address, &ip6_0->dst_address, - clib_net_to_host_u16(udp0->dst_port), - spd0->id); + clib_warning + ("packet received from %U port %u to %U port %u spd_id %u", + format_ip6_address, &ip6_0->src_address, + clib_net_to_host_u16 (udp0->src_port), format_ip6_address, + &ip6_0->dst_address, clib_net_to_host_u16 (udp0->dst_port), + spd0->id); #endif - p0 = ipsec_output_ip6_policy_match(spd0, - &ip6_0->src_address, - &ip6_0->dst_address, - clib_net_to_host_u16(udp0->src_port), - clib_net_to_host_u16(udp0->dst_port), - ip6_0->protocol); - } + p0 = ipsec_output_ip6_policy_match (spd0, + &ip6_0->src_address, + &ip6_0->dst_address, + clib_net_to_host_u16 (udp0-> + src_port), + clib_net_to_host_u16 (udp0-> + dst_port), + ip6_0->protocol); + } else - { - udp0 = (udp_header_t *) ((u8 *) ip0 + ip4_header_bytes (ip0)); + { + udp0 = (udp_header_t *) ((u8 *) ip0 + ip4_header_bytes (ip0)); #if 0 - clib_warning("packet received from %U to %U port %u", - format_ip4_address, ip0->src_address.as_u8, - format_ip4_address, ip0->dst_address.as_u8, - clib_net_to_host_u16(udp0->dst_port)); - clib_warning("sw_if_index0 %u spd_index0 %u spd_id %u", - sw_if_index0, spd_index0, spd0->id); + clib_warning ("packet received from %U to %U port %u", + format_ip4_address, ip0->src_address.as_u8, + format_ip4_address, ip0->dst_address.as_u8, + clib_net_to_host_u16 (udp0->dst_port)); + clib_warning ("sw_if_index0 %u spd_index0 %u spd_id %u", + sw_if_index0, spd_index0, spd0->id); #endif - p0 = ipsec_output_policy_match(spd0, ip0->protocol, - clib_net_to_host_u32(ip0->src_address.as_u32), - clib_net_to_host_u32(ip0->dst_address.as_u32), - clib_net_to_host_u16(udp0->src_port), - clib_net_to_host_u16(udp0->dst_port)); - } - - if (PREDICT_TRUE(p0 != NULL)) - { - if (p0->policy == IPSEC_POLICY_ACTION_PROTECT) - { - nc_protect++; - next_node_index = im->esp_encrypt_node_index; - vnet_buffer(b0)->output_features.ipsec_sad_index = p0->sa_index; - vlib_buffer_advance(b0, sizeof(ethernet_header_t)); - p0->counter.packets++; - if (is_ipv6) - { - p0->counter.bytes += clib_net_to_host_u16(ip6_0->payload_length); - p0->counter.bytes += sizeof(ip6_header_t); - } - else - { - p0->counter.bytes += clib_net_to_host_u16(ip0->length); - } - } - else if (p0->policy == IPSEC_POLICY_ACTION_BYPASS) - { - nc_bypass++; - next_node_index = get_next_output_feature_node_index(vnm, b0); - p0->counter.packets++; - if (is_ipv6) - { - p0->counter.bytes += clib_net_to_host_u16(ip6_0->payload_length); - p0->counter.bytes += sizeof(ip6_header_t); - } - else - { - p0->counter.bytes += clib_net_to_host_u16(ip0->length); - } - } - else - { - nc_discard++; - p0->counter.packets++; - if (is_ipv6) - { - p0->counter.bytes += clib_net_to_host_u16(ip6_0->payload_length); - p0->counter.bytes += sizeof(ip6_header_t); - } - else - { - p0->counter.bytes += clib_net_to_host_u16(ip0->length); - } - next_node_index = im->error_drop_node_index; - } - } + p0 = ipsec_output_policy_match (spd0, ip0->protocol, + clib_net_to_host_u32 (ip0-> + src_address. + as_u32), + clib_net_to_host_u32 (ip0-> + dst_address. + as_u32), + clib_net_to_host_u16 (udp0-> + src_port), + clib_net_to_host_u16 (udp0-> + dst_port)); + } + + if (PREDICT_TRUE (p0 != NULL)) + { + if (p0->policy == IPSEC_POLICY_ACTION_PROTECT) + { + nc_protect++; + next_node_index = im->esp_encrypt_node_index; + vnet_buffer (b0)->output_features.ipsec_sad_index = + p0->sa_index; + vlib_buffer_advance (b0, sizeof (ethernet_header_t)); + p0->counter.packets++; + if (is_ipv6) + { + p0->counter.bytes += + clib_net_to_host_u16 (ip6_0->payload_length); + p0->counter.bytes += sizeof (ip6_header_t); + } + else + { + p0->counter.bytes += clib_net_to_host_u16 (ip0->length); + } + } + else if (p0->policy == IPSEC_POLICY_ACTION_BYPASS) + { + nc_bypass++; + next_node_index = get_next_output_feature_node_index (vnm, b0); + p0->counter.packets++; + if (is_ipv6) + { + p0->counter.bytes += + clib_net_to_host_u16 (ip6_0->payload_length); + p0->counter.bytes += sizeof (ip6_header_t); + } + else + { + p0->counter.bytes += clib_net_to_host_u16 (ip0->length); + } + } + else + { + nc_discard++; + p0->counter.packets++; + if (is_ipv6) + { + p0->counter.bytes += + clib_net_to_host_u16 (ip6_0->payload_length); + p0->counter.bytes += sizeof (ip6_header_t); + } + else + { + p0->counter.bytes += clib_net_to_host_u16 (ip0->length); + } + next_node_index = im->error_drop_node_index; + } + } else - { - nc_nomatch++; - next_node_index = im->error_drop_node_index; - } + { + nc_nomatch++; + next_node_index = im->error_drop_node_index; + } -dispatch0: + dispatch0: from += 1; n_left_from -= 1; - if (PREDICT_FALSE((last_next_node_index != next_node_index))) - { - /* if this is not 1st frame */ - if (f) - vlib_put_frame_to_node (vm, last_next_node_index, f); + if (PREDICT_FALSE ((last_next_node_index != next_node_index))) + { + /* if this is not 1st frame */ + if (f) + vlib_put_frame_to_node (vm, last_next_node_index, f); - last_next_node_index = next_node_index; + last_next_node_index = next_node_index; - f = vlib_get_frame_to_node(vm, next_node_index); - to_next = vlib_frame_vector_args (f); - } + f = vlib_get_frame_to_node (vm, next_node_index); + to_next = vlib_frame_vector_args (f); + } to_next[0] = bi0; - to_next+=1; + to_next += 1; f->n_vectors++; - if (PREDICT_FALSE(b0->flags & VLIB_BUFFER_IS_TRACED)) { - ipsec_output_trace_t *tr = vlib_add_trace (vm, node, b0, sizeof (*tr)); - if (spd0) - tr->spd_id = spd0->id; - } + if (PREDICT_FALSE (b0->flags & VLIB_BUFFER_IS_TRACED)) + { + ipsec_output_trace_t *tr = + vlib_add_trace (vm, node, b0, sizeof (*tr)); + if (spd0) + tr->spd_id = spd0->id; + } } vlib_put_frame_to_node (vm, next_node_index, f); vlib_node_increment_counter (vm, ipsec_output_node.index, - IPSEC_OUTPUT_ERROR_POLICY_PROTECT, nc_protect); + IPSEC_OUTPUT_ERROR_POLICY_PROTECT, nc_protect); vlib_node_increment_counter (vm, ipsec_output_node.index, - IPSEC_OUTPUT_ERROR_POLICY_BYPASS, nc_bypass); + IPSEC_OUTPUT_ERROR_POLICY_BYPASS, nc_bypass); vlib_node_increment_counter (vm, ipsec_output_node.index, - IPSEC_OUTPUT_ERROR_POLICY_DISCARD, nc_discard); + IPSEC_OUTPUT_ERROR_POLICY_DISCARD, nc_discard); vlib_node_increment_counter (vm, ipsec_output_node.index, - IPSEC_OUTPUT_ERROR_POLICY_NO_MATCH, nc_nomatch); + IPSEC_OUTPUT_ERROR_POLICY_NO_MATCH, + nc_nomatch); return from_frame->n_vectors; } +/* *INDENT-OFF* */ VLIB_REGISTER_NODE (ipsec_output_node,static) = { .function = ipsec_output_node_fn, .name = "ipsec-output", @@ -404,25 +424,34 @@ VLIB_REGISTER_NODE (ipsec_output_node,static) = { #undef _ }, }; +/* *INDENT-ON* */ VLIB_NODE_FUNCTION_MULTIARCH (ipsec_output_node, ipsec_output_node_fn) - #else /* IPSEC > 1 */ /* Dummy ipsec output node, in case when IPSec is disabled */ static uword ipsec_output_node_fn (vlib_main_t * vm, - vlib_node_runtime_t * node, - vlib_frame_t * frame) + vlib_node_runtime_t * node, vlib_frame_t * frame) { clib_warning ("IPSec disabled"); return 0; } +/* *INDENT-OFF* */ VLIB_REGISTER_NODE (ipsec_output_node) = { .vector_size = sizeof (u32), .function = ipsec_output_node_fn, .name = "ipsec-output", }; +/* *INDENT-ON* */ #endif + +/* + * fd.io coding-style-patch-verification: ON + * + * Local Variables: + * eval: (c-set-style "gnu") + * End: + */ |