From 5f1fe8111ce9dae9a96df83963a1c4cbbb89a25f Mon Sep 17 00:00:00 2001 From: Szymon Sliwa Date: Wed, 14 Feb 2018 13:40:01 +0100 Subject: plugins: odp: Add error checks in IPsec nodes Change-Id: I62cba4a845c91b208420f3f6b20781d75976c113 Signed-off-by: Szymon Sliwa --- src/plugins/odp/ipsec/crypto_input.c | 22 ++++++++++++-- src/plugins/odp/ipsec/esp_decrypt_ipsec_api.c | 30 ++++++++++++++------ src/plugins/odp/ipsec/esp_encrypt_ipsec_api.c | 41 +++++++++++++++++++-------- 3 files changed, 70 insertions(+), 23 deletions(-) diff --git a/src/plugins/odp/ipsec/crypto_input.c b/src/plugins/odp/ipsec/crypto_input.c index a522b225..05e32573 100644 --- a/src/plugins/odp/ipsec/crypto_input.c +++ b/src/plugins/odp/ipsec/crypto_input.c @@ -30,7 +30,8 @@ typedef enum #define foreach_crypto_input_error \ _(DEQUE_COP, "Dequed crypto operations") \ -_(CRYPTO_ERROR, "Error while performing crypto") +_(CRYPTO_ERROR, "Error while performing crypto") \ +_(IPSEC_ERROR, "Erro while performing ipsec processing") typedef enum { @@ -163,11 +164,26 @@ odp_dequeue_ipsec_ops (vlib_main_t * vm, vlib_node_runtime_t * node, odp_event_t event = events[index++]; odp_packet_t pkt; + odp_ipsec_packet_result_t result; vlib_buffer_t *b0; u32 bi0; + u32 next0 = next_index; + + /* We are not interested in other event types */ + ASSERT (ODP_EVENT_PACKET == odp_event_type (event)); + pkt = odp_packet_from_event (event); + odp_ipsec_result (&result, pkt); + + if (PREDICT_FALSE (result.status.all != ODP_IPSEC_OK)) + { + vlib_node_increment_counter (vm, odp_crypto_input_node.index, + CRYPTO_INPUT_ERROR_IPSEC_ERROR, 1); + next0 = ODP_CRYPTO_INPUT_NEXT_DROP; + } + b0 = vlib_buffer_from_odp_packet (pkt); bi0 = vlib_get_buffer_index (vm, b0); @@ -191,12 +207,12 @@ odp_dequeue_ipsec_ops (vlib_main_t * vm, vlib_node_runtime_t * node, { odp_packet_crypto_trace_t *tr; tr = vlib_add_trace (vm, node, b0, sizeof (*tr)); - tr->next_index = next_index; + tr->next_index = next0; } vlib_validate_buffer_enqueue_x1 (vm, node, next_index, to_next, n_left_to_next, bi0, - next_node_index); + next0); } vlib_put_next_frame (vm, node, next_index, n_left_to_next); } diff --git a/src/plugins/odp/ipsec/esp_decrypt_ipsec_api.c b/src/plugins/odp/ipsec/esp_decrypt_ipsec_api.c index 5a1b2d38..8069bf55 100644 --- a/src/plugins/odp/ipsec/esp_decrypt_ipsec_api.c +++ b/src/plugins/odp/ipsec/esp_decrypt_ipsec_api.c @@ -179,6 +179,7 @@ odp_ipsec_esp_decrypt_node_fn (vlib_main_t * vm, else next0 = ESP_DECRYPT_NEXT_IP4_INPUT; + odp_ipsec_packet_result_t result; odp_packet_t pkt = odp_packet_from_vlib_buffer (i_b0); odp_packet_t out_pkt; @@ -210,6 +211,16 @@ odp_ipsec_esp_decrypt_node_fn (vlib_main_t * vm, if (!is_async) { + odp_ipsec_result (&result, out_pkt); + if (PREDICT_FALSE (result.status.all != ODP_IPSEC_OK)) + { + vlib_node_increment_counter (vm, + odp_ipsec_esp_decrypt_node.index, + ESP_DECRYPT_ERROR_DECRYPTION_FAILED, + from_frame->n_vectors); + goto trace; + } + o_b0 = vlib_buffer_from_odp_packet (out_pkt); /* add the change of the ODP data offset @@ -222,14 +233,6 @@ odp_ipsec_esp_decrypt_node_fn (vlib_main_t * vm, odp_packet_len (out_pkt) - sizeof (ethernet_header_t); vnet_buffer (o_b0)->sw_if_index[VLIB_TX] = (u32) ~ 0; - - vlib_validate_buffer_enqueue_x1 (vm, node, next_index, to_next, - n_left_to_next, bi0, next0); - } - else - { - to_next -= 1; - n_left_to_next += 1; } trace: @@ -240,6 +243,17 @@ odp_ipsec_esp_decrypt_node_fn (vlib_main_t * vm, tr->crypto_alg = sa0->crypto_alg; tr->integ_alg = sa0->integ_alg; } + + if (!is_async) + { + vlib_validate_buffer_enqueue_x1 (vm, node, next_index, to_next, + n_left_to_next, bi0, next0); + } + else + { + to_next -= 1; + n_left_to_next += 1; + } } vlib_put_next_frame (vm, node, next_index, n_left_to_next); } diff --git a/src/plugins/odp/ipsec/esp_encrypt_ipsec_api.c b/src/plugins/odp/ipsec/esp_encrypt_ipsec_api.c index 994cd9cf..3051f62a 100644 --- a/src/plugins/odp/ipsec/esp_encrypt_ipsec_api.c +++ b/src/plugins/odp/ipsec/esp_encrypt_ipsec_api.c @@ -42,7 +42,7 @@ typedef enum #define foreach_esp_encrypt_error \ _(RX_PKTS, "ESP pkts received") \ _(NO_BUFFER, "No buffer (packet dropped)") \ - _(DECRYPTION_FAILED, "ESP encryption failed") \ + _(ENCRYPTION_FAILED, "ESP encryption failed") \ _(SEQ_CYCLED, "sequence number cycled") @@ -206,6 +206,7 @@ odp_ipsec_esp_encrypt_node_fn (vlib_main_t * vm, if (PREDICT_TRUE (sa0->crypto_alg != IPSEC_CRYPTO_ALG_NONE)) { + odp_ipsec_packet_result_t result; odp_packet_t pkt = odp_packet_from_vlib_buffer (i_b0); odp_packet_t out_pkt; odp_ipsec_out_inline_param_t ipsec_inline_params; @@ -248,7 +249,7 @@ odp_ipsec_esp_encrypt_node_fn (vlib_main_t * vm, vnet_buffer (i_b0)->sw_if_index[VLIB_TX], 1, i_b0->current_length); } - else if (is_async) + else if (is_async) ret = odp_ipsec_out_enq (&pkt, 1, &oiopt); else ret = odp_ipsec_out (&pkt, 1, &out_pkt, &processed, &oiopt); @@ -256,6 +257,7 @@ odp_ipsec_esp_encrypt_node_fn (vlib_main_t * vm, if (ret < 1) { clib_error ("(out) IPsec packet not processed\n"); + next0 = ESP_ENCRYPT_NEXT_DROP; goto trace; } @@ -264,8 +266,18 @@ odp_ipsec_esp_encrypt_node_fn (vlib_main_t * vm, && !(is_inline && next0 == ESP_ENCRYPT_NEXT_INTERFACE_OUTPUT)) { - o_b0 = vlib_buffer_from_odp_packet (out_pkt); + odp_ipsec_result (&result, out_pkt); + if (PREDICT_FALSE (result.status.all != ODP_IPSEC_OK)) + { + vlib_node_increment_counter (vm, + odp_ipsec_esp_encrypt_node.index, + ESP_ENCRYPT_ERROR_ENCRYPTION_FAILED, + from_frame->n_vectors); + next0 = ESP_ENCRYPT_NEXT_DROP; + goto trace; + } + o_b0 = vlib_buffer_from_odp_packet (out_pkt); o_b0->current_data = (i16) ((intptr_t) odp_packet_data (out_pkt) - @@ -294,16 +306,8 @@ odp_ipsec_esp_encrypt_node_fn (vlib_main_t * vm, o_b0->current_data -= sizeof (ethernet_header_t); o_b0->current_length += sizeof (ethernet_header_t); } - - vlib_validate_buffer_enqueue_x1 (vm, node, next_index, - to_next, n_left_to_next, - bi0, next0); - } - else - { - to_next -= 1; - n_left_to_next += 1; } + } trace: if (PREDICT_FALSE (i_b0->flags & VLIB_BUFFER_IS_TRACED)) @@ -315,6 +319,19 @@ odp_ipsec_esp_encrypt_node_fn (vlib_main_t * vm, tr->crypto_alg = sa0->crypto_alg; tr->integ_alg = sa0->integ_alg; } + + if (!is_async + && !(is_inline && next0 == ESP_ENCRYPT_NEXT_INTERFACE_OUTPUT)) + { + vlib_validate_buffer_enqueue_x1 (vm, node, next_index, + to_next, n_left_to_next, + bi0, next0); + } + else + { + to_next -= 1; + n_left_to_next += 1; + } } vlib_put_next_frame (vm, node, next_index, n_left_to_next); } -- cgit 1.2.3-korg