LCOV - code coverage report
Current view: top level - vnet/ipsec - ipsec_handoff.c (source / functions) Hit Total Coverage
Test: coverage-filtered.info Lines: 100 104 96.2 %
Date: 2023-10-26 01:39:38 Functions: 92 132 69.7 %

          Line data    Source code
       1             : /*
       2             :  * esp_encrypt.c : IPSec ESP encrypt node
       3             :  *
       4             :  * Copyright (c) 2015 Cisco and/or its affiliates.
       5             :  * Licensed under the Apache License, Version 2.0 (the "License");
       6             :  * you may not use this file except in compliance with the License.
       7             :  * You may obtain a copy of the License at:
       8             :  *
       9             :  *     http://www.apache.org/licenses/LICENSE-2.0
      10             :  *
      11             :  * Unless required by applicable law or agreed to in writing, software
      12             :  * distributed under the License is distributed on an "AS IS" BASIS,
      13             :  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
      14             :  * See the License for the specific language governing permissions and
      15             :  * limitations under the License.
      16             :  */
      17             : 
      18             : #include <vnet/ipsec/ipsec.h>
      19             : #include <vnet/ipsec/ipsec_sa.h>
      20             : 
      21             : #define foreach_ipsec_handoff_error  \
      22             : _(CONGESTION_DROP, "congestion drop")
      23             : 
      24             : typedef enum
      25             : {
      26             : #define _(sym,str) IPSEC_HANDOFF_ERROR_##sym,
      27             :   foreach_ipsec_handoff_error
      28             : #undef _
      29             :     NAT44_HANDOFF_N_ERROR,
      30             : } ipsec_handoff_error_t;
      31             : 
      32             : static char *ipsec_handoff_error_strings[] = {
      33             : #define _(sym,string) string,
      34             :   foreach_ipsec_handoff_error
      35             : #undef _
      36             : };
      37             : 
      38             : typedef struct ipsec_handoff_trace_t_
      39             : {
      40             :   u32 next_worker_index;
      41             : } ipsec_handoff_trace_t;
      42             : 
      43             : static u8 *
      44        1070 : format_ipsec_handoff_trace (u8 * s, va_list * args)
      45             : {
      46        1070 :   CLIB_UNUSED (vlib_main_t * vm) = va_arg (*args, vlib_main_t *);
      47        1070 :   CLIB_UNUSED (vlib_node_t * node) = va_arg (*args, vlib_node_t *);
      48        1070 :   ipsec_handoff_trace_t *t = va_arg (*args, ipsec_handoff_trace_t *);
      49             : 
      50        1070 :   s = format (s, "next-worker %d", t->next_worker_index);
      51             : 
      52        1070 :   return s;
      53             : }
      54             : 
      55             : /* do worker handoff based on thread_index in NAT HA protcol header */
      56             : static_always_inline uword
      57          44 : ipsec_handoff (vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame,
      58             :                u32 fq_index)
      59             : {
      60             :   vlib_buffer_t *bufs[VLIB_FRAME_SIZE], **b;
      61             :   u16 thread_indices[VLIB_FRAME_SIZE], *ti;
      62             :   u32 n_enq, n_left_from, *from;
      63             : 
      64          44 :   from = vlib_frame_vector_args (frame);
      65          44 :   n_left_from = frame->n_vectors;
      66          44 :   vlib_get_buffers (vm, from, bufs, n_left_from);
      67             : 
      68          44 :   b = bufs;
      69          44 :   ti = thread_indices;
      70             : 
      71         392 :   while (n_left_from >= 4)
      72             :     {
      73             :       /* Prefetch next iteration. */
      74         348 :       if (n_left_from >= 12)
      75             :         {
      76         260 :           vlib_prefetch_buffer_header (b[8], LOAD);
      77         260 :           vlib_prefetch_buffer_header (b[9], LOAD);
      78         260 :           vlib_prefetch_buffer_header (b[10], LOAD);
      79         260 :           vlib_prefetch_buffer_header (b[11], LOAD);
      80             :         }
      81             : 
      82         348 :       ti[0] = vnet_buffer (b[0])->ipsec.thread_index;
      83         348 :       ti[1] = vnet_buffer (b[1])->ipsec.thread_index;
      84         348 :       ti[2] = vnet_buffer (b[2])->ipsec.thread_index;
      85         348 :       ti[3] = vnet_buffer (b[3])->ipsec.thread_index;
      86             : 
      87         348 :       if (PREDICT_FALSE (node->flags & VLIB_NODE_FLAG_TRACE))
      88             :         {
      89         180 :           if (PREDICT_FALSE (b[0]->flags & VLIB_BUFFER_IS_TRACED))
      90             :             {
      91             :               ipsec_handoff_trace_t *t =
      92         179 :                 vlib_add_trace (vm, node, b[0], sizeof (*t));
      93         179 :               t->next_worker_index = ti[0];
      94             :             }
      95         180 :           if (PREDICT_FALSE (b[1]->flags & VLIB_BUFFER_IS_TRACED))
      96             :             {
      97             :               ipsec_handoff_trace_t *t =
      98         178 :                 vlib_add_trace (vm, node, b[1], sizeof (*t));
      99         178 :               t->next_worker_index = ti[1];
     100             :             }
     101         180 :           if (PREDICT_FALSE (b[2]->flags & VLIB_BUFFER_IS_TRACED))
     102             :             {
     103             :               ipsec_handoff_trace_t *t =
     104         178 :                 vlib_add_trace (vm, node, b[2], sizeof (*t));
     105         178 :               t->next_worker_index = ti[2];
     106             :             }
     107         180 :           if (PREDICT_FALSE (b[3]->flags & VLIB_BUFFER_IS_TRACED))
     108             :             {
     109             :               ipsec_handoff_trace_t *t =
     110         178 :                 vlib_add_trace (vm, node, b[3], sizeof (*t));
     111         178 :               t->next_worker_index = ti[3];
     112             :             }
     113             :         }
     114             : 
     115         348 :       n_left_from -= 4;
     116         348 :       ti += 4;
     117         348 :       b += 4;
     118             :     }
     119         155 :   while (n_left_from > 0)
     120             :     {
     121         111 :       ti[0] = vnet_buffer (b[0])->ipsec.thread_index;
     122             : 
     123         111 :       if (PREDICT_FALSE (b[0]->flags & VLIB_BUFFER_IS_TRACED))
     124             :         {
     125             :           ipsec_handoff_trace_t *t =
     126         100 :             vlib_add_trace (vm, node, b[0], sizeof (*t));
     127         100 :           t->next_worker_index = ti[0];
     128             :         }
     129             : 
     130         111 :       n_left_from -= 1;
     131         111 :       ti += 1;
     132         111 :       b += 1;
     133             :     }
     134             : 
     135          44 :   n_enq = vlib_buffer_enqueue_to_thread (vm, node, fq_index, from,
     136          44 :                                          thread_indices, frame->n_vectors, 1);
     137             : 
     138          44 :   if (n_enq < frame->n_vectors)
     139           0 :     vlib_node_increment_counter (vm, node->node_index,
     140             :                                  IPSEC_HANDOFF_ERROR_CONGESTION_DROP,
     141           0 :                                  frame->n_vectors - n_enq);
     142             : 
     143          44 :   return n_enq;
     144             : }
     145             : 
     146        2314 : VLIB_NODE_FN (esp4_encrypt_handoff) (vlib_main_t * vm,
     147             :                                      vlib_node_runtime_t * node,
     148             :                                      vlib_frame_t * from_frame)
     149             : {
     150          14 :   ipsec_main_t *im = &ipsec_main;
     151             : 
     152          14 :   return ipsec_handoff (vm, node, from_frame, im->esp4_enc_fq_index);
     153             : }
     154             : 
     155        2302 : VLIB_NODE_FN (esp6_encrypt_handoff) (vlib_main_t * vm,
     156             :                                      vlib_node_runtime_t * node,
     157             :                                      vlib_frame_t * from_frame)
     158             : {
     159           2 :   ipsec_main_t *im = &ipsec_main;
     160             : 
     161           2 :   return ipsec_handoff (vm, node, from_frame, im->esp6_enc_fq_index);
     162             : }
     163             : 
     164        2302 : VLIB_NODE_FN (esp4_encrypt_tun_handoff) (vlib_main_t * vm,
     165             :                                          vlib_node_runtime_t * node,
     166             :                                          vlib_frame_t * from_frame)
     167             : {
     168           2 :   ipsec_main_t *im = &ipsec_main;
     169             : 
     170           2 :   return ipsec_handoff (vm, node, from_frame, im->esp4_enc_tun_fq_index);
     171             : }
     172             : 
     173        2302 : VLIB_NODE_FN (esp6_encrypt_tun_handoff) (vlib_main_t * vm,
     174             :                                          vlib_node_runtime_t * node,
     175             :                                          vlib_frame_t * from_frame)
     176             : {
     177           2 :   ipsec_main_t *im = &ipsec_main;
     178             : 
     179           2 :   return ipsec_handoff (vm, node, from_frame, im->esp6_enc_tun_fq_index);
     180             : }
     181             : 
     182        2300 : VLIB_NODE_FN (esp_mpls_encrypt_tun_handoff)
     183             : (vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *from_frame)
     184             : {
     185           0 :   ipsec_main_t *im = &ipsec_main;
     186             : 
     187           0 :   return ipsec_handoff (vm, node, from_frame, im->esp_mpls_enc_tun_fq_index);
     188             : }
     189             : 
     190        2302 : VLIB_NODE_FN (esp4_decrypt_handoff) (vlib_main_t * vm,
     191             :                                      vlib_node_runtime_t * node,
     192             :                                      vlib_frame_t * from_frame)
     193             : {
     194           2 :   ipsec_main_t *im = &ipsec_main;
     195             : 
     196           2 :   return ipsec_handoff (vm, node, from_frame, im->esp4_dec_fq_index);
     197             : }
     198             : 
     199        2302 : VLIB_NODE_FN (esp6_decrypt_handoff) (vlib_main_t * vm,
     200             :                                      vlib_node_runtime_t * node,
     201             :                                      vlib_frame_t * from_frame)
     202             : {
     203           2 :   ipsec_main_t *im = &ipsec_main;
     204             : 
     205           2 :   return ipsec_handoff (vm, node, from_frame, im->esp6_dec_fq_index);
     206             : }
     207             : 
     208        2306 : VLIB_NODE_FN (esp4_decrypt_tun_handoff) (vlib_main_t * vm,
     209             :                                          vlib_node_runtime_t * node,
     210             :                                          vlib_frame_t * from_frame)
     211             : {
     212           6 :   ipsec_main_t *im = &ipsec_main;
     213             : 
     214           6 :   return ipsec_handoff (vm, node, from_frame, im->esp4_dec_tun_fq_index);
     215             : }
     216             : 
     217        2306 : VLIB_NODE_FN (esp6_decrypt_tun_handoff) (vlib_main_t * vm,
     218             :                                          vlib_node_runtime_t * node,
     219             :                                          vlib_frame_t * from_frame)
     220             : {
     221           6 :   ipsec_main_t *im = &ipsec_main;
     222             : 
     223           6 :   return ipsec_handoff (vm, node, from_frame, im->esp6_dec_tun_fq_index);
     224             : }
     225             : 
     226        2302 : VLIB_NODE_FN (ah4_encrypt_handoff) (vlib_main_t * vm,
     227             :                                     vlib_node_runtime_t * node,
     228             :                                     vlib_frame_t * from_frame)
     229             : {
     230           2 :   ipsec_main_t *im = &ipsec_main;
     231             : 
     232           2 :   return ipsec_handoff (vm, node, from_frame, im->ah4_enc_fq_index);
     233             : }
     234             : 
     235        2302 : VLIB_NODE_FN (ah6_encrypt_handoff) (vlib_main_t * vm,
     236             :                                     vlib_node_runtime_t * node,
     237             :                                     vlib_frame_t * from_frame)
     238             : {
     239           2 :   ipsec_main_t *im = &ipsec_main;
     240             : 
     241           2 :   return ipsec_handoff (vm, node, from_frame, im->ah6_enc_fq_index);
     242             : }
     243             : 
     244        2302 : VLIB_NODE_FN (ah4_decrypt_handoff) (vlib_main_t * vm,
     245             :                                     vlib_node_runtime_t * node,
     246             :                                     vlib_frame_t * from_frame)
     247             : {
     248           2 :   ipsec_main_t *im = &ipsec_main;
     249             : 
     250           2 :   return ipsec_handoff (vm, node, from_frame, im->ah4_dec_fq_index);
     251             : }
     252             : 
     253        2302 : VLIB_NODE_FN (ah6_decrypt_handoff) (vlib_main_t * vm,
     254             :                                     vlib_node_runtime_t * node,
     255             :                                     vlib_frame_t * from_frame)
     256             : {
     257           2 :   ipsec_main_t *im = &ipsec_main;
     258             : 
     259           2 :   return ipsec_handoff (vm, node, from_frame, im->ah6_dec_fq_index);
     260             : }
     261             : 
     262             : /* *INDENT-OFF* */
     263      183788 : VLIB_REGISTER_NODE (esp4_encrypt_handoff) = {
     264             :   .name = "esp4-encrypt-handoff",
     265             :   .vector_size = sizeof (u32),
     266             :   .format_trace = format_ipsec_handoff_trace,
     267             :   .type = VLIB_NODE_TYPE_INTERNAL,
     268             :   .n_errors = ARRAY_LEN(ipsec_handoff_error_strings),
     269             :   .error_strings = ipsec_handoff_error_strings,
     270             :   .n_next_nodes = 1,
     271             :   .next_nodes = {
     272             :     [0] = "error-drop",
     273             :   },
     274             : };
     275      183788 : VLIB_REGISTER_NODE (esp6_encrypt_handoff) = {
     276             :   .name = "esp6-encrypt-handoff",
     277             :   .vector_size = sizeof (u32),
     278             :   .format_trace = format_ipsec_handoff_trace,
     279             :   .type = VLIB_NODE_TYPE_INTERNAL,
     280             :   .n_errors = ARRAY_LEN(ipsec_handoff_error_strings),
     281             :   .error_strings = ipsec_handoff_error_strings,
     282             :   .n_next_nodes = 1,
     283             :   .next_nodes = {
     284             :     [0] = "error-drop",
     285             :   },
     286             : };
     287      183788 : VLIB_REGISTER_NODE (esp4_encrypt_tun_handoff) = {
     288             :   .name = "esp4-encrypt-tun-handoff",
     289             :   .vector_size = sizeof (u32),
     290             :   .format_trace = format_ipsec_handoff_trace,
     291             :   .type = VLIB_NODE_TYPE_INTERNAL,
     292             :   .n_errors = ARRAY_LEN(ipsec_handoff_error_strings),
     293             :   .error_strings = ipsec_handoff_error_strings,
     294             :   .n_next_nodes = 1,
     295             :   .next_nodes = {
     296             :     [0] = "error-drop",
     297             :   },
     298             : };
     299      183788 : VLIB_REGISTER_NODE (esp6_encrypt_tun_handoff) = {
     300             :   .name = "esp6-encrypt-tun-handoff",
     301             :   .vector_size = sizeof (u32),
     302             :   .format_trace = format_ipsec_handoff_trace,
     303             :   .type = VLIB_NODE_TYPE_INTERNAL,
     304             :   .n_errors = ARRAY_LEN(ipsec_handoff_error_strings),
     305             :   .error_strings = ipsec_handoff_error_strings,
     306             :   .n_next_nodes = 1,
     307             :   .next_nodes = {
     308             :     [0] = "error-drop",
     309             :   },
     310             : };
     311      183788 : VLIB_REGISTER_NODE (esp_mpls_encrypt_tun_handoff) = {
     312             :   .name = "esp-mpls-encrypt-tun-handoff",
     313             :   .vector_size = sizeof (u32),
     314             :   .format_trace = format_ipsec_handoff_trace,
     315             :   .type = VLIB_NODE_TYPE_INTERNAL,
     316             :   .n_errors = ARRAY_LEN(ipsec_handoff_error_strings),
     317             :   .error_strings = ipsec_handoff_error_strings,
     318             :   .n_next_nodes = 1,
     319             :   .next_nodes = {
     320             :     [0] = "error-drop",
     321             :   },
     322             : };
     323      183788 : VLIB_REGISTER_NODE (esp4_decrypt_handoff) = {
     324             :   .name = "esp4-decrypt-handoff",
     325             :   .vector_size = sizeof (u32),
     326             :   .format_trace = format_ipsec_handoff_trace,
     327             :   .type = VLIB_NODE_TYPE_INTERNAL,
     328             :   .n_errors = ARRAY_LEN(ipsec_handoff_error_strings),
     329             :   .error_strings = ipsec_handoff_error_strings,
     330             :   .n_next_nodes = 1,
     331             :   .next_nodes = {
     332             :     [0] = "error-drop",
     333             :   },
     334             : };
     335      183788 : VLIB_REGISTER_NODE (esp6_decrypt_handoff) = {
     336             :   .name = "esp6-decrypt-handoff",
     337             :   .vector_size = sizeof (u32),
     338             :   .format_trace = format_ipsec_handoff_trace,
     339             :   .type = VLIB_NODE_TYPE_INTERNAL,
     340             :   .n_errors = ARRAY_LEN(ipsec_handoff_error_strings),
     341             :   .error_strings = ipsec_handoff_error_strings,
     342             :   .n_next_nodes = 1,
     343             :   .next_nodes = {
     344             :     [0] = "error-drop",
     345             :   },
     346             : };
     347      183788 : VLIB_REGISTER_NODE (esp4_decrypt_tun_handoff) = {
     348             :   .name = "esp4-decrypt-tun-handoff",
     349             :   .vector_size = sizeof (u32),
     350             :   .format_trace = format_ipsec_handoff_trace,
     351             :   .type = VLIB_NODE_TYPE_INTERNAL,
     352             :   .n_errors = ARRAY_LEN(ipsec_handoff_error_strings),
     353             :   .error_strings = ipsec_handoff_error_strings,
     354             :   .n_next_nodes = 1,
     355             :   .next_nodes = {
     356             :     [0] = "error-drop",
     357             :   },
     358             : };
     359      183788 : VLIB_REGISTER_NODE (esp6_decrypt_tun_handoff) = {
     360             :   .name = "esp6-decrypt-tun-handoff",
     361             :   .vector_size = sizeof (u32),
     362             :   .format_trace = format_ipsec_handoff_trace,
     363             :   .type = VLIB_NODE_TYPE_INTERNAL,
     364             :   .n_errors = ARRAY_LEN(ipsec_handoff_error_strings),
     365             :   .error_strings = ipsec_handoff_error_strings,
     366             :   .n_next_nodes = 1,
     367             :   .next_nodes = {
     368             :     [0] = "error-drop",
     369             :   },
     370             : };
     371      183788 : VLIB_REGISTER_NODE (ah4_encrypt_handoff) = {
     372             :   .name = "ah4-encrypt-handoff",
     373             :   .vector_size = sizeof (u32),
     374             :   .format_trace = format_ipsec_handoff_trace,
     375             :   .type = VLIB_NODE_TYPE_INTERNAL,
     376             :   .n_errors = ARRAY_LEN(ipsec_handoff_error_strings),
     377             :   .error_strings = ipsec_handoff_error_strings,
     378             :   .n_next_nodes = 1,
     379             :   .next_nodes = {
     380             :     [0] = "error-drop",
     381             :   },
     382             : };
     383      183788 : VLIB_REGISTER_NODE (ah6_encrypt_handoff) = {
     384             :   .name = "ah6-encrypt-handoff",
     385             :   .vector_size = sizeof (u32),
     386             :   .format_trace = format_ipsec_handoff_trace,
     387             :   .type = VLIB_NODE_TYPE_INTERNAL,
     388             :   .n_errors = ARRAY_LEN(ipsec_handoff_error_strings),
     389             :   .error_strings = ipsec_handoff_error_strings,
     390             :   .n_next_nodes = 1,
     391             :   .next_nodes = {
     392             :     [0] = "error-drop",
     393             :   },
     394             : };
     395      183788 : VLIB_REGISTER_NODE (ah4_decrypt_handoff) = {
     396             :   .name = "ah4-decrypt-handoff",
     397             :   .vector_size = sizeof (u32),
     398             :   .format_trace = format_ipsec_handoff_trace,
     399             :   .type = VLIB_NODE_TYPE_INTERNAL,
     400             :   .n_errors = ARRAY_LEN(ipsec_handoff_error_strings),
     401             :   .error_strings = ipsec_handoff_error_strings,
     402             :   .n_next_nodes = 1,
     403             :   .next_nodes = {
     404             :     [0] = "error-drop",
     405             :   },
     406             : };
     407      183788 : VLIB_REGISTER_NODE (ah6_decrypt_handoff) = {
     408             :   .name = "ah6-decrypt-handoff",
     409             :   .vector_size = sizeof (u32),
     410             :   .format_trace = format_ipsec_handoff_trace,
     411             :   .type = VLIB_NODE_TYPE_INTERNAL,
     412             :   .n_errors = ARRAY_LEN(ipsec_handoff_error_strings),
     413             :   .error_strings = ipsec_handoff_error_strings,
     414             :   .n_next_nodes = 1,
     415             :   .next_nodes = {
     416             :     [0] = "error-drop",
     417             :   },
     418             : };
     419             : /* *INDENT-ON* */
     420             : 
     421             : /*
     422             :  * fd.io coding-style-patch-verification: ON
     423             :  *
     424             :  * Local Variables:
     425             :  * eval: (c-set-style "gnu")
     426             :  * End:
     427             :  */

Generated by: LCOV version 1.14