LCOV - code coverage report
Current view: top level - vnet/ipsec - ah_decrypt.c (source / functions) Hit Total Coverage
Test: coverage-filtered.info Lines: 193 202 95.5 %
Date: 2023-07-05 22:20:52 Functions: 20 26 76.9 %

          Line data    Source code
       1             : /*
       2             :  * ah_decrypt.c : IPSec AH decrypt 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/vnet.h>
      19             : #include <vnet/api_errno.h>
      20             : #include <vnet/ip/ip.h>
      21             : 
      22             : #include <vnet/ipsec/ipsec.h>
      23             : #include <vnet/ipsec/esp.h>
      24             : #include <vnet/ipsec/ah.h>
      25             : #include <vnet/ipsec/ipsec_io.h>
      26             : 
      27             : #define foreach_ah_decrypt_next                 \
      28             :   _(DROP, "error-drop")                         \
      29             :   _(IP4_INPUT, "ip4-input")                     \
      30             :   _(IP6_INPUT, "ip6-input")                     \
      31             :   _(HANDOFF, "handoff")
      32             : 
      33             : #define _(v, s) AH_DECRYPT_NEXT_##v,
      34             : typedef enum
      35             : {
      36             :   foreach_ah_decrypt_next
      37             : #undef _
      38             :     AH_DECRYPT_N_NEXT,
      39             : } ah_decrypt_next_t;
      40             : 
      41             : typedef struct
      42             : {
      43             :   ipsec_integ_alg_t integ_alg;
      44             :   u32 seq_num;
      45             : } ah_decrypt_trace_t;
      46             : 
      47             : /* packet trace format function */
      48             : static u8 *
      49        3208 : format_ah_decrypt_trace (u8 * s, va_list * args)
      50             : {
      51        3208 :   CLIB_UNUSED (vlib_main_t * vm) = va_arg (*args, vlib_main_t *);
      52        3208 :   CLIB_UNUSED (vlib_node_t * node) = va_arg (*args, vlib_node_t *);
      53        3208 :   ah_decrypt_trace_t *t = va_arg (*args, ah_decrypt_trace_t *);
      54             : 
      55        3208 :   s = format (s, "ah: integrity %U seq-num %d",
      56        3208 :               format_ipsec_integ_alg, t->integ_alg, t->seq_num);
      57        3208 :   return s;
      58             : }
      59             : 
      60             : typedef struct
      61             : {
      62             :   union
      63             :   {
      64             :     struct
      65             :     {
      66             :       u8 hop_limit;
      67             :       u8 nexthdr;
      68             :       u32 ip_version_traffic_class_and_flow_label;
      69             :     };
      70             : 
      71             :     struct
      72             :     {
      73             :       u8 ttl;
      74             :       u8 tos;
      75             :     };
      76             :   };
      77             :   u32 sa_index;
      78             :   u32 seq;
      79             :   u32 seq_hi;
      80             :   u8 icv_padding_len;
      81             :   u8 icv_size;
      82             :   u8 ip_hdr_size;
      83             :   i16 current_data;
      84             :   u8 nexthdr_cached;
      85             : } ah_decrypt_packet_data_t;
      86             : 
      87             : static_always_inline void
      88         156 : ah_process_ops (vlib_main_t * vm, vlib_node_runtime_t * node,
      89             :                 vnet_crypto_op_t * ops, vlib_buffer_t * b[], u16 * nexts)
      90             : {
      91         156 :   u32 n_fail, n_ops = vec_len (ops);
      92         156 :   vnet_crypto_op_t *op = ops;
      93             : 
      94         156 :   if (n_ops == 0)
      95           7 :     return;
      96             : 
      97         149 :   n_fail = n_ops - vnet_crypto_process_ops (vm, op, n_ops);
      98             : 
      99         166 :   while (n_fail)
     100             :     {
     101          17 :       ASSERT (op - ops < n_ops);
     102             : 
     103          17 :       if (op->status != VNET_CRYPTO_OP_STATUS_COMPLETED)
     104             :         {
     105          17 :           u32 bi = op->user_data;
     106          17 :           ah_decrypt_set_next_index (
     107          17 :             b[bi], node, vm->thread_index, AH_DECRYPT_ERROR_INTEG_ERROR, bi,
     108          17 :             nexts, AH_DECRYPT_NEXT_DROP, vnet_buffer (b[bi])->ipsec.sad_index);
     109          17 :           n_fail--;
     110             :         }
     111          17 :       op++;
     112             :     }
     113             : }
     114             : 
     115             : always_inline uword
     116         156 : ah_decrypt_inline (vlib_main_t * vm,
     117             :                    vlib_node_runtime_t * node, vlib_frame_t * from_frame,
     118             :                    int is_ip6)
     119             : {
     120             :   u32 n_left, *from;
     121         156 :   u32 thread_index = vm->thread_index;
     122         156 :   u16 buffer_data_size = vlib_buffer_get_default_data_size (vm);
     123         156 :   ah_decrypt_packet_data_t pkt_data[VLIB_FRAME_SIZE], *pd = pkt_data;
     124         156 :   vlib_buffer_t *bufs[VLIB_FRAME_SIZE], **b = bufs;
     125         156 :   u16 nexts[VLIB_FRAME_SIZE], *next = nexts;
     126         156 :   ipsec_main_t *im = &ipsec_main;
     127         156 :   ipsec_per_thread_data_t *ptd = vec_elt_at_index (im->ptd, thread_index);
     128         156 :   from = vlib_frame_vector_args (from_frame);
     129         156 :   n_left = from_frame->n_vectors;
     130         156 :   ipsec_sa_t *sa0 = 0;
     131         156 :   u32 current_sa_index = ~0, current_sa_bytes = 0, current_sa_pkts = 0;
     132             : 
     133         156 :   clib_memset (pkt_data, 0, VLIB_FRAME_SIZE * sizeof (pkt_data[0]));
     134         156 :   vlib_get_buffers (vm, from, b, n_left);
     135         156 :   clib_memset_u16 (nexts, -1, n_left);
     136         156 :   vec_reset_length (ptd->integ_ops);
     137             : 
     138        4136 :   while (n_left > 0)
     139             :     {
     140             :       ah_header_t *ah0;
     141             :       ip4_header_t *ih4;
     142             :       ip6_header_t *ih6;
     143             : 
     144        3980 :       if (vnet_buffer (b[0])->ipsec.sad_index != current_sa_index)
     145             :         {
     146         156 :           if (current_sa_index != ~0)
     147           0 :             vlib_increment_combined_counter (&ipsec_sa_counters, thread_index,
     148             :                                              current_sa_index, current_sa_pkts,
     149             :                                              current_sa_bytes);
     150         156 :           current_sa_index = vnet_buffer (b[0])->ipsec.sad_index;
     151         156 :           sa0 = ipsec_sa_get (current_sa_index);
     152             : 
     153         156 :           current_sa_bytes = current_sa_pkts = 0;
     154         156 :           vlib_prefetch_combined_counter (&ipsec_sa_counters,
     155             :                                           thread_index, current_sa_index);
     156             :         }
     157             : 
     158        3980 :       if (PREDICT_FALSE ((u16) ~0 == sa0->thread_index))
     159             :         {
     160             :           /* this is the first packet to use this SA, claim the SA
     161             :            * for this thread. this could happen simultaneously on
     162             :            * another thread */
     163           2 :           clib_atomic_cmp_and_swap (&sa0->thread_index, ~0,
     164             :                                     ipsec_sa_assign_thread (thread_index));
     165             :         }
     166             : 
     167        3980 :       if (PREDICT_TRUE (thread_index != sa0->thread_index))
     168             :         {
     169          60 :           vnet_buffer (b[0])->ipsec.thread_index = sa0->thread_index;
     170          60 :           next[0] = AH_DECRYPT_NEXT_HANDOFF;
     171          60 :           goto next;
     172             :         }
     173             : 
     174        3920 :       pd->sa_index = current_sa_index;
     175             : 
     176        3920 :       ih4 = vlib_buffer_get_current (b[0]);
     177        3920 :       ih6 = vlib_buffer_get_current (b[0]);
     178        3920 :       pd->current_data = b[0]->current_data;
     179             : 
     180        3920 :       if (is_ip6)
     181             :         {
     182        1911 :           ip6_ext_header_t *prev = NULL;
     183             :           ah0 =
     184        1911 :             ip6_ext_header_find (vm, b[0], ih6, IP_PROTOCOL_IPSEC_AH, &prev);
     185        1911 :           pd->ip_hdr_size = sizeof (ip6_header_t);
     186        1911 :           ASSERT ((u8 *) ah0 - (u8 *) ih6 == pd->ip_hdr_size);
     187             :         }
     188             :       else
     189             :         {
     190        2009 :           if (ip4_is_fragment (ih4))
     191             :             {
     192           0 :               ah_decrypt_set_next_index (
     193             :                 b[0], node, vm->thread_index, AH_DECRYPT_ERROR_DROP_FRAGMENTS,
     194             :                 0, next, AH_DECRYPT_NEXT_DROP, current_sa_index);
     195           0 :               goto next;
     196             :             }
     197        2009 :           pd->ip_hdr_size = ip4_header_bytes (ih4);
     198        2009 :           ah0 = (ah_header_t *) ((u8 *) ih4 + pd->ip_hdr_size);
     199             :         }
     200             : 
     201        3920 :       pd->seq = clib_host_to_net_u32 (ah0->seq_no);
     202             : 
     203             :       /* anti-replay check */
     204        3920 :       if (ipsec_sa_anti_replay_and_sn_advance (sa0, pd->seq, ~0, false,
     205             :                                                &pd->seq_hi))
     206             :         {
     207          53 :           ah_decrypt_set_next_index (b[0], node, vm->thread_index,
     208             :                                      AH_DECRYPT_ERROR_REPLAY, 0, next,
     209             :                                      AH_DECRYPT_NEXT_DROP, current_sa_index);
     210          53 :           goto next;
     211             :         }
     212             : 
     213        3867 :       current_sa_bytes += b[0]->current_length;
     214        3867 :       current_sa_pkts += 1;
     215             : 
     216        3867 :       pd->icv_size = sa0->integ_icv_size;
     217        3867 :       pd->nexthdr_cached = ah0->nexthdr;
     218        3867 :       if (PREDICT_TRUE (sa0->integ_alg != IPSEC_INTEG_ALG_NONE))
     219             :         {
     220        3867 :           if (PREDICT_FALSE (ipsec_sa_is_set_USE_ESN (sa0) &&
     221             :                              pd->current_data + b[0]->current_length
     222             :                              + sizeof (u32) > buffer_data_size))
     223             :             {
     224           0 :               ah_decrypt_set_next_index (
     225             :                 b[0], node, vm->thread_index, AH_DECRYPT_ERROR_NO_TAIL_SPACE,
     226             :                 0, next, AH_DECRYPT_NEXT_DROP, current_sa_index);
     227           0 :               goto next;
     228             :             }
     229             : 
     230             :           vnet_crypto_op_t *op;
     231        3867 :           vec_add2_aligned (ptd->integ_ops, op, 1, CLIB_CACHE_LINE_BYTES);
     232        3867 :           vnet_crypto_op_init (op, sa0->integ_op_id);
     233             : 
     234        3867 :           op->src = (u8 *) ih4;
     235        3867 :           op->len = b[0]->current_length;
     236        3867 :           op->digest = (u8 *) ih4 - pd->icv_size;
     237        3867 :           op->flags = VNET_CRYPTO_OP_FLAG_HMAC_CHECK;
     238        3867 :           op->digest_len = pd->icv_size;
     239        3867 :           op->key_index = sa0->integ_key_index;
     240        3867 :           op->user_data = b - bufs;
     241        3867 :           if (ipsec_sa_is_set_USE_ESN (sa0))
     242             :             {
     243         816 :               u32 seq_hi = clib_host_to_net_u32 (pd->seq_hi);
     244             : 
     245         816 :               op->len += sizeof (seq_hi);
     246         816 :               clib_memcpy (op->src + b[0]->current_length, &seq_hi,
     247             :                            sizeof (seq_hi));
     248             :             }
     249        3867 :           clib_memcpy (op->digest, ah0->auth_data, pd->icv_size);
     250        3867 :           clib_memset (ah0->auth_data, 0, pd->icv_size);
     251             : 
     252        3867 :           if (is_ip6)
     253             :             {
     254        1911 :               pd->ip_version_traffic_class_and_flow_label =
     255        1911 :                 ih6->ip_version_traffic_class_and_flow_label;
     256        1911 :               pd->hop_limit = ih6->hop_limit;
     257        1911 :               ih6->ip_version_traffic_class_and_flow_label = 0x60;
     258        1911 :               ih6->hop_limit = 0;
     259        1911 :               pd->nexthdr = ah0->nexthdr;
     260        1911 :               pd->icv_padding_len =
     261        1911 :                 ah_calc_icv_padding_len (pd->icv_size, 1 /* is_ipv6 */ );
     262             :             }
     263             :           else
     264             :             {
     265        1956 :               pd->tos = ih4->tos;
     266        1956 :               pd->ttl = ih4->ttl;
     267        1956 :               ih4->tos = 0;
     268        1956 :               ih4->ttl = 0;
     269        1956 :               ih4->checksum = 0;
     270        1956 :               pd->icv_padding_len =
     271        1956 :                 ah_calc_icv_padding_len (pd->icv_size, 0 /* is_ipv6 */ );
     272             :             }
     273             :         }
     274             : 
     275           0 :     next:
     276        3980 :       n_left -= 1;
     277        3980 :       pd += 1;
     278        3980 :       next += 1;
     279        3980 :       b += 1;
     280             :     }
     281             : 
     282         156 :   n_left = from_frame->n_vectors;
     283         156 :   next = nexts;
     284         156 :   pd = pkt_data;
     285         156 :   b = bufs;
     286             : 
     287         156 :   vlib_node_increment_counter (vm, node->node_index, AH_DECRYPT_ERROR_RX_PKTS,
     288             :                                n_left);
     289         156 :   vlib_increment_combined_counter (&ipsec_sa_counters, thread_index,
     290             :                                    current_sa_index, current_sa_pkts,
     291             :                                    current_sa_bytes);
     292             : 
     293         156 :   ah_process_ops (vm, node, ptd->integ_ops, bufs, nexts);
     294             : 
     295        4136 :   while (n_left > 0)
     296             :     {
     297             :       ip4_header_t *oh4;
     298             :       ip6_header_t *oh6;
     299        3980 :       u64 n_lost = 0;
     300             : 
     301        3980 :       if (next[0] < AH_DECRYPT_N_NEXT)
     302         130 :         goto trace;
     303             : 
     304        3850 :       sa0 = ipsec_sa_get (pd->sa_index);
     305             : 
     306        3850 :       if (PREDICT_TRUE (sa0->integ_alg != IPSEC_INTEG_ALG_NONE))
     307             :         {
     308             :           /* redo the anti-reply check. see esp_decrypt for details */
     309        3850 :           if (ipsec_sa_anti_replay_and_sn_advance (sa0, pd->seq, pd->seq_hi,
     310             :                                                    true, NULL))
     311             :             {
     312           7 :               ah_decrypt_set_next_index (b[0], node, vm->thread_index,
     313             :                                          AH_DECRYPT_ERROR_REPLAY, 0, next,
     314             :                                          AH_DECRYPT_NEXT_DROP, pd->sa_index);
     315           7 :               goto trace;
     316             :             }
     317        3843 :           n_lost = ipsec_sa_anti_replay_advance (sa0, thread_index, pd->seq,
     318             :                                                  pd->seq_hi);
     319        3843 :           vlib_prefetch_simple_counter (
     320             :             &ipsec_sa_err_counters[IPSEC_SA_ERROR_LOST], thread_index,
     321             :             pd->sa_index);
     322             :         }
     323             : 
     324        3843 :       u16 ah_hdr_len = sizeof (ah_header_t) + pd->icv_size
     325        3843 :         + pd->icv_padding_len;
     326        3843 :       vlib_buffer_advance (b[0], pd->ip_hdr_size + ah_hdr_len);
     327        3843 :       b[0]->flags |= VLIB_BUFFER_TOTAL_LENGTH_VALID;
     328             : 
     329        3843 :       if (PREDICT_TRUE (ipsec_sa_is_set_IS_TUNNEL (sa0)))
     330             :         {                       /* tunnel mode */
     331        2104 :           if (PREDICT_TRUE (pd->nexthdr_cached == IP_PROTOCOL_IP_IN_IP))
     332         859 :             next[0] = AH_DECRYPT_NEXT_IP4_INPUT;
     333        1245 :           else if (pd->nexthdr_cached == IP_PROTOCOL_IPV6)
     334        1245 :             next[0] = AH_DECRYPT_NEXT_IP6_INPUT;
     335             :           else
     336             :             {
     337           0 :               ah_decrypt_set_next_index (b[0], node, vm->thread_index,
     338             :                                          AH_DECRYPT_ERROR_DECRYPTION_FAILED, 0,
     339             :                                          next, AH_DECRYPT_NEXT_DROP,
     340             :                                          pd->sa_index);
     341           0 :               goto trace;
     342             :             }
     343             :         }
     344             :       else
     345             :         {                       /* transport mode */
     346        1739 :           if (is_ip6)
     347             :             {
     348         666 :               vlib_buffer_advance (b[0], -sizeof (ip6_header_t));
     349         666 :               oh6 = vlib_buffer_get_current (b[0]);
     350         666 :               if (ah_hdr_len >= sizeof (ip6_header_t))
     351         204 :                 clib_memcpy (oh6, b[0]->data + pd->current_data,
     352             :                              sizeof (ip6_header_t));
     353             :               else
     354         462 :                 memmove (oh6, b[0]->data + pd->current_data,
     355             :                          sizeof (ip6_header_t));
     356             : 
     357         666 :               next[0] = AH_DECRYPT_NEXT_IP6_INPUT;
     358         666 :               oh6->protocol = pd->nexthdr;
     359         666 :               oh6->hop_limit = pd->hop_limit;
     360         666 :               oh6->ip_version_traffic_class_and_flow_label =
     361         666 :                 pd->ip_version_traffic_class_and_flow_label;
     362         666 :               oh6->payload_length =
     363         666 :                 clib_host_to_net_u16 (vlib_buffer_length_in_chain
     364         666 :                                       (vm, b[0]) - sizeof (ip6_header_t));
     365             :             }
     366             :           else
     367             :             {
     368        1073 :               vlib_buffer_advance (b[0], -sizeof (ip4_header_t));
     369        1073 :               oh4 = vlib_buffer_get_current (b[0]);
     370        1073 :               if (ah_hdr_len >= sizeof (ip4_header_t))
     371        1073 :                 clib_memcpy (oh4, b[0]->data + pd->current_data,
     372             :                              sizeof (ip4_header_t));
     373             :               else
     374           0 :                 memmove (oh4, b[0]->data + pd->current_data,
     375             :                          sizeof (ip4_header_t));
     376             : 
     377        1073 :               next[0] = AH_DECRYPT_NEXT_IP4_INPUT;
     378        1073 :               oh4->ip_version_and_header_length = 0x45;
     379        1073 :               oh4->fragment_id = 0;
     380        1073 :               oh4->flags_and_fragment_offset = 0;
     381        1073 :               oh4->protocol = pd->nexthdr_cached;
     382        1073 :               oh4->length =
     383        1073 :                 clib_host_to_net_u16 (vlib_buffer_length_in_chain (vm, b[0]));
     384        1073 :               oh4->ttl = pd->ttl;
     385        1073 :               oh4->tos = pd->tos;
     386        1073 :               oh4->checksum = ip4_header_checksum (oh4);
     387             :             }
     388             :         }
     389             : 
     390        3843 :       if (PREDICT_FALSE (n_lost))
     391         137 :         vlib_increment_simple_counter (
     392             :           &ipsec_sa_err_counters[IPSEC_SA_ERROR_LOST], thread_index,
     393             :           pd->sa_index, n_lost);
     394             : 
     395        3843 :       vnet_buffer (b[0])->sw_if_index[VLIB_TX] = (u32) ~ 0;
     396        3980 :     trace:
     397        3980 :       if (PREDICT_FALSE (b[0]->flags & VLIB_BUFFER_IS_TRACED))
     398             :         {
     399        3980 :           sa0 = ipsec_sa_get (vnet_buffer (b[0])->ipsec.sad_index);
     400             :           ah_decrypt_trace_t *tr =
     401        3980 :             vlib_add_trace (vm, node, b[0], sizeof (*tr));
     402        3980 :           tr->integ_alg = sa0->integ_alg;
     403        3980 :           tr->seq_num = pd->seq;
     404             :         }
     405             : 
     406        3980 :       n_left -= 1;
     407        3980 :       pd += 1;
     408        3980 :       next += 1;
     409        3980 :       b += 1;
     410             :     }
     411             : 
     412         156 :   n_left = from_frame->n_vectors;
     413         156 :   vlib_buffer_enqueue_to_next (vm, node, from, nexts, n_left);
     414             : 
     415         156 :   return n_left;
     416             : }
     417             : 
     418        2323 : VLIB_NODE_FN (ah4_decrypt_node) (vlib_main_t * vm,
     419             :                                  vlib_node_runtime_t * node,
     420             :                                  vlib_frame_t * from_frame)
     421             : {
     422          87 :   return ah_decrypt_inline (vm, node, from_frame, 0 /* is_ip6 */ );
     423             : }
     424             : 
     425             : /* *INDENT-OFF* */
     426      178120 : VLIB_REGISTER_NODE (ah4_decrypt_node) = {
     427             :   .name = "ah4-decrypt",
     428             :   .vector_size = sizeof (u32),
     429             :   .format_trace = format_ah_decrypt_trace,
     430             :   .type = VLIB_NODE_TYPE_INTERNAL,
     431             : 
     432             :   .n_errors = AH_DECRYPT_N_ERROR,
     433             :   .error_counters = ah_decrypt_error_counters,
     434             : 
     435             :   .n_next_nodes = AH_DECRYPT_N_NEXT,
     436             :   .next_nodes = {
     437             :     [AH_DECRYPT_NEXT_DROP] = "ip4-drop",
     438             :     [AH_DECRYPT_NEXT_IP4_INPUT] = "ip4-input-no-checksum",
     439             :     [AH_DECRYPT_NEXT_IP6_INPUT] = "ip6-input",
     440             :     [AH_DECRYPT_NEXT_HANDOFF] = "ah4-decrypt-handoff",
     441             :   },
     442             : };
     443             : /* *INDENT-ON* */
     444             : 
     445        2305 : VLIB_NODE_FN (ah6_decrypt_node) (vlib_main_t * vm,
     446             :                                  vlib_node_runtime_t * node,
     447             :                                  vlib_frame_t * from_frame)
     448             : {
     449          69 :   return ah_decrypt_inline (vm, node, from_frame, 1 /* is_ip6 */ );
     450             : }
     451             : 
     452             : /* *INDENT-OFF* */
     453      178120 : VLIB_REGISTER_NODE (ah6_decrypt_node) = {
     454             :   .name = "ah6-decrypt",
     455             :   .vector_size = sizeof (u32),
     456             :   .format_trace = format_ah_decrypt_trace,
     457             :   .type = VLIB_NODE_TYPE_INTERNAL,
     458             : 
     459             :   .n_errors = AH_DECRYPT_N_ERROR,
     460             :   .error_counters = ah_decrypt_error_counters,
     461             : 
     462             :   .n_next_nodes = AH_DECRYPT_N_NEXT,
     463             :   .next_nodes = {
     464             :     [AH_DECRYPT_NEXT_DROP] = "ip6-drop",
     465             :     [AH_DECRYPT_NEXT_IP4_INPUT] = "ip4-input-no-checksum",
     466             :     [AH_DECRYPT_NEXT_IP6_INPUT] = "ip6-input",
     467             :     [AH_DECRYPT_NEXT_HANDOFF] = "ah6-decrypt-handoff",
     468             :   },
     469             : };
     470             : /* *INDENT-ON* */
     471             : 
     472             : #ifndef CLIB_MARCH_VARIANT
     473             : 
     474             : static clib_error_t *
     475         559 : ah_decrypt_init (vlib_main_t *vm)
     476             : {
     477         559 :   ipsec_main_t *im = &ipsec_main;
     478             : 
     479         559 :   im->ah4_dec_fq_index =
     480         559 :     vlib_frame_queue_main_init (ah4_decrypt_node.index, 0);
     481         559 :   im->ah6_dec_fq_index =
     482         559 :     vlib_frame_queue_main_init (ah6_decrypt_node.index, 0);
     483             : 
     484         559 :   return 0;
     485             : }
     486             : 
     487       54879 : VLIB_INIT_FUNCTION (ah_decrypt_init);
     488             : 
     489             : #endif
     490             : 
     491             : /*
     492             :  * fd.io coding-style-patch-verification: ON
     493             :  *
     494             :  * Local Variables:
     495             :  * eval: (c-set-style "gnu")
     496             :  * End:
     497             :  */

Generated by: LCOV version 1.14