FD.io VPP  v20.09-64-g4f7b92f0a
Vector Packet Processing
ah_encrypt.c
Go to the documentation of this file.
1 /*
2  * ah_encrypt.c : IPSec AH 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/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 
26 #define foreach_ah_encrypt_next \
27  _ (DROP, "error-drop") \
28  _ (HANDOFF, "handoff") \
29  _ (INTERFACE_OUTPUT, "interface-output")
30 
31 
32 #define _(v, s) AH_ENCRYPT_NEXT_##v,
33 typedef enum
34 {
36 #undef _
39 
40 #define foreach_ah_encrypt_error \
41  _(RX_PKTS, "AH pkts received") \
42  _(CRYPTO_ENGINE_ERROR, "crypto engine error (packet dropped)") \
43  _(SEQ_CYCLED, "sequence number cycled")
44 
45 
46 typedef enum
47 {
48 #define _(sym,str) AH_ENCRYPT_ERROR_##sym,
50 #undef _
53 
54 static char *ah_encrypt_error_strings[] = {
55 #define _(sym,string) string,
57 #undef _
58 };
59 
60 typedef struct
61 {
68 
69 /* packet trace format function */
70 static u8 *
71 format_ah_encrypt_trace (u8 * s, va_list * args)
72 {
73  CLIB_UNUSED (vlib_main_t * vm) = va_arg (*args, vlib_main_t *);
74  CLIB_UNUSED (vlib_node_t * node) = va_arg (*args, vlib_node_t *);
75  ah_encrypt_trace_t *t = va_arg (*args, ah_encrypt_trace_t *);
76 
77  s = format (s, "ah: sa-index %d spi %u (0x%08x) seq %u:%u integrity %U",
78  t->sa_index, t->spi, t->spi, t->seq_hi, t->seq_lo,
80  return s;
81 }
82 
85  vnet_crypto_op_t * ops, vlib_buffer_t * b[], u16 * nexts)
86 {
87  u32 n_fail, n_ops = vec_len (ops);
88  vnet_crypto_op_t *op = ops;
89 
90  if (n_ops == 0)
91  return;
92 
93  n_fail = n_ops - vnet_crypto_process_ops (vm, op, n_ops);
94 
95  while (n_fail)
96  {
97  ASSERT (op - ops < n_ops);
98 
99  if (op->status != VNET_CRYPTO_OP_STATUS_COMPLETED)
100  {
101  u32 bi = op->user_data;
102  b[bi]->error = node->errors[AH_ENCRYPT_ERROR_CRYPTO_ENGINE_ERROR];
103  nexts[bi] = AH_ENCRYPT_NEXT_DROP;
104  n_fail--;
105  }
106  op++;
107  }
108 }
109 
110 typedef struct
111 {
112  union
113  {
114  struct
115  {
118  };
119 
120  struct
121  {
124  };
125  };
130 
134  int is_ip6)
135 {
136  u32 n_left, *from, thread_index;
137  int icv_size = 0;
138  from = vlib_frame_vector_args (frame);
139  n_left = frame->n_vectors;
140  ipsec_main_t *im = &ipsec_main;
141  ah_encrypt_packet_data_t pkt_data[VLIB_FRAME_SIZE], *pd = pkt_data;
142  thread_index = vm->thread_index;
143  vlib_buffer_t *bufs[VLIB_FRAME_SIZE], **b = bufs;
144  u16 nexts[VLIB_FRAME_SIZE], *next = nexts;
145  ipsec_per_thread_data_t *ptd = vec_elt_at_index (im->ptd, thread_index);
146  ipsec_sa_t *sa0 = 0;
147  ip4_and_ah_header_t *ih0, *oh0 = 0;
148  ip6_and_ah_header_t *ih6_0, *oh6_0 = 0;
149  u32 current_sa_index = ~0, current_sa_bytes = 0, current_sa_pkts = 0;
150  const static ip4_header_t ip4_hdr_template = {
152  .protocol = IP_PROTOCOL_IPSEC_AH,
153  };
154  const static ip6_header_t ip6_hdr_template = {
156  .protocol = IP_PROTOCOL_IPSEC_AH,
157  };
158 
159  clib_memset (pkt_data, 0, VLIB_FRAME_SIZE * sizeof (pkt_data[0]));
160  vlib_get_buffers (vm, from, b, n_left);
163 
164  while (n_left > 0)
165  {
166  u8 ip_hdr_size;
167  u8 next_hdr_type;
168 
169  if (vnet_buffer (b[0])->ipsec.sad_index != current_sa_index)
170  {
171  if (current_sa_index != ~0)
173  current_sa_index,
174  current_sa_pkts,
175  current_sa_bytes);
176  current_sa_index = vnet_buffer (b[0])->ipsec.sad_index;
177  sa0 = pool_elt_at_index (im->sad, current_sa_index);
178 
179  current_sa_bytes = current_sa_pkts = 0;
180  }
181 
182  pd->sa_index = current_sa_index;
183  next[0] = AH_ENCRYPT_NEXT_DROP;
184 
185  if (PREDICT_FALSE (~0 == sa0->encrypt_thread_index))
186  {
187  /* this is the first packet to use this SA, claim the SA
188  * for this thread. this could happen simultaneously on
189  * another thread */
191  ipsec_sa_assign_thread (thread_index));
192  }
193 
194  if (PREDICT_TRUE (thread_index != sa0->encrypt_thread_index))
195  {
196  next[0] = AH_ENCRYPT_NEXT_HANDOFF;
197  goto next;
198  }
199 
200  if (PREDICT_FALSE (esp_seq_advance (sa0)))
201  {
202  b[0]->error = node->errors[AH_ENCRYPT_ERROR_SEQ_CYCLED];
203  pd->skip = 1;
204  goto next;
205  }
206 
207  current_sa_pkts += 1;
208  current_sa_bytes += b[0]->current_length;
209 
210  ssize_t adv;
211  ih0 = vlib_buffer_get_current (b[0]);
212  pd->ttl = ih0->ip4.ttl;
213  pd->tos = ih0->ip4.tos;
214 
215  if (PREDICT_TRUE (ipsec_sa_is_set_IS_TUNNEL (sa0)))
216  {
217  if (is_ip6)
218  adv = -sizeof (ip6_and_ah_header_t);
219  else
220  adv = -sizeof (ip4_and_ah_header_t);
221  }
222  else
223  {
224  adv = -sizeof (ah_header_t);
225  }
226 
227  icv_size = sa0->integ_icv_size;
228  const u8 padding_len = ah_calc_icv_padding_len (icv_size, is_ip6);
229  adv -= padding_len;
230  /* transport mode save the eth header before it is overwritten */
231  if (PREDICT_FALSE (!ipsec_sa_is_set_IS_TUNNEL (sa0)))
232  {
233  const u32 l2_len = vnet_buffer (b[0])->ip.save_rewrite_length;
234  u8 *l2_hdr_in = (u8 *) vlib_buffer_get_current (b[0]) - l2_len;
235 
236  u8 *l2_hdr_out = l2_hdr_in + adv - icv_size;
237 
238  clib_memcpy_le32 (l2_hdr_out, l2_hdr_in, l2_len);
239  }
240 
241  vlib_buffer_advance (b[0], adv - icv_size);
242 
243  if (is_ip6)
244  {
245  ih6_0 = (ip6_and_ah_header_t *) ih0;
246  ip_hdr_size = sizeof (ip6_header_t);
247  oh6_0 = vlib_buffer_get_current (b[0]);
248  pd->current_data = b[0]->current_data;
249 
250  pd->hop_limit = ih6_0->ip6.hop_limit;
252  ih6_0->ip6.ip_version_traffic_class_and_flow_label;
253  if (PREDICT_TRUE (ipsec_sa_is_set_IS_TUNNEL (sa0)))
254  {
255  next_hdr_type = IP_PROTOCOL_IPV6;
256  }
257  else
258  {
259  next_hdr_type = ih6_0->ip6.protocol;
260  memmove (oh6_0, ih6_0, sizeof (ip6_header_t));
261  }
262 
263  clib_memcpy_fast (&oh6_0->ip6, &ip6_hdr_template, 8);
264  oh6_0->ah.reserved = 0;
265  oh6_0->ah.nexthdr = next_hdr_type;
266  oh6_0->ah.spi = clib_net_to_host_u32 (sa0->spi);
267  oh6_0->ah.seq_no = clib_net_to_host_u32 (sa0->seq);
268  oh6_0->ip6.payload_length =
269  clib_host_to_net_u16 (vlib_buffer_length_in_chain (vm, b[0]) -
270  sizeof (ip6_header_t));
271  oh6_0->ah.hdrlen =
272  (sizeof (ah_header_t) + icv_size + padding_len) / 4 - 2;
273  }
274  else
275  {
276  ip_hdr_size = sizeof (ip4_header_t);
277  oh0 = vlib_buffer_get_current (b[0]);
278  clib_memset (oh0, 0, sizeof (ip4_and_ah_header_t));
279  pd->current_data = b[0]->current_data;
280 
281  if (PREDICT_TRUE (ipsec_sa_is_set_IS_TUNNEL (sa0)))
282  {
283  next_hdr_type = IP_PROTOCOL_IP_IN_IP;
284  }
285  else
286  {
287  next_hdr_type = ih0->ip4.protocol;
288  memmove (oh0, ih0, sizeof (ip4_header_t));
289  }
290 
291  clib_memcpy_fast (&oh0->ip4, &ip4_hdr_template,
292  sizeof (ip4_header_t) -
293  sizeof (ip4_address_pair_t));
294 
295  oh0->ip4.length =
296  clib_host_to_net_u16 (vlib_buffer_length_in_chain (vm, b[0]));
297  oh0->ah.spi = clib_net_to_host_u32 (sa0->spi);
298  oh0->ah.seq_no = clib_net_to_host_u32 (sa0->seq);
299  oh0->ah.nexthdr = next_hdr_type;
300  oh0->ah.hdrlen =
301  (sizeof (ah_header_t) + icv_size + padding_len) / 4 - 2;
302  }
303 
304  if (PREDICT_TRUE (!is_ip6 && ipsec_sa_is_set_IS_TUNNEL (sa0) &&
305  !ipsec_sa_is_set_IS_TUNNEL_V6 (sa0)))
306  {
307  clib_memcpy_fast (&oh0->ip4.address_pair,
308  &sa0->ip4_hdr.address_pair,
309  sizeof (ip4_address_pair_t));
310 
311  next[0] = sa0->dpo.dpoi_next_node;
312  vnet_buffer (b[0])->ip.adj_index[VLIB_TX] = sa0->dpo.dpoi_index;
313  }
314  else if (is_ip6 && ipsec_sa_is_set_IS_TUNNEL (sa0) &&
315  ipsec_sa_is_set_IS_TUNNEL_V6 (sa0))
316  {
317  clib_memcpy_fast (&oh6_0->ip6.src_address,
318  &sa0->ip6_hdr.src_address,
319  sizeof (ip6_address_t) * 2);
320  next[0] = sa0->dpo.dpoi_next_node;
321  vnet_buffer (b[0])->ip.adj_index[VLIB_TX] = sa0->dpo.dpoi_index;
322  }
323 
324  if (PREDICT_TRUE (sa0->integ_op_id))
325  {
326  vnet_crypto_op_t *op;
328  vnet_crypto_op_init (op, sa0->integ_op_id);
329  op->src = vlib_buffer_get_current (b[0]);
330  op->len = b[0]->current_length;
331  op->digest = vlib_buffer_get_current (b[0]) + ip_hdr_size +
332  sizeof (ah_header_t);
333  clib_memset (op->digest, 0, icv_size);
334  op->digest_len = icv_size;
335  op->key_index = sa0->integ_key_index;
336  op->user_data = b - bufs;
337  if (ipsec_sa_is_set_USE_ESN (sa0))
338  {
339  u32 seq_hi = clib_host_to_net_u32 (sa0->seq_hi);
340 
341  op->len += sizeof (seq_hi);
342  clib_memcpy (op->src + b[0]->current_length, &seq_hi,
343  sizeof (seq_hi));
344  }
345  }
346 
347  if (!ipsec_sa_is_set_IS_TUNNEL (sa0))
348  {
349  next[0] = AH_ENCRYPT_NEXT_INTERFACE_OUTPUT;
350  vlib_buffer_advance (b[0], -sizeof (ethernet_header_t));
351  }
352 
353  next:
354  n_left -= 1;
355  next += 1;
356  pd += 1;
357  b += 1;
358  }
359 
360  n_left = frame->n_vectors;
361  next = nexts;
362  pd = pkt_data;
363  b = bufs;
364 
366  AH_ENCRYPT_ERROR_RX_PKTS, n_left);
368  current_sa_index, current_sa_pkts,
369  current_sa_bytes);
370 
371  ah_process_ops (vm, node, ptd->integ_ops, bufs, nexts);
372 
373  while (n_left)
374  {
375  if (pd->skip)
376  goto trace;
377 
378  if (is_ip6)
379  {
380  oh6_0 = (ip6_and_ah_header_t *) (b[0]->data + pd->current_data);
381  oh6_0->ip6.hop_limit = pd->hop_limit;
382  oh6_0->ip6.ip_version_traffic_class_and_flow_label =
384  }
385  else
386  {
387  oh0 = (ip4_and_ah_header_t *) (b[0]->data + pd->current_data);
388  oh0->ip4.ttl = pd->ttl;
389  oh0->ip4.tos = pd->tos;
390  oh0->ip4.checksum = ip4_header_checksum (&oh0->ip4);
391  }
392 
393  trace:
394  if (PREDICT_FALSE (b[0]->flags & VLIB_BUFFER_IS_TRACED))
395  {
396  sa0 = vec_elt_at_index (im->sad, pd->sa_index);
397  ah_encrypt_trace_t *tr =
398  vlib_add_trace (vm, node, b[0], sizeof (*tr));
399  tr->spi = sa0->spi;
400  tr->seq_lo = sa0->seq;
401  tr->seq_hi = sa0->seq_hi;
402  tr->integ_alg = sa0->integ_alg;
403  tr->sa_index = pd->sa_index;
404  }
405 
406  n_left -= 1;
407  next += 1;
408  pd += 1;
409  b += 1;
410  }
411 
412  n_left = frame->n_vectors;
413  vlib_buffer_enqueue_to_next (vm, node, from, nexts, n_left);
414 
415  return n_left;
416 }
417 
420  vlib_frame_t * from_frame)
421 {
422  return ah_encrypt_inline (vm, node, from_frame, 0 /* is_ip6 */ );
423 }
424 
425 /* *INDENT-OFF* */
427  .name = "ah4-encrypt",
428  .vector_size = sizeof (u32),
429  .format_trace = format_ah_encrypt_trace,
431 
432  .n_errors = ARRAY_LEN(ah_encrypt_error_strings),
433  .error_strings = ah_encrypt_error_strings,
434 
435  .n_next_nodes = AH_ENCRYPT_N_NEXT,
436  .next_nodes = {
437  [AH_ENCRYPT_NEXT_DROP] = "ip4-drop",
438  [AH_ENCRYPT_NEXT_HANDOFF] = "ah4-encrypt-handoff",
439  [AH_ENCRYPT_NEXT_INTERFACE_OUTPUT] = "interface-output",
440  },
441 };
442 /* *INDENT-ON* */
443 
446  vlib_frame_t * from_frame)
447 {
448  return ah_encrypt_inline (vm, node, from_frame, 1 /* is_ip6 */ );
449 }
450 
451 /* *INDENT-OFF* */
453  .name = "ah6-encrypt",
454  .vector_size = sizeof (u32),
455  .format_trace = format_ah_encrypt_trace,
457 
458  .n_errors = ARRAY_LEN(ah_encrypt_error_strings),
459  .error_strings = ah_encrypt_error_strings,
460 
461  .n_next_nodes = AH_ENCRYPT_N_NEXT,
462  .next_nodes = {
463  [AH_ENCRYPT_NEXT_DROP] = "ip6-drop",
464  [AH_ENCRYPT_NEXT_HANDOFF] = "ah6-encrypt-handoff",
465  [AH_ENCRYPT_NEXT_INTERFACE_OUTPUT] = "interface-output",
466  },
467 };
468 /* *INDENT-ON* */
469 
470 /*
471  * fd.io coding-style-patch-verification: ON
472  *
473  * Local Variables:
474  * eval: (c-set-style "gnu")
475  * End:
476  */
u32 vnet_crypto_process_ops(vlib_main_t *vm, vnet_crypto_op_t ops[], u32 n_ops)
Definition: crypto.c:99
u8 * format_ipsec_integ_alg(u8 *s, va_list *args)
Definition: ipsec_format.c:110
static vlib_cli_command_t trace
(constructor) VLIB_CLI_COMMAND (trace)
Definition: vlib_api_cli.c:899
#define CLIB_UNUSED(x)
Definition: clib.h:87
ipsec_per_thread_data_t * ptd
Definition: ipsec.h:185
vnet_crypto_op_t * integ_ops
Definition: ipsec.h:96
vl_api_wireguard_peer_flags_t flags
Definition: wireguard.api:103
static void vlib_increment_combined_counter(vlib_combined_counter_main_t *cm, u32 thread_index, u32 index, u64 n_packets, u64 n_bytes)
Increment a combined counter.
Definition: counter.h:220
#define PREDICT_TRUE(x)
Definition: clib.h:121
ipsec_integ_alg_t
Definition: ipsec_sa.h:59
i16 current_data
signed offset in data[], pre_data[] that we are currently processing.
Definition: buffer.h:110
#define clib_memcpy_fast(a, b, c)
Definition: string.h:81
clib_memset(h->entries, 0, sizeof(h->entries[0]) *entries)
static u32 ipsec_sa_assign_thread(u32 thread_id)
Definition: ipsec_sa.h:490
#define vec_add2_aligned(V, P, N, A)
Add N elements to end of vector V, return pointer to new elements in P.
Definition: vec.h:642
ipsec_integ_alg_t integ_alg
Definition: ipsec_sa.h:171
u32 thread_index
Definition: main.h:249
u16 current_length
Nbytes between current data and the end of this buffer.
Definition: buffer.h:113
vnet_crypto_op_t * crypto_ops
Definition: ipsec.h:95
vlib_node_registration_t ah6_encrypt_node
(constructor) VLIB_REGISTER_NODE (ah6_encrypt_node)
Definition: ah_encrypt.c:452
vlib_main_t * vm
Definition: in2out_ed.c:1582
u8 * format(u8 *s, const char *fmt,...)
Definition: format.c:424
#define VLIB_NODE_FN(node)
Definition: node.h:202
vlib_error_t * errors
Vector of errors for this node.
Definition: node.h:469
vnet_crypto_op_id_t integ_op_id
Definition: ipsec_sa.h:139
static uword vlib_buffer_length_in_chain(vlib_main_t *vm, vlib_buffer_t *b)
Get length in bytes of the buffer chain.
Definition: buffer_funcs.h:402
ip6_address_t src_address
Definition: ip6_packet.h:310
static uword ah_encrypt_inline(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame, int is_ip6)
Definition: ah_encrypt.c:132
unsigned char u8
Definition: types.h:56
u8 data[128]
Definition: ipsec_types.api:89
#define vec_reset_length(v)
Reset vector length to zero NULL-pointer tolerant.
u32 seq_hi
Definition: ipsec_sa.h:122
#define clib_memcpy(d, s, n)
Definition: string.h:180
static int esp_seq_advance(ipsec_sa_t *sa)
Definition: esp.h:84
#define static_always_inline
Definition: clib.h:108
ipsec_main_t ipsec_main
Definition: ipsec.c:28
static_always_inline void vnet_crypto_op_init(vnet_crypto_op_t *op, vnet_crypto_op_id_t type)
Definition: crypto.h:496
#define vec_elt_at_index(v, i)
Get vector value at index i checking that i is in bounds.
unsigned int u32
Definition: types.h:88
#define VLIB_FRAME_SIZE
Definition: node.h:377
ipsec_integ_alg_t integ_alg
Definition: ah_encrypt.c:66
bool is_ip6
Definition: ip.api:43
static u8 ah_calc_icv_padding_len(u8 icv_size, int is_ipv6)
Definition: ah.h:47
vl_api_fib_path_type_t type
Definition: fib_types.api:123
vlib_error_t error
Error code for buffers to be enqueued to error handler.
Definition: buffer.h:136
u32 encrypt_thread_index
Definition: ipsec_sa.h:118
#define pool_elt_at_index(p, i)
Returns pointer to element at given index.
Definition: pool.h:534
uword user_data
Definition: crypto.h:233
unsigned short u16
Definition: types.h:57
static void * vlib_buffer_get_current(vlib_buffer_t *b)
Get pointer to current data to process.
Definition: buffer.h:229
ip4_address_pair_t address_pair
Definition: ip4_packet.h:127
#define PREDICT_FALSE(x)
Definition: clib.h:120
#define always_inline
Definition: ipsec.h:28
ah_encrypt_next_t
Definition: ah_encrypt.c:33
vlib_node_registration_t ah4_encrypt_node
(constructor) VLIB_REGISTER_NODE (ah4_encrypt_node)
Definition: ah_encrypt.c:426
u32 node_index
Node index.
Definition: node.h:487
u32 ip_version_traffic_class_and_flow_label
Definition: ah_encrypt.c:117
static void vlib_node_increment_counter(vlib_main_t *vm, u32 node_index, u32 counter_index, u64 increment)
Definition: node_funcs.h:1231
static u8 * format_ah_encrypt_trace(u8 *s, va_list *args)
Definition: ah_encrypt.c:71
#define VLIB_REGISTER_NODE(x,...)
Definition: node.h:169
u16 n_vectors
Definition: node.h:396
static_always_inline void vlib_buffer_enqueue_to_next(vlib_main_t *vm, vlib_node_runtime_t *node, u32 *buffers, u16 *nexts, uword count)
Definition: buffer_node.h:339
static char * ah_encrypt_error_strings[]
Definition: ah_encrypt.c:54
#define ARRAY_LEN(x)
Definition: clib.h:67
vlib_main_t vlib_node_runtime_t * node
Definition: in2out_ed.c:1582
#define clib_atomic_cmp_and_swap(addr, old, new)
Definition: atomics.h:37
vlib_combined_counter_main_t ipsec_sa_counters
SA packet & bytes counters.
Definition: ipsec_sa.c:27
#define ASSERT(truth)
static_always_inline void ah_process_ops(vlib_main_t *vm, vlib_node_runtime_t *node, vnet_crypto_op_t *ops, vlib_buffer_t *b[], u16 *nexts)
Definition: ah_encrypt.c:84
#define foreach_ah_encrypt_error
Definition: ah_encrypt.c:40
ip6_header_t ip6_hdr
Definition: ipsec_sa.h:158
ipsec_sa_t * sad
Definition: ipsec.h:107
static void vlib_buffer_advance(vlib_buffer_t *b, word l)
Advance current data pointer by the supplied (signed!) amount.
Definition: buffer.h:248
vnet_crypto_key_index_t integ_key_index
Definition: ipsec_sa.h:129
u32 ip_version_traffic_class_and_flow_label
Definition: ip6_packet.h:297
Definition: defs.h:47
index_t dpoi_index
the index of objects of that type
Definition: dpo.h:186
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
vlib_main_t vlib_node_runtime_t vlib_frame_t * frame
Definition: in2out_ed.c:1583
VLIB buffer representation.
Definition: buffer.h:102
u64 uword
Definition: types.h:112
static void * vlib_frame_vector_args(vlib_frame_t *f)
Get pointer to frame vector data.
Definition: node_funcs.h:297
vnet_crypto_op_status_t status
Definition: crypto.h:235
#define vnet_buffer(b)
Definition: buffer.h:417
dpo_id_t dpo
Definition: ipsec_sa.h:126
ip4_header_t ip4_hdr
Definition: ipsec_sa.h:157
Definition: ah.h:21
ah_encrypt_error_t
Definition: ah_encrypt.c:46
#define foreach_ah_encrypt_next
Definition: ah_encrypt.c:26
void * vlib_add_trace(vlib_main_t *vm, vlib_node_runtime_t *r, vlib_buffer_t *b, u32 n_data_bytes)
Definition: trace.c:577
u16 dpoi_next_node
The next VLIB node to follow.
Definition: dpo.h:182
u8 ip_version_and_header_length
Definition: ip4_packet.h:93
static_always_inline void vlib_get_buffers(vlib_main_t *vm, u32 *bi, vlib_buffer_t **b, int count)
Translate array of buffer indices into buffer pointers.
Definition: buffer_funcs.h:280
#define CLIB_CACHE_LINE_BYTES
Definition: cache.h:59
u8 integ_icv_size
Definition: ipsec_sa.h:117
static u16 ip4_header_checksum(ip4_header_t *i)
Definition: ip4_packet.h:314
static_always_inline void clib_memcpy_le32(u8 *dst, u8 *src, u8 len)
Definition: string.h:289
signed short i16
Definition: types.h:46