plugins: odp: Add error checks in IPsec nodes 59/10659/5
authorSzymon Sliwa <[email protected]>
Wed, 14 Feb 2018 12:40:01 +0000 (13:40 +0100)
committerSzymon Sliwa <[email protected]>
Wed, 21 Feb 2018 15:43:46 +0000 (16:43 +0100)
Change-Id: I62cba4a845c91b208420f3f6b20781d75976c113
Signed-off-by: Szymon Sliwa <[email protected]>
src/plugins/odp/ipsec/crypto_input.c
src/plugins/odp/ipsec/esp_decrypt_ipsec_api.c
src/plugins/odp/ipsec/esp_encrypt_ipsec_api.c

index a522b22..05e3257 100644 (file)
@@ -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);
     }
index 5a1b2d3..8069bf5 100644 (file)
@@ -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);
     }
index 994cd9c..3051f62 100644 (file)
@@ -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);
     }