X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=src%2Fplugins%2Fdpdk%2Fipsec%2Fesp_decrypt.c;h=9a782abeb949b273a66c345cb353c6feb4edbcce;hb=c5fe57dac12a46fa618259643909afaec1ac5aae;hp=dcc276f99bc5dfa25d28c8ca3f3c947177cef7e5;hpb=d709cbcb1ef80633af657c5427608831e5bbd919;p=vpp.git diff --git a/src/plugins/dpdk/ipsec/esp_decrypt.c b/src/plugins/dpdk/ipsec/esp_decrypt.c index dcc276f99bc..9a782abeb94 100644 --- a/src/plugins/dpdk/ipsec/esp_decrypt.c +++ b/src/plugins/dpdk/ipsec/esp_decrypt.c @@ -44,8 +44,8 @@ typedef enum _(DECRYPTION_FAILED, "ESP decryption failed") \ _(REPLAY, "SA replayed packet") \ _(NOT_IP, "Not IP packet (dropped)") \ - _(ENQ_FAIL, "Enqueue failed (buffer full)") \ - _(DISCARD, "Not enough crypto operations, discarding frame") \ + _(ENQ_FAIL, "Enqueue decrypt failed (queue full)") \ + _(DISCARD, "Not enough crypto operations") \ _(BAD_LEN, "Invalid ciphertext length") \ _(SESSION, "Failed to get crypto session") \ _(NOSUP, "Cipher/Auth not supported") @@ -98,7 +98,6 @@ dpdk_esp_decrypt_inline (vlib_main_t * vm, vlib_frame_t * from_frame, int is_ip6) { u32 n_left_from, *from, *to_next, next_index, thread_index; - ipsec_main_t *im = &ipsec_main; u32 thread_idx = vlib_get_thread_index (); dpdk_crypto_main_t *dcm = &dpdk_crypto_main; crypto_resource_t *res = 0; @@ -121,11 +120,12 @@ dpdk_esp_decrypt_inline (vlib_main_t * vm, { if (is_ip6) vlib_node_increment_counter (vm, dpdk_esp6_decrypt_node.index, - ESP_DECRYPT_ERROR_DISCARD, 1); + ESP_DECRYPT_ERROR_DISCARD, n_left_from); else vlib_node_increment_counter (vm, dpdk_esp4_decrypt_node.index, - ESP_DECRYPT_ERROR_DISCARD, 1); + ESP_DECRYPT_ERROR_DISCARD, n_left_from); /* Discard whole frame */ + vlib_buffer_free (vm, from, n_left_from); return n_left_from; } @@ -140,7 +140,7 @@ dpdk_esp_decrypt_inline (vlib_main_t * vm, while (n_left_from > 0 && n_left_to_next > 0) { clib_error_t *error; - u32 bi0, sa_index0, seq, iv_size; + u32 bi0, sa_index0, iv_size; u8 trunc_size; vlib_buffer_t *b0; esp_header_t *esp0; @@ -168,6 +168,7 @@ dpdk_esp_decrypt_inline (vlib_main_t * vm, dpdk_op_priv_t *priv = crypto_op_get_priv (op); /* store bi in op private */ priv->bi = bi0; + priv->encrypt = 0; u16 op_len = sizeof (op[0]) + sizeof (op[0].sym[0]) + sizeof (priv[0]); @@ -179,7 +180,7 @@ dpdk_esp_decrypt_inline (vlib_main_t * vm, if (sa_index0 != last_sa_index) { - sa0 = pool_elt_at_index (im->sad, sa_index0); + sa0 = ipsec_sa_get (sa_index0); cipher_alg = vec_elt_at_index (dcm->cipher_algs, sa0->crypto_alg); @@ -193,8 +194,6 @@ dpdk_esp_decrypt_inline (vlib_main_t * vm, if (PREDICT_FALSE (res_idx == (u16) ~ 0)) { - clib_warning ("unsupported SA by thread index %u", - thread_idx); if (is_ip6) vlib_node_increment_counter (vm, dpdk_esp6_decrypt_node.index, @@ -213,7 +212,6 @@ dpdk_esp_decrypt_inline (vlib_main_t * vm, error = crypto_get_session (&session, sa_index0, res, cwm, 0); if (PREDICT_FALSE (error || !session)) { - clib_warning ("failed to get crypto session"); if (is_ip6) vlib_node_increment_counter (vm, dpdk_esp6_decrypt_node.index, @@ -234,39 +232,30 @@ dpdk_esp_decrypt_inline (vlib_main_t * vm, } /* anti-replay check */ - if (ipsec_sa_is_set_USE_ANTI_REPLAY (sa0)) + if (ipsec_sa_anti_replay_check + (sa0, clib_host_to_net_u32 (esp0->seq))) { - int rv = 0; - - seq = clib_net_to_host_u32 (esp0->seq); - - if (PREDICT_TRUE (ipsec_sa_is_set_USE_EXTENDED_SEQ_NUM (sa0))) - rv = esp_replay_check_esn (sa0, seq); + if (is_ip6) + vlib_node_increment_counter (vm, + dpdk_esp6_decrypt_node.index, + ESP_DECRYPT_ERROR_REPLAY, 1); else - rv = esp_replay_check (sa0, seq); - - if (PREDICT_FALSE (rv)) - { - clib_warning ("failed anti-replay check"); - if (is_ip6) - vlib_node_increment_counter (vm, - dpdk_esp6_decrypt_node.index, - ESP_DECRYPT_ERROR_REPLAY, 1); - else - vlib_node_increment_counter (vm, - dpdk_esp4_decrypt_node.index, - ESP_DECRYPT_ERROR_REPLAY, 1); - to_next[0] = bi0; - to_next += 1; - n_left_to_next -= 1; - goto trace; - } + vlib_node_increment_counter (vm, + dpdk_esp4_decrypt_node.index, + ESP_DECRYPT_ERROR_REPLAY, 1); + to_next[0] = bi0; + to_next += 1; + n_left_to_next -= 1; + goto trace; } if (is_ip6) priv->next = DPDK_CRYPTO_INPUT_NEXT_DECRYPT6_POST; else - priv->next = DPDK_CRYPTO_INPUT_NEXT_DECRYPT4_POST; + { + priv->next = DPDK_CRYPTO_INPUT_NEXT_DECRYPT4_POST; + b0->flags |= VNET_BUFFER_F_IS_IP4; + } /* FIXME multi-seg */ vlib_increment_combined_counter @@ -293,8 +282,6 @@ dpdk_esp_decrypt_inline (vlib_main_t * vm, if (payload_len & (cipher_alg->boundary - 1)) { - clib_warning ("payload %u not multiple of %d\n", - payload_len, cipher_alg->boundary); if (is_ip6) vlib_node_increment_counter (vm, dpdk_esp6_decrypt_node.index, ESP_DECRYPT_ERROR_BAD_LEN, 1); @@ -320,8 +307,7 @@ dpdk_esp_decrypt_inline (vlib_main_t * vm, cipher_len = payload_len; u8 *digest = vlib_buffer_get_tail (b0) - trunc_size; - u64 digest_paddr = - mb0->buf_physaddr + digest - ((u8 *) mb0->buf_addr); + u64 digest_paddr = mb0->buf_iova + digest - ((u8 *) mb0->buf_addr); if (!is_aead && cipher_alg->alg == RTE_CRYPTO_CIPHER_AES_CBC) clib_memcpy_fast (icb, iv, 16); @@ -339,8 +325,11 @@ dpdk_esp_decrypt_inline (vlib_main_t * vm, clib_memcpy_fast (aad, esp0, 8); /* _aad[3] should always be 0 */ - if (PREDICT_FALSE (ipsec_sa_is_set_USE_EXTENDED_SEQ_NUM (sa0))) - _aad[2] = clib_host_to_net_u32 (sa0->seq_hi); + if (PREDICT_FALSE (ipsec_sa_is_set_USE_ESN (sa0))) + { + _aad[2] = _aad[1]; + _aad[1] = clib_host_to_net_u32 (sa0->seq_hi); + } else _aad[2] = 0; } @@ -348,7 +337,7 @@ dpdk_esp_decrypt_inline (vlib_main_t * vm, { auth_len = sizeof (esp_header_t) + iv_size + payload_len; - if (ipsec_sa_is_set_USE_EXTENDED_SEQ_NUM (sa0)) + if (ipsec_sa_is_set_USE_ESN (sa0)) { clib_memcpy_fast (priv->icv, digest, trunc_size); u32 *_digest = (u32 *) digest; @@ -384,7 +373,7 @@ dpdk_esp_decrypt_inline (vlib_main_t * vm, from_frame->n_vectors); crypto_enqueue_ops (vm, cwm, dpdk_esp6_decrypt_node.index, - ESP_DECRYPT_ERROR_ENQ_FAIL, numa); + ESP_DECRYPT_ERROR_ENQ_FAIL, numa, 0 /* encrypt */ ); } else { @@ -393,7 +382,7 @@ dpdk_esp_decrypt_inline (vlib_main_t * vm, from_frame->n_vectors); crypto_enqueue_ops (vm, cwm, dpdk_esp4_decrypt_node.index, - ESP_DECRYPT_ERROR_ENQ_FAIL, numa); + ESP_DECRYPT_ERROR_ENQ_FAIL, numa, 0 /* encrypt */ ); } crypto_free_ops (numa, ops, cwm->ops + from_frame->n_vectors - ops); @@ -508,7 +497,6 @@ dpdk_esp_decrypt_post_inline (vlib_main_t * vm, u32 n_left_from, *from, *to_next = 0, next_index; ipsec_sa_t *sa0; u32 sa_index0 = ~0; - ipsec_main_t *im = &ipsec_main; dpdk_crypto_main_t *dcm = &dpdk_crypto_main; from = vlib_frame_vector_args (from_frame); @@ -545,7 +533,7 @@ dpdk_esp_decrypt_post_inline (vlib_main_t * vm, esp0 = vlib_buffer_get_current (b0); sa_index0 = vnet_buffer (b0)->ipsec.sad_index; - sa0 = pool_elt_at_index (im->sad, sa_index0); + sa0 = ipsec_sa_get (sa_index0); to_next[0] = bi0; to_next += 1; @@ -560,15 +548,8 @@ dpdk_esp_decrypt_post_inline (vlib_main_t * vm, iv_size = cipher_alg->iv_len; - if (ipsec_sa_is_set_USE_ANTI_REPLAY (sa0)) - { - u32 seq; - seq = clib_host_to_net_u32 (esp0->seq); - if (PREDICT_TRUE (ipsec_sa_is_set_USE_EXTENDED_SEQ_NUM (sa0))) - esp_replay_advance_esn (sa0, seq); - else - esp_replay_advance (sa0, seq); - } + ipsec_sa_anti_replay_advance (sa0, + clib_host_to_net_u32 (esp0->seq)); /* if UDP encapsulation is used adjust the address of the IP header */ if (ipsec_sa_is_set_UDP_ENCAP (sa0) @@ -604,8 +585,7 @@ dpdk_esp_decrypt_post_inline (vlib_main_t * vm, { if (f0->next_header == IP_PROTOCOL_IP_IN_IP) next0 = ESP_DECRYPT_NEXT_IP4_INPUT; - else if (ipsec_sa_is_set_IS_TUNNEL_V6 (sa0) - && f0->next_header == IP_PROTOCOL_IPV6) + else if (f0->next_header == IP_PROTOCOL_IPV6) next0 = ESP_DECRYPT_NEXT_IP6_INPUT; else { @@ -628,16 +608,14 @@ dpdk_esp_decrypt_post_inline (vlib_main_t * vm, if ((ih4->ip_version_and_header_length & 0xF0) == 0x40) { u16 ih4_len = ip4_header_bytes (ih4); - vlib_buffer_advance (b0, -ih4_len - udp_encap_adv); + vlib_buffer_advance (b0, -ih4_len); next0 = ESP_DECRYPT_NEXT_IP4_INPUT; - if (!ipsec_sa_is_set_UDP_ENCAP (sa0)) - { - oh4 = vlib_buffer_get_current (b0); - memmove (oh4, ih4, ih4_len); - oh4->protocol = f0->next_header; - oh4->length = clib_host_to_net_u16 (b0->current_length); - oh4->checksum = ip4_header_checksum (oh4); - } + + oh4 = vlib_buffer_get_current (b0); + memmove (oh4, ih4, ih4_len); + oh4->protocol = f0->next_header; + oh4->length = clib_host_to_net_u16 (b0->current_length); + oh4->checksum = ip4_header_checksum (oh4); } else if ((ih4->ip_version_and_header_length & 0xF0) == 0x60) {