FD.io VPP  v19.04.4-rc0-5-ge88582fac
Vector Packet Processing
esp_encrypt.c
Go to the documentation of this file.
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/vnet.h>
19 #include <vnet/api_errno.h>
20 #include <vnet/ip/ip.h>
21 #include <vnet/udp/udp.h>
22 
23 #include <vnet/crypto/crypto.h>
24 
25 #include <vnet/ipsec/ipsec.h>
26 #include <vnet/ipsec/esp.h>
27 
28 #define foreach_esp_encrypt_next \
29 _(DROP, "error-drop") \
30 _(IP4_LOOKUP, "ip4-lookup") \
31 _(IP6_LOOKUP, "ip6-lookup") \
32 _(INTERFACE_OUTPUT, "interface-output")
33 
34 #define _(v, s) ESP_ENCRYPT_NEXT_##v,
35 typedef enum
36 {
38 #undef _
41 
42 #define foreach_esp_encrypt_error \
43  _(RX_PKTS, "ESP pkts received") \
44  _(SEQ_CYCLED, "sequence number cycled (packet dropped)") \
45  _(CRYPTO_ENGINE_ERROR, "crypto engine error (packet dropped)") \
46  _(CHAINED_BUFFER, "chained buffers (packet dropped)") \
47  _(NO_TRAILER_SPACE, "no trailer space (packet dropped)")
48 
49 typedef enum
50 {
51 #define _(sym,str) ESP_ENCRYPT_ERROR_##sym,
53 #undef _
56 
57 static char *esp_encrypt_error_strings[] = {
58 #define _(sym,string) string,
60 #undef _
61 };
62 
63 typedef struct
64 {
72 
73 /* packet trace format function */
74 static u8 *
75 format_esp_encrypt_trace (u8 * s, va_list * args)
76 {
77  CLIB_UNUSED (vlib_main_t * vm) = va_arg (*args, vlib_main_t *);
78  CLIB_UNUSED (vlib_node_t * node) = va_arg (*args, vlib_node_t *);
79  esp_encrypt_trace_t *t = va_arg (*args, esp_encrypt_trace_t *);
80 
81  s = format (s, "esp: sa-index %d spi %u seq %u crypto %U integrity %U%s",
82  t->sa_index, t->spi, t->seq,
85  t->udp_encap ? " udp-encap-enabled" : "");
86  return s;
87 }
88 
89 /* pad packet in input buffer */
91 esp_add_footer_and_icv (vlib_buffer_t * b, u8 block_size, u8 icv_sz)
92 {
93  static const u8 pad_data[ESP_MAX_BLOCK_SIZE] = {
94  0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
95  0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x00, 0x00,
96  };
97 
98  u16 min_length = b->current_length + sizeof (esp_footer_t);
99  u16 new_length = round_pow2 (min_length, block_size);
100  u8 pad_bytes = new_length - min_length;
102  new_length - sizeof (esp_footer_t));
103 
104  if (pad_bytes)
105  clib_memcpy_fast ((u8 *) f - pad_bytes, pad_data, ESP_MAX_BLOCK_SIZE);
106 
107  f->pad_length = pad_bytes;
108  b->current_length = new_length + icv_sz;
109  return &f->next_header;
110 }
111 
113 esp_update_ip4_hdr (ip4_header_t * ip4, u16 len, int is_transport, int is_udp)
114 {
115  ip_csum_t sum;
116  u16 old_len;
117 
118  len = clib_net_to_host_u16 (len);
119  old_len = ip4->length;
120 
121  if (is_transport)
122  {
123  u8 prot = is_udp ? IP_PROTOCOL_UDP : IP_PROTOCOL_IPSEC_ESP;
124 
125  sum = ip_csum_update (ip4->checksum, ip4->protocol,
126  prot, ip4_header_t, protocol);
127  ip4->protocol = prot;
128 
129  sum = ip_csum_update (sum, old_len, len, ip4_header_t, length);
130  }
131  else
132  sum = ip_csum_update (ip4->checksum, old_len, len, ip4_header_t, length);
133 
134  ip4->length = len;
135  ip4->checksum = ip_csum_fold (sum);
136 }
137 
140 {
141  clib_memcpy_fast (udp, &sa->udp_hdr, sizeof (udp_header_t));
142  udp->length = clib_net_to_host_u16 (len);
143 }
144 
147 {
148 #ifdef CLIB_HAVE_VEC128
149  static const u8x16 ext_hdr_types = {
150  IP_PROTOCOL_IP6_HOP_BY_HOP_OPTIONS,
151  IP_PROTOCOL_IPV6_ROUTE,
152  IP_PROTOCOL_IPV6_FRAGMENTATION,
153  };
154 
155  return !u8x16_is_all_zero (ext_hdr_types == u8x16_splat (nexthdr));
156 #else
157  return ((nexthdr ^ IP_PROTOCOL_IP6_HOP_BY_HOP_OPTIONS) |
158  (nexthdr ^ IP_PROTOCOL_IPV6_ROUTE) |
159  (nexthdr ^ IP_PROTOCOL_IPV6_FRAGMENTATION) != 0);
160 #endif
161 }
162 
165 {
166  /* this code assumes that HbH, route and frag headers will be before
167  others, if that is not the case, they will end up encrypted */
168 
169  u8 len = sizeof (ip6_header_t);
170  ip6_ext_header_t *p;
171 
172  /* if next packet doesn't have ext header */
173  if (ext_hdr_is_pre_esp (ip6->protocol) == 0)
174  return len;
175 
176  p = (void *) (ip6 + 1);
177  len += ip6_ext_header_len (p);
178 
179  while (ext_hdr_is_pre_esp (p->next_hdr))
180  {
181  len += ip6_ext_header_len (p);
182  p = ip6_ext_next_header (p);
183  }
184 
185  return len;
186 }
187 
190  u16 * next, u16 buffer_data_size)
191 {
192  if (b->current_data + b->current_length <= buffer_data_size)
193  return 0;
194 
195  b->current_length -= buffer_data_size - b->current_data;
196  b->error = node->errors[ESP_ENCRYPT_ERROR_NO_TRAILER_SPACE];
197  next[0] = ESP_ENCRYPT_NEXT_DROP;
198  return 1;
199 }
200 
203  vnet_crypto_op_t * ops, vlib_buffer_t * b[], u16 * nexts)
204 {
205  u32 n_fail, n_ops = vec_len (ops);
206  vnet_crypto_op_t *op = ops;
207 
208  if (n_ops == 0)
209  return;
210 
211  n_fail = n_ops - vnet_crypto_process_ops (vm, op, n_ops);
212 
213  while (n_fail)
214  {
215  ASSERT (op - ops < n_ops);
216 
217  if (op->status != VNET_CRYPTO_OP_STATUS_COMPLETED)
218  {
219  u32 bi = op->user_data;
220  b[bi]->error = node->errors[ESP_ENCRYPT_ERROR_CRYPTO_ENGINE_ERROR];
221  nexts[bi] = ESP_ENCRYPT_NEXT_DROP;
222  n_fail--;
223  }
224  op++;
225  }
226 }
227 
230  vlib_frame_t * frame, int is_ip6, int is_tun)
231 {
232  ipsec_main_t *im = &ipsec_main;
234  u32 *from = vlib_frame_vector_args (frame);
235  u32 n_left = frame->n_vectors;
236  vlib_buffer_t *bufs[VLIB_FRAME_SIZE], **b = bufs;
237  u16 nexts[VLIB_FRAME_SIZE], *next = nexts;
238  u32 thread_index = vm->thread_index;
239  u16 buffer_data_size = vlib_buffer_get_default_data_size (vm);
240  u32 current_sa_index = ~0, current_sa_packets = 0;
241  u32 current_sa_bytes = 0, spi = 0;
242  u8 block_sz = 0, iv_sz = 0, icv_sz = 0;
243  ipsec_sa_t *sa0 = 0;
244 
245  vlib_get_buffers (vm, from, b, n_left);
248 
249  while (n_left > 0)
250  {
251  u32 sa_index0 = vnet_buffer (b[0])->ipsec.sad_index;
252  dpo_id_t *dpo;
253  esp_header_t *esp;
254  u8 *payload, *next_hdr_ptr;
255  u16 payload_len;
256  u32 hdr_len;
257 
258  if (n_left > 2)
259  {
260  u8 *p;
261  vlib_prefetch_buffer_header (b[2], LOAD);
262  p = vlib_buffer_get_current (b[1]);
266  }
267 
268  if (is_tun)
269  {
270  /* we are on a ipsec tunnel's feature arc */
271  u32 next0;
272  sa_index0 = *(u32 *) vnet_feature_next_with_data (&next0, b[0],
273  sizeof
274  (sa_index0));
275  next[0] = next0;
276  }
277  else
278  sa_index0 = vnet_buffer (b[0])->ipsec.sad_index;
279 
280  if (sa_index0 != current_sa_index)
281  {
282  sa0 = pool_elt_at_index (im->sad, sa_index0);
283  current_sa_index = sa_index0;
285  sa_index0, current_sa_packets,
286  current_sa_bytes);
287  current_sa_packets = current_sa_bytes = 0;
288  spi = clib_net_to_host_u32 (sa0->spi);
289  block_sz = sa0->crypto_block_size;
290  icv_sz = sa0->integ_icv_size;
291  iv_sz = sa0->crypto_iv_size;
292  }
293 
294  if (vlib_buffer_chain_linearize (vm, b[0]) != 1)
295  {
296  b[0]->error = node->errors[ESP_ENCRYPT_ERROR_CHAINED_BUFFER];
297  next[0] = ESP_ENCRYPT_NEXT_DROP;
298  goto trace;
299  }
300 
301  if (PREDICT_FALSE (esp_seq_advance (sa0)))
302  {
303  b[0]->error = node->errors[ESP_ENCRYPT_ERROR_SEQ_CYCLED];
304  next[0] = ESP_ENCRYPT_NEXT_DROP;
305  goto trace;
306  }
307 
308  /* space for IV */
309  hdr_len = iv_sz;
310 
311  if (ipsec_sa_is_set_IS_TUNNEL (sa0))
312  {
313  payload = vlib_buffer_get_current (b[0]);
314  next_hdr_ptr = esp_add_footer_and_icv (b[0], block_sz, icv_sz);
315  payload_len = b[0]->current_length;
316 
317  if (esp_trailer_icv_overflow (node, b[0], next, buffer_data_size))
318  goto trace;
319 
320  /* ESP header */
321  hdr_len += sizeof (*esp);
322  esp = (esp_header_t *) (payload - hdr_len);
323 
324  /* optional UDP header */
325  if (ipsec_sa_is_set_UDP_ENCAP (sa0))
326  {
327  hdr_len += sizeof (udp_header_t);
328  esp_fill_udp_hdr (sa0, (udp_header_t *) (payload - hdr_len),
329  payload_len + hdr_len);
330  }
331 
332  /* IP header */
333  if (ipsec_sa_is_set_IS_TUNNEL_V6 (sa0))
334  {
335  ip6_header_t *ip6;
336  u16 len = sizeof (ip6_header_t);
337  hdr_len += len;
338  ip6 = (ip6_header_t *) (payload - hdr_len);
339  clib_memcpy_fast (ip6, &sa0->ip6_hdr, len);
340  *next_hdr_ptr = (is_ip6 ?
341  IP_PROTOCOL_IPV6 : IP_PROTOCOL_IP_IN_IP);
342  len = payload_len + hdr_len - len;
343  ip6->payload_length = clib_net_to_host_u16 (len);
344  }
345  else
346  {
347  ip4_header_t *ip4;
348  u16 len = sizeof (ip4_header_t);
349  hdr_len += len;
350  ip4 = (ip4_header_t *) (payload - hdr_len);
351  clib_memcpy_fast (ip4, &sa0->ip4_hdr, len);
352  *next_hdr_ptr = (is_ip6 ?
353  IP_PROTOCOL_IPV6 : IP_PROTOCOL_IP_IN_IP);
354  len = payload_len + hdr_len;
355  esp_update_ip4_hdr (ip4, len, /* is_transport */ 0, 0);
356  }
357 
358  dpo = sa0->dpo + IPSEC_PROTOCOL_ESP;
359  if (!is_tun)
360  {
361  next[0] = dpo->dpoi_next_node;
362  vnet_buffer (b[0])->ip.adj_index[VLIB_TX] = dpo->dpoi_index;
363  }
364  }
365  else /* transport mode */
366  {
367  u8 *l2_hdr, l2_len, *ip_hdr, ip_len;
368  udp_header_t *udp = 0;
369  u8 *old_ip_hdr = vlib_buffer_get_current (b[0]);
370 
371  ip_len = is_ip6 ?
372  esp_get_ip6_hdr_len ((ip6_header_t *) old_ip_hdr) :
373  ip4_header_bytes ((ip4_header_t *) old_ip_hdr);
374 
375  vlib_buffer_advance (b[0], ip_len);
376  payload = vlib_buffer_get_current (b[0]);
377  next_hdr_ptr = esp_add_footer_and_icv (b[0], block_sz, icv_sz);
378  payload_len = b[0]->current_length;
379 
380  if (esp_trailer_icv_overflow (node, b[0], next, buffer_data_size))
381  goto trace;
382 
383  /* ESP header */
384  hdr_len += sizeof (*esp);
385  esp = (esp_header_t *) (payload - hdr_len);
386 
387  /* optional UDP header */
388  if (ipsec_sa_is_set_UDP_ENCAP (sa0))
389  {
390  hdr_len += sizeof (udp_header_t);
391  udp = (udp_header_t *) (payload - hdr_len);
392  }
393 
394  /* IP header */
395  hdr_len += ip_len;
396  ip_hdr = payload - hdr_len;
397 
398  /* L2 header */
399  l2_len = vnet_buffer (b[0])->ip.save_rewrite_length;
400  hdr_len += l2_len;
401  l2_hdr = payload - hdr_len;
402 
403  /* copy l2 and ip header */
404  clib_memcpy_le32 (l2_hdr, old_ip_hdr - l2_len, l2_len);
405  clib_memcpy_le64 (ip_hdr, old_ip_hdr, ip_len);
406 
407  if (is_ip6)
408  {
409  ip6_header_t *ip6 = (ip6_header_t *) (ip_hdr);
410  *next_hdr_ptr = ip6->protocol;
411  ip6->protocol = IP_PROTOCOL_IPSEC_ESP;
412  ip6->payload_length =
413  clib_host_to_net_u16 (payload_len + hdr_len - l2_len -
414  ip_len);
415  }
416  else
417  {
418  u16 len;
419  ip4_header_t *ip4 = (ip4_header_t *) (ip_hdr);
420  *next_hdr_ptr = ip4->protocol;
421  len = payload_len + hdr_len - l2_len;
422  if (udp)
423  {
424  esp_update_ip4_hdr (ip4, len, /* is_transport */ 1, 1);
425  esp_fill_udp_hdr (sa0, udp, len - ip_len);
426  }
427  else
428  esp_update_ip4_hdr (ip4, len, /* is_transport */ 1, 0);
429  }
430 
431  next[0] = ESP_ENCRYPT_NEXT_INTERFACE_OUTPUT;
432  }
433 
434  esp->spi = spi;
435  esp->seq = clib_net_to_host_u32 (sa0->seq);
436 
437  if (sa0->crypto_enc_op_id)
438  {
439  vnet_crypto_op_t *op;
442  op->iv = payload - iv_sz;
443  op->src = op->dst = payload;
444  op->key = sa0->crypto_key.data;
445  op->len = payload_len - icv_sz;
447  op->user_data = b - bufs;
448  op->salt = sa0->salt;
449 
450  if (ipsec_sa_is_set_IS_AEAD (sa0))
451  {
452  /*
453  * construct the AAD in a scratch space in front
454  * of the IP header.
455  */
456  op->aad = payload - hdr_len - sizeof (esp_aead_t);
457 
458  esp_aad_fill (op, esp, sa0);
459 
460  op->tag = payload + op->len;
461  op->tag_len = 16;
462  }
463  }
464 
465  if (sa0->integ_op_id)
466  {
467  vnet_crypto_op_t *op;
469  vnet_crypto_op_init (op, sa0->integ_op_id);
470  op->src = payload - iv_sz - sizeof (esp_header_t);
471  op->digest = payload + payload_len - icv_sz;
472  op->key = sa0->integ_key.data;
473  op->key_len = sa0->integ_key.len;
474  op->digest_len = icv_sz;
475  op->len = payload_len - icv_sz + iv_sz + sizeof (esp_header_t);
476  op->user_data = b - bufs;
477  if (ipsec_sa_is_set_USE_ESN (sa0))
478  {
479  u32 seq_hi = clib_net_to_host_u32 (sa0->seq_hi);
480  clib_memcpy_fast (op->digest, &seq_hi, sizeof (seq_hi));
481  op->len += sizeof (seq_hi);
482  }
483  }
484 
485  vlib_buffer_advance (b[0], 0LL - hdr_len);
486 
487  current_sa_packets += 1;
488  current_sa_bytes += payload_len;
489 
490  trace:
491  if (PREDICT_FALSE (b[0]->flags & VLIB_BUFFER_IS_TRACED))
492  {
493  esp_encrypt_trace_t *tr = vlib_add_trace (vm, node, b[0],
494  sizeof (*tr));
495  tr->sa_index = sa_index0;
496  tr->spi = sa0->spi;
497  tr->seq = sa0->seq - 1;
498  tr->udp_encap = ipsec_sa_is_set_UDP_ENCAP (sa0);
499  tr->crypto_alg = sa0->crypto_alg;
500  tr->integ_alg = sa0->integ_alg;
501  }
502  /* next */
503  n_left -= 1;
504  next += 1;
505  b += 1;
506  }
507 
509  current_sa_index, current_sa_packets,
510  current_sa_bytes);
511  esp_process_ops (vm, node, ptd->crypto_ops, bufs, nexts);
512  esp_process_ops (vm, node, ptd->integ_ops, bufs, nexts);
513 
515  ESP_ENCRYPT_ERROR_RX_PKTS, frame->n_vectors);
516 
517  vlib_buffer_enqueue_to_next (vm, node, from, nexts, frame->n_vectors);
518  return frame->n_vectors;
519 }
520 
522  vlib_node_runtime_t * node,
523  vlib_frame_t * from_frame)
524 {
525  return esp_encrypt_inline (vm, node, from_frame, 0 /* is_ip6 */ , 0);
526 }
527 
528 /* *INDENT-OFF* */
530  .name = "esp4-encrypt",
531  .vector_size = sizeof (u32),
532  .format_trace = format_esp_encrypt_trace,
533  .type = VLIB_NODE_TYPE_INTERNAL,
534 
536  .error_strings = esp_encrypt_error_strings,
537 
538  .n_next_nodes = ESP_ENCRYPT_N_NEXT,
539  .next_nodes = {
540 #define _(s,n) [ESP_ENCRYPT_NEXT_##s] = n,
542 #undef _
543  },
544 };
545 /* *INDENT-ON* */
546 
548  vlib_node_runtime_t * node,
549  vlib_frame_t * from_frame)
550 {
551  return esp_encrypt_inline (vm, node, from_frame, 1 /* is_ip6 */ , 0);
552 }
553 
554 /* *INDENT-OFF* */
556  .name = "esp6-encrypt",
557  .vector_size = sizeof (u32),
558  .format_trace = format_esp_encrypt_trace,
559  .type = VLIB_NODE_TYPE_INTERNAL,
560 
562  .error_strings = esp_encrypt_error_strings,
563 
564  .n_next_nodes = ESP_ENCRYPT_N_NEXT,
565  .next_nodes = {
566 #define _(s,n) [ESP_ENCRYPT_NEXT_##s] = n,
568 #undef _
569  },
570 };
571 /* *INDENT-ON* */
572 
574  vlib_node_runtime_t * node,
575  vlib_frame_t * from_frame)
576 {
577  return esp_encrypt_inline (vm, node, from_frame, 0 /* is_ip6 */ , 1);
578 }
579 
580 /* *INDENT-OFF* */
582  .name = "esp4-encrypt-tun",
583  .vector_size = sizeof (u32),
584  .format_trace = format_esp_encrypt_trace,
585  .type = VLIB_NODE_TYPE_INTERNAL,
586 
588  .error_strings = esp_encrypt_error_strings,
589 
590  .n_next_nodes = 1,
591  .next_nodes = {
592  [ESP_ENCRYPT_NEXT_DROP] = "ip4-drop",
593  },
594 };
595 
596 VNET_FEATURE_INIT (esp4_encrypt_tun_feat_node, static) =
597 {
598  .arc_name = "ip4-output",
599  .node_name = "esp4-encrypt-tun",
600  .runs_before = VNET_FEATURES ("adj-midchain-tx"),
601 };
602 /* *INDENT-ON* */
603 
605  vlib_node_runtime_t * node,
606  vlib_frame_t * from_frame)
607 {
608  return esp_encrypt_inline (vm, node, from_frame, 1 /* is_ip6 */ , 1);
609 }
610 
611 /* *INDENT-OFF* */
613  .name = "esp6-encrypt-tun",
614  .vector_size = sizeof (u32),
615  .format_trace = format_esp_encrypt_trace,
616  .type = VLIB_NODE_TYPE_INTERNAL,
617 
619  .error_strings = esp_encrypt_error_strings,
620 
621  .n_next_nodes = 1,
622  .next_nodes = {
623  [ESP_ENCRYPT_NEXT_DROP] = "ip6-drop",
624  },
625 };
626 
627 VNET_FEATURE_INIT (esp6_encrypt_tun_feat_node, static) =
628 {
629  .arc_name = "ip6-output",
630  .node_name = "esp6-encrypt-tun",
631  .runs_before = VNET_FEATURES ("adj-midchain-tx"),
632 };
633 /* *INDENT-ON* */
634 
635 /*
636  * fd.io coding-style-patch-verification: ON
637  *
638  * Local Variables:
639  * eval: (c-set-style "gnu")
640  * End:
641  */
u32 vnet_crypto_process_ops(vlib_main_t *vm, vnet_crypto_op_t ops[], u32 n_ops)
Definition: crypto.c:46
u8 * format_ipsec_integ_alg(u8 *s, va_list *args)
Definition: ipsec_format.c:109
static_always_inline u8 esp_get_ip6_hdr_len(ip6_header_t *ip6)
Definition: esp_encrypt.c:164
static vlib_cli_command_t trace
(constructor) VLIB_CLI_COMMAND (trace)
Definition: vlib_api_cli.c:862
u32 flags
Definition: vhost_user.h:115
#define CLIB_UNUSED(x)
Definition: clib.h:82
ipsec_per_thread_data_t * ptd
Definition: ipsec.h:161
vnet_crypto_op_t * integ_ops
Definition: ipsec.h:87
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
static_always_inline void esp_process_ops(vlib_main_t *vm, vlib_node_runtime_t *node, vnet_crypto_op_t *ops, vlib_buffer_t *b[], u16 *nexts)
Definition: esp_encrypt.c:202
ipsec_integ_alg_t
Definition: ipsec_sa.h:60
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
#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_key_t crypto_key
Definition: ipsec_sa.h:151
ipsec_integ_alg_t integ_alg
Definition: ipsec_sa.h:153
u32 thread_index
Definition: main.h:197
u16 current_length
Nbytes between current data and the end of this buffer.
Definition: buffer.h:113
struct esp_aead_t_ esp_aead_t
AES GCM Additional Authentication data.
vnet_crypto_op_t * crypto_ops
Definition: ipsec.h:86
static void * ip6_ext_next_header(ip6_ext_header_t *ext_hdr)
Definition: ip6_packet.h:552
static u8 * format_esp_encrypt_trace(u8 *s, va_list *args)
Definition: esp_encrypt.c:75
ipsec_integ_alg_t integ_alg
Definition: esp_encrypt.c:70
uword ip_csum_t
Definition: ip_packet.h:181
u8 * format(u8 *s, const char *fmt,...)
Definition: format.c:424
ipsec_crypto_alg_t crypto_alg
Definition: esp_encrypt.c:69
#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:130
unsigned char u8
Definition: types.h:56
vlib_node_registration_t esp4_encrypt_tun_node
(constructor) VLIB_REGISTER_NODE (esp4_encrypt_tun_node)
Definition: esp_encrypt.c:581
#define vec_reset_length(v)
Reset vector length to zero NULL-pointer tolerant.
u32 seq_hi
Definition: ipsec_sa.h:123
static int esp_seq_advance(ipsec_sa_t *sa)
Definition: esp.h:80
#define static_always_inline
Definition: clib.h:99
static_always_inline int esp_trailer_icv_overflow(vlib_node_runtime_t *node, vlib_buffer_t *b, u16 *next, u16 buffer_data_size)
Definition: esp_encrypt.c:189
#define foreach_esp_encrypt_next
Definition: esp_encrypt.c:28
ipsec_main_t ipsec_main
Definition: ipsec.c:28
#define always_inline
Definition: clib.h:98
static_always_inline void esp_fill_udp_hdr(ipsec_sa_t *sa, udp_header_t *udp, u16 len)
Definition: esp_encrypt.c:139
#define vlib_prefetch_buffer_header(b, type)
Prefetch buffer metadata.
Definition: buffer.h:203
static_always_inline void vnet_crypto_op_init(vnet_crypto_op_t *op, vnet_crypto_op_id_t type)
Definition: crypto.h:190
#define vec_elt_at_index(v, i)
Get vector value at index i checking that i is in bounds.
static_always_inline u8 ext_hdr_is_pre_esp(u8 nexthdr)
Definition: esp_encrypt.c:146
u8 * format_ipsec_crypto_alg(u8 *s, va_list *args)
Definition: ipsec_format.c:77
unsigned int u32
Definition: types.h:88
static const u8 pad_data[]
Definition: ipsec.h:175
#define VLIB_FRAME_SIZE
Definition: node.h:376
vlib_error_t error
Error code for buffers to be enqueued to error handler.
Definition: buffer.h:136
esp_encrypt_error_t
Definition: esp_encrypt.c:49
vlib_node_registration_t esp6_encrypt_node
(constructor) VLIB_REGISTER_NODE (esp6_encrypt_node)
Definition: esp_encrypt.c:555
static u32 vlib_buffer_chain_linearize(vlib_main_t *vm, vlib_buffer_t *b)
The identity of a DPO is a combination of its type and its instance number/index of objects of that t...
Definition: dpo.h:168
static_always_inline void * vnet_feature_next_with_data(u32 *next0, vlib_buffer_t *b0, u32 n_data_bytes)
Definition: feature.h:282
#define pool_elt_at_index(p, i)
Returns pointer to element at given index.
Definition: pool.h:514
vlib_node_registration_t esp6_encrypt_tun_node
(constructor) VLIB_REGISTER_NODE (esp6_encrypt_tun_node)
Definition: esp_encrypt.c:612
static void esp_aad_fill(vnet_crypto_op_t *op, const esp_header_t *esp, const ipsec_sa_t *sa)
Definition: esp.h:135
uword user_data
Definition: crypto.h:125
u32 salt
Definition: ipsec_sa.h:163
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
u32 node_index
Node index.
Definition: node.h:494
static char * esp_encrypt_error_strings[]
Definition: esp_encrypt.c:57
static void vlib_node_increment_counter(vlib_main_t *vm, u32 node_index, u32 counter_index, u64 increment)
Definition: node_funcs.h:1150
u8 len
Definition: ip_types.api:49
#define ip6_ext_header_len(p)
Definition: ip6_packet.h:548
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
#define VNET_CRYPTO_OP_FLAG_INIT_IV
Definition: crypto.h:113
#define CLIB_PREFETCH(addr, size, type)
Definition: cache.h:80
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 esp4_encrypt_node
(constructor) VLIB_REGISTER_NODE (esp4_encrypt_node)
Definition: esp_encrypt.c:529
udp_header_t udp_hdr
Definition: ipsec_sa.h:142
#define ARRAY_LEN(x)
Definition: clib.h:62
esp_encrypt_next_t
Definition: esp_encrypt.c:35
static uword round_pow2(uword x, uword pow2)
Definition: clib.h:241
#define ESP_MAX_BLOCK_SIZE
Definition: esp.h:72
vlib_combined_counter_main_t ipsec_sa_counters
SA packet & bytes counters.
Definition: ipsec_sa.c:25
u8 data[IPSEC_KEY_MAX_LEN]
Definition: ipsec_sa.h:80
#define ASSERT(truth)
u32 spi
Definition: ipsec.api:270
static_always_inline u8 * esp_add_footer_and_icv(vlib_buffer_t *b, u8 block_size, u8 icv_sz)
Definition: esp_encrypt.c:91
ip6_header_t ip6_hdr
Definition: ipsec_sa.h:140
ipsec_sa_t * sad
Definition: ipsec.h:95
static_always_inline void esp_update_ip4_hdr(ip4_header_t *ip4, u16 len, int is_transport, int is_udp)
Definition: esp_encrypt.c:113
dpo_id_t dpo[IPSEC_N_PROTOCOLS]
Definition: ipsec_sa.h:132
u32 seq
Definition: esp.h:25
static void vlib_buffer_advance(vlib_buffer_t *b, word l)
Advance current data pointer by the supplied (signed!) amount.
Definition: buffer.h:248
u32 spi
Definition: esp.h:24
#define VNET_FEATURES(...)
Definition: feature.h:435
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:57
static_always_inline void clib_memcpy_le64(u8 *dst, u8 *src, u8 len)
Definition: string.h:283
Definition: defs.h:47
u16 payload_length
Definition: ip6_packet.h:376
index_t dpoi_index
the index of objects of that type
Definition: dpo.h:184
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
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
ipsec_crypto_alg_t
Definition: ipsec_sa.h:38
#define ip_csum_update(sum, old, new, type, field)
Definition: ip_packet.h:231
static uword esp_encrypt_inline(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame, int is_ip6, int is_tun)
Definition: esp_encrypt.c:229
vnet_crypto_op_id_t crypto_enc_op_id
Definition: ipsec_sa.h:128
vnet_crypto_op_status_t status
Definition: crypto.h:111
#define vnet_buffer(b)
Definition: buffer.h:369
ipsec_crypto_alg_t crypto_alg
Definition: ipsec_sa.h:150
ip4_header_t ip4_hdr
Definition: ipsec_sa.h:139
u8 crypto_block_size
Definition: ipsec_sa.h:119
u16 dpoi_next_node
The next VLIB node to follow.
Definition: dpo.h:180
static int ip4_header_bytes(const ip4_header_t *i)
Definition: ip4_packet.h:235
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
VNET_FEATURE_INIT(esp4_encrypt_tun_feat_node, static)
u8 crypto_iv_size
Definition: ipsec_sa.h:118
#define CLIB_CACHE_LINE_BYTES
Definition: cache.h:59
ipsec_key_t integ_key
Definition: ipsec_sa.h:154
#define foreach_esp_encrypt_error
Definition: esp_encrypt.c:42
u8 integ_icv_size
Definition: ipsec_sa.h:120
static u16 ip_csum_fold(ip_csum_t c)
Definition: ip_packet.h:237
static_always_inline void clib_memcpy_le32(u8 *dst, u8 *src, u8 len)
Definition: string.h:289
u8 protocol
Definition: ipsec.api:96