FD.io VPP  v19.08-27-gf4dcae4
Vector Packet Processing
ah_decrypt.c
Go to the documentation of this file.
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 
32 #define _(v, s) AH_DECRYPT_NEXT_##v,
33 typedef enum
34 {
36 #undef _
39 
40 #define foreach_ah_decrypt_error \
41  _ (RX_PKTS, "AH pkts received") \
42  _ (DECRYPTION_FAILED, "AH decryption failed") \
43  _ (INTEG_ERROR, "Integrity check failed") \
44  _ (NO_TAIL_SPACE, "not enough buffer tail space (dropped)") \
45  _ (DROP_FRAGMENTS, "IP fragments drop") \
46  _ (REPLAY, "SA replayed packet")
47 
48 typedef enum
49 {
50 #define _(sym,str) AH_DECRYPT_ERROR_##sym,
52 #undef _
55 
56 static char *ah_decrypt_error_strings[] = {
57 #define _(sym,string) string,
59 #undef _
60 };
61 
62 typedef struct
63 {
67 
68 /* packet trace format function */
69 static u8 *
70 format_ah_decrypt_trace (u8 * s, va_list * args)
71 {
72  CLIB_UNUSED (vlib_main_t * vm) = va_arg (*args, vlib_main_t *);
73  CLIB_UNUSED (vlib_node_t * node) = va_arg (*args, vlib_node_t *);
74  ah_decrypt_trace_t *t = va_arg (*args, ah_decrypt_trace_t *);
75 
76  s = format (s, "ah: integrity %U seq-num %d",
78  return s;
79 }
80 
81 typedef struct
82 {
83  union
84  {
85  struct
86  {
90  };
91 
92  struct
93  {
96  };
97  };
106 
109  vnet_crypto_op_t * ops, vlib_buffer_t * b[], u16 * nexts)
110 {
111  u32 n_fail, n_ops = vec_len (ops);
112  vnet_crypto_op_t *op = ops;
113 
114  if (n_ops == 0)
115  return;
116 
117  n_fail = n_ops - vnet_crypto_process_ops (vm, op, n_ops);
118 
119  while (n_fail)
120  {
121  ASSERT (op - ops < n_ops);
122 
123  if (op->status != VNET_CRYPTO_OP_STATUS_COMPLETED)
124  {
125  u32 bi = op->user_data;
126  b[bi]->error = node->errors[AH_DECRYPT_ERROR_INTEG_ERROR];
127  nexts[bi] = AH_DECRYPT_NEXT_DROP;
128  n_fail--;
129  }
130  op++;
131  }
132 }
133 
136  vlib_node_runtime_t * node, vlib_frame_t * from_frame,
137  int is_ip6)
138 {
139  u32 n_left, *from;
140  u32 thread_index = vm->thread_index;
141  u16 buffer_data_size = vlib_buffer_get_default_data_size (vm);
142  ah_decrypt_packet_data_t pkt_data[VLIB_FRAME_SIZE], *pd = pkt_data;
143  vlib_buffer_t *bufs[VLIB_FRAME_SIZE], **b = bufs;
144  u16 nexts[VLIB_FRAME_SIZE], *next = nexts;
145  ipsec_main_t *im = &ipsec_main;
146  ipsec_per_thread_data_t *ptd = vec_elt_at_index (im->ptd, thread_index);
147  from = vlib_frame_vector_args (from_frame);
148  n_left = from_frame->n_vectors;
149  ipsec_sa_t *sa0 = 0;
150  u32 current_sa_index = ~0, current_sa_bytes = 0, current_sa_pkts = 0;
151 
152  clib_memset (pkt_data, 0, VLIB_FRAME_SIZE * sizeof (pkt_data[0]));
153  vlib_get_buffers (vm, from, b, n_left);
154  clib_memset_u16 (nexts, -1, n_left);
156 
157  while (n_left > 0)
158  {
159  ah_header_t *ah0;
160  ip4_header_t *ih4;
161  ip6_header_t *ih6;
162 
163  if (vnet_buffer (b[0])->ipsec.sad_index != current_sa_index)
164  {
165  if (current_sa_index != ~0)
167  current_sa_index,
168  current_sa_pkts,
169  current_sa_bytes);
170  current_sa_index = vnet_buffer (b[0])->ipsec.sad_index;
171  sa0 = pool_elt_at_index (im->sad, current_sa_index);
172 
173  current_sa_bytes = current_sa_pkts = 0;
175  thread_index, current_sa_index);
176  }
177 
178  pd->sa_index = current_sa_index;
179 
180  ih4 = vlib_buffer_get_current (b[0]);
181  ih6 = vlib_buffer_get_current (b[0]);
182  pd->current_data = b[0]->current_data;
183 
184  if (is_ip6)
185  {
186  ip6_ext_header_t *prev = NULL;
187  ip6_ext_header_find_t (ih6, prev, ah0, IP_PROTOCOL_IPSEC_AH);
188  pd->ip_hdr_size = sizeof (ip6_header_t);
189  ASSERT ((u8 *) ah0 - (u8 *) ih6 == pd->ip_hdr_size);
190  }
191  else
192  {
193  if (ip4_is_fragment (ih4))
194  {
195  b[0]->error = node->errors[AH_DECRYPT_ERROR_DROP_FRAGMENTS];
196  next[0] = AH_DECRYPT_NEXT_DROP;
197  goto next;
198  }
199  pd->ip_hdr_size = ip4_header_bytes (ih4);
200  ah0 = (ah_header_t *) ((u8 *) ih4 + pd->ip_hdr_size);
201  }
202 
203  pd->seq = clib_host_to_net_u32 (ah0->seq_no);
204 
205  /* anti-replay check */
206  if (ipsec_sa_anti_replay_check (sa0, pd->seq))
207  {
208  b[0]->error = node->errors[AH_DECRYPT_ERROR_REPLAY];
209  next[0] = AH_DECRYPT_NEXT_DROP;
210  goto next;
211  }
212 
213  current_sa_bytes += b[0]->current_length;
214  current_sa_pkts += 1;
215 
216  pd->icv_size = sa0->integ_icv_size;
217  pd->nexthdr_cached = ah0->nexthdr;
218  if (PREDICT_TRUE (sa0->integ_alg != IPSEC_INTEG_ALG_NONE))
219  {
220  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  b[0]->error = node->errors[AH_DECRYPT_ERROR_NO_TAIL_SPACE];
225  next[0] = AH_DECRYPT_NEXT_DROP;
226  goto next;
227  }
228 
229  vnet_crypto_op_t *op;
231  vnet_crypto_op_init (op, sa0->integ_op_id);
232 
233  op->src = (u8 *) ih4;
234  op->len = b[0]->current_length;
235  op->digest = (u8 *) ih4 - pd->icv_size;
237  op->digest_len = pd->icv_size;
238  op->key_index = sa0->integ_key_index;
239  op->user_data = b - bufs;
240  if (ipsec_sa_is_set_USE_ESN (sa0))
241  {
242  u32 seq_hi = clib_host_to_net_u32 (sa0->seq_hi);
243 
244  op->len += sizeof (seq_hi);
245  clib_memcpy (op->src + b[0]->current_length, &seq_hi,
246  sizeof (seq_hi));
247  }
248  clib_memcpy (op->digest, ah0->auth_data, pd->icv_size);
249  clib_memset (ah0->auth_data, 0, pd->icv_size);
250 
251  if (is_ip6)
252  {
255  pd->hop_limit = ih6->hop_limit;
257  ih6->hop_limit = 0;
258  pd->nexthdr = ah0->nexthdr;
259  pd->icv_padding_len =
260  ah_calc_icv_padding_len (pd->icv_size, 1 /* is_ipv6 */ );
261  }
262  else
263  {
264  pd->tos = ih4->tos;
265  pd->ttl = ih4->ttl;
266  ih4->tos = 0;
267  ih4->ttl = 0;
268  ih4->checksum = 0;
269  pd->icv_padding_len =
270  ah_calc_icv_padding_len (pd->icv_size, 0 /* is_ipv6 */ );
271  }
272  }
273 
274  next:
275  n_left -= 1;
276  pd += 1;
277  next += 1;
278  b += 1;
279  }
280 
281  n_left = from_frame->n_vectors;
282  next = nexts;
283  pd = pkt_data;
284  b = bufs;
285 
286  vlib_node_increment_counter (vm, node->node_index, AH_DECRYPT_ERROR_RX_PKTS,
287  n_left);
289  current_sa_index, current_sa_pkts,
290  current_sa_bytes);
291 
292  ah_process_ops (vm, node, ptd->integ_ops, bufs, nexts);
293 
294  while (n_left > 0)
295  {
296  ip4_header_t *oh4;
297  ip6_header_t *oh6;
298 
299  if (next[0] < AH_DECRYPT_N_NEXT)
300  goto trace;
301 
302  sa0 = vec_elt_at_index (im->sad, pd->sa_index);
303 
304  if (PREDICT_TRUE (sa0->integ_alg != IPSEC_INTEG_ALG_NONE))
305  {
306  /* redo the anit-reply check. see esp_decrypt for details */
307  if (ipsec_sa_anti_replay_check (sa0, pd->seq))
308  {
309  b[0]->error = node->errors[AH_DECRYPT_ERROR_REPLAY];
310  next[0] = AH_DECRYPT_NEXT_DROP;
311  goto trace;
312  }
314  }
315 
316  u16 ah_hdr_len = sizeof (ah_header_t) + pd->icv_size
317  + pd->icv_padding_len;
318  vlib_buffer_advance (b[0], pd->ip_hdr_size + ah_hdr_len);
319  b[0]->flags |= VLIB_BUFFER_TOTAL_LENGTH_VALID;
320 
321  if (PREDICT_TRUE (ipsec_sa_is_set_IS_TUNNEL (sa0)))
322  { /* tunnel mode */
323  if (PREDICT_TRUE (pd->nexthdr_cached == IP_PROTOCOL_IP_IN_IP))
324  next[0] = AH_DECRYPT_NEXT_IP4_INPUT;
325  else if (pd->nexthdr_cached == IP_PROTOCOL_IPV6)
326  next[0] = AH_DECRYPT_NEXT_IP6_INPUT;
327  else
328  {
329  b[0]->error = node->errors[AH_DECRYPT_ERROR_DECRYPTION_FAILED];
330  next[0] = AH_DECRYPT_NEXT_DROP;
331  goto trace;
332  }
333  }
334  else
335  { /* transport mode */
336  if (is_ip6)
337  {
338  vlib_buffer_advance (b[0], -sizeof (ip6_header_t));
339  oh6 = vlib_buffer_get_current (b[0]);
340  if (ah_hdr_len >= sizeof (ip6_header_t))
341  clib_memcpy (oh6, b[0]->data + pd->current_data,
342  sizeof (ip6_header_t));
343  else
344  memmove (oh6, b[0]->data + pd->current_data,
345  sizeof (ip6_header_t));
346 
347  next[0] = AH_DECRYPT_NEXT_IP6_INPUT;
348  oh6->protocol = pd->nexthdr;
349  oh6->hop_limit = pd->hop_limit;
352  oh6->payload_length =
353  clib_host_to_net_u16 (vlib_buffer_length_in_chain
354  (vm, b[0]) - sizeof (ip6_header_t));
355  }
356  else
357  {
358  vlib_buffer_advance (b[0], -sizeof (ip4_header_t));
359  oh4 = vlib_buffer_get_current (b[0]);
360  if (ah_hdr_len >= sizeof (ip4_header_t))
361  clib_memcpy (oh4, b[0]->data + pd->current_data,
362  sizeof (ip4_header_t));
363  else
364  memmove (oh4, b[0]->data + pd->current_data,
365  sizeof (ip4_header_t));
366 
367  next[0] = AH_DECRYPT_NEXT_IP4_INPUT;
368  oh4->ip_version_and_header_length = 0x45;
369  oh4->fragment_id = 0;
370  oh4->flags_and_fragment_offset = 0;
371  oh4->protocol = pd->nexthdr_cached;
372  oh4->length =
373  clib_host_to_net_u16 (vlib_buffer_length_in_chain (vm, b[0]));
374  oh4->ttl = pd->ttl;
375  oh4->tos = pd->tos;
376  oh4->checksum = ip4_header_checksum (oh4);
377  }
378  }
379 
380  vnet_buffer (b[0])->sw_if_index[VLIB_TX] = (u32) ~ 0;
381  trace:
382  if (PREDICT_FALSE (b[0]->flags & VLIB_BUFFER_IS_TRACED))
383  {
384  sa0 = pool_elt_at_index (im->sad,
385  vnet_buffer (b[0])->ipsec.sad_index);
386  ah_decrypt_trace_t *tr =
387  vlib_add_trace (vm, node, b[0], sizeof (*tr));
388  tr->integ_alg = sa0->integ_alg;
389  tr->seq_num = pd->seq;
390  }
391 
392  n_left -= 1;
393  pd += 1;
394  next += 1;
395  b += 1;
396  }
397 
398  n_left = from_frame->n_vectors;
399  vlib_buffer_enqueue_to_next (vm, node, from, nexts, n_left);
400 
401  return n_left;
402 }
403 
405  vlib_node_runtime_t * node,
406  vlib_frame_t * from_frame)
407 {
408  return ah_decrypt_inline (vm, node, from_frame, 0 /* is_ip6 */ );
409 }
410 
411 /* *INDENT-OFF* */
413  .name = "ah4-decrypt",
414  .vector_size = sizeof (u32),
415  .format_trace = format_ah_decrypt_trace,
417 
418  .n_errors = ARRAY_LEN(ah_decrypt_error_strings),
419  .error_strings = ah_decrypt_error_strings,
420 
421  .n_next_nodes = AH_DECRYPT_N_NEXT,
422  .next_nodes = {
423 #define _(s,n) [AH_DECRYPT_NEXT_##s] = n,
425 #undef _
426  },
427 };
428 /* *INDENT-ON* */
429 
431  vlib_node_runtime_t * node,
432  vlib_frame_t * from_frame)
433 {
434  return ah_decrypt_inline (vm, node, from_frame, 1 /* is_ip6 */ );
435 }
436 
437 /* *INDENT-OFF* */
439  .name = "ah6-decrypt",
440  .vector_size = sizeof (u32),
441  .format_trace = format_ah_decrypt_trace,
443 
444  .n_errors = ARRAY_LEN(ah_decrypt_error_strings),
445  .error_strings = ah_decrypt_error_strings,
446 
447  .n_next_nodes = AH_DECRYPT_N_NEXT,
448  .next_nodes = {
449 #define _(s,n) [AH_DECRYPT_NEXT_##s] = n,
451 #undef _
452  },
453 };
454 /* *INDENT-ON* */
455 
456 /*
457  * fd.io coding-style-patch-verification: ON
458  *
459  * Local Variables:
460  * eval: (c-set-style "gnu")
461  * End:
462  */
u32 vnet_crypto_process_ops(vlib_main_t *vm, vnet_crypto_op_t ops[], u32 n_ops)
Definition: crypto.c:46
static char * ah_decrypt_error_strings[]
Definition: ah_decrypt.c:56
u32 flags
buffer flags: VLIB_BUFFER_FREE_LIST_INDEX_MASK: bits used to store free list index, VLIB_BUFFER_IS_TRACED: trace this buffer.
Definition: buffer.h:124
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:870
u32 flags
Definition: vhost_user.h:141
#define CLIB_UNUSED(x)
Definition: clib.h:82
ipsec_per_thread_data_t * ptd
Definition: ipsec.h:169
vnet_crypto_op_t * integ_ops
Definition: ipsec.h:89
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:112
ipsec_integ_alg_t
Definition: ipsec_sa.h:58
i16 current_data
signed offset in data[], pre_data[] that we are currently processing.
Definition: buffer.h:110
#define NULL
Definition: clib.h:58
#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:572
ipsec_integ_alg_t integ_alg
Definition: ipsec_sa.h:150
u32 thread_index
Definition: main.h:197
u16 current_length
Nbytes between current data and the end of this buffer.
Definition: buffer.h:113
static uword ah_decrypt_inline(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *from_frame, int is_ip6)
Definition: ah_decrypt.c:135
clib_memset(h->entries, 0, sizeof(h->entries[0])*entries)
u8 * format(u8 *s, const char *fmt,...)
Definition: format.c:424
u16 flags_and_fragment_offset
Definition: ip4_packet.h:151
u8 data[128]
Definition: ipsec.api:249
#define VLIB_NODE_FN(node)
Definition: node.h:201
vlib_error_t * errors
Vector of errors for this node.
Definition: node.h:468
vnet_crypto_op_id_t integ_op_id
Definition: ipsec_sa.h:129
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:366
ah_decrypt_error_t
Definition: ah_decrypt.c:48
unsigned char u8
Definition: types.h:56
#define vec_reset_length(v)
Reset vector length to zero NULL-pointer tolerant.
static int ip4_is_fragment(const ip4_header_t *i)
Definition: ip4_packet.h:213
u32 seq_hi
Definition: ipsec_sa.h:119
#define clib_memcpy(d, s, n)
Definition: string.h:180
vlib_node_registration_t ah6_decrypt_node
(constructor) VLIB_REGISTER_NODE (ah6_decrypt_node)
Definition: ah_decrypt.c:438
#define static_always_inline
Definition: clib.h:99
ipsec_main_t ipsec_main
Definition: ipsec.c:28
unsigned int seq_no
Definition: ah.h:27
#define always_inline
Definition: clib.h:98
u32 ip_version_traffic_class_and_flow_label
Definition: ah_decrypt.c:89
static_always_inline void vnet_crypto_op_init(vnet_crypto_op_t *op, vnet_crypto_op_id_t type)
Definition: crypto.h:221
#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
static u8 * format_ah_decrypt_trace(u8 *s, va_list *args)
Definition: ah_decrypt.c:70
unsigned char auth_data[0]
Definition: ah.h:28
#define VLIB_FRAME_SIZE
Definition: node.h:376
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
#define foreach_ah_decrypt_error
Definition: ah_decrypt.c:40
#define pool_elt_at_index(p, i)
Returns pointer to element at given index.
Definition: pool.h:514
uword user_data
Definition: crypto.h:143
static void ipsec_sa_anti_replay_advance(ipsec_sa_t *sa, u32 seq)
Definition: ipsec_sa.h:379
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
#define PREDICT_FALSE(x)
Definition: clib.h:111
static void vlib_prefetch_combined_counter(const vlib_combined_counter_main_t *cm, u32 thread_index, u32 index)
Pre-fetch a per-thread combined counter for the given object index.
Definition: counter.h:235
unsigned char nexthdr
Definition: ah.h:23
u32 node_index
Node index.
Definition: node.h:494
#define VNET_CRYPTO_OP_FLAG_HMAC_CHECK
Definition: crypto.h:132
static void vlib_node_increment_counter(vlib_main_t *vm, u32 node_index, u32 counter_index, u64 increment)
Definition: node_funcs.h:1150
static_always_inline u32 vlib_buffer_get_default_data_size(vlib_main_t *vm)
Definition: buffer_funcs.h:96
#define VLIB_REGISTER_NODE(x,...)
Definition: node.h:169
u16 n_vectors
Definition: node.h:395
vlib_main_t * vm
Definition: buffer.c:312
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:332
vlib_node_registration_t ah4_decrypt_node
(constructor) VLIB_REGISTER_NODE (ah4_decrypt_node)
Definition: ah_decrypt.c:412
#define ARRAY_LEN(x)
Definition: clib.h:62
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_decrypt.c:108
#define foreach_ah_decrypt_next
Definition: ah_decrypt.c:27
vlib_combined_counter_main_t ipsec_sa_counters
SA packet & bytes counters.
Definition: ipsec_sa.c:27
#define ASSERT(truth)
ip_dscp_t tos
Definition: ip4_packet.h:141
ipsec_sa_t * sad
Definition: ipsec.h:97
static int ipsec_sa_anti_replay_check(ipsec_sa_t *sa, u32 seq)
Definition: ipsec_sa.h:252
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:126
static void * vlib_add_trace(vlib_main_t *vm, vlib_node_runtime_t *r, vlib_buffer_t *b, u32 n_data_bytes)
Definition: trace_funcs.h:55
static_always_inline void clib_memset_u16(void *p, u16 val, uword count)
Definition: string.h:378
u32 ip_version_traffic_class_and_flow_label
Definition: ip6_packet.h:370
Definition: defs.h:47
u16 payload_length
Definition: ip6_packet.h:374
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
ah_decrypt_next_t
Definition: ah_decrypt.c:33
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:244
vnet_crypto_op_status_t status
Definition: crypto.h:129
#define vnet_buffer(b)
Definition: buffer.h:361
Definition: ah.h:21
#define ip6_ext_header_find_t(i, p, m, t)
Definition: ip6_packet.h:559
static int ip4_header_bytes(const ip4_header_t *i)
Definition: ip4_packet.h:235
u8 ip_version_and_header_length
Definition: ip4_packet.h:138
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:244
#define CLIB_CACHE_LINE_BYTES
Definition: cache.h:59
ipsec_integ_alg_t integ_alg
Definition: ah_decrypt.c:64
u8 integ_icv_size
Definition: ipsec_sa.h:116
static u16 ip4_header_checksum(ip4_header_t *i)
Definition: ip4_packet.h:247
signed short i16
Definition: types.h:46