FD.io VPP  v20.05.1-5-g09f167997
Vector Packet Processing
ipsec_input.c
Go to the documentation of this file.
1 /*
2  * decap.c : IPSec tunnel decapsulation
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/feature/feature.h>
22 
23 #include <vnet/ipsec/ipsec.h>
24 #include <vnet/ipsec/esp.h>
25 #include <vnet/ipsec/ah.h>
26 #include <vnet/ipsec/ipsec_io.h>
27 
28 #define foreach_ipsec_input_error \
29 _(RX_PKTS, "IPSec pkts received") \
30 _(RX_POLICY_MATCH, "IPSec policy match") \
31 _(RX_POLICY_NO_MATCH, "IPSec policy not matched") \
32 _(RX_POLICY_BYPASS, "IPSec policy bypass") \
33 _(RX_POLICY_DISCARD, "IPSec policy discard")
34 
35 typedef enum
36 {
37 #define _(sym,str) IPSEC_INPUT_ERROR_##sym,
39 #undef _
42 
43 static char *ipsec_input_error_strings[] = {
44 #define _(sym,string) string,
46 #undef _
47 };
48 
49 typedef struct
50 {
58 
59 /* packet trace format function */
60 static u8 *
61 format_ipsec_input_trace (u8 * s, va_list * args)
62 {
63  CLIB_UNUSED (vlib_main_t * vm) = va_arg (*args, vlib_main_t *);
64  CLIB_UNUSED (vlib_node_t * node) = va_arg (*args, vlib_node_t *);
65  ipsec_input_trace_t *t = va_arg (*args, ipsec_input_trace_t *);
66 
67  s = format (s, "%U: sa_id %u spd %u policy %d spi %u (0x%08x) seq %u",
69  t->spd, t->policy_index, t->spi, t->spi, t->seq);
70 
71  return s;
72 }
73 
76  ipsec_spd_policy_type_t policy_type)
77 {
78  ipsec_main_t *im = &ipsec_main;
79  ipsec_policy_t *p;
80  u32 *i;
81 
82  vec_foreach (i, spd->policies[policy_type])
83  {
84  p = pool_elt_at_index (im->policies, *i);
85 
86  if (da < clib_net_to_host_u32 (p->laddr.start.ip4.as_u32))
87  continue;
88 
89  if (da > clib_net_to_host_u32 (p->laddr.stop.ip4.as_u32))
90  continue;
91 
92  if (sa < clib_net_to_host_u32 (p->raddr.start.ip4.as_u32))
93  continue;
94 
95  if (sa > clib_net_to_host_u32 (p->raddr.stop.ip4.as_u32))
96  continue;
97 
98  return p;
99  }
100  return 0;
101 }
102 
105 {
106  ipsec_main_t *im = &ipsec_main;
107  ipsec_policy_t *p;
108  ipsec_sa_t *s;
109  u32 *i;
110 
111  vec_foreach (i, spd->policies[IPSEC_SPD_POLICY_IP4_INBOUND_PROTECT])
112  {
113  p = pool_elt_at_index (im->policies, *i);
114  s = pool_elt_at_index (im->sad, p->sa_index);
115 
116  if (spi != s->spi)
117  continue;
118 
119  if (ipsec_sa_is_set_IS_TUNNEL (s))
120  {
121  if (da != clib_net_to_host_u32 (s->tunnel_dst_addr.ip4.as_u32))
122  continue;
123 
124  if (sa != clib_net_to_host_u32 (s->tunnel_src_addr.ip4.as_u32))
125  continue;
126 
127  return p;
128  }
129 
130  if (da < clib_net_to_host_u32 (p->laddr.start.ip4.as_u32))
131  continue;
132 
133  if (da > clib_net_to_host_u32 (p->laddr.stop.ip4.as_u32))
134  continue;
135 
136  if (sa < clib_net_to_host_u32 (p->raddr.start.ip4.as_u32))
137  continue;
138 
139  if (sa > clib_net_to_host_u32 (p->raddr.stop.ip4.as_u32))
140  continue;
141 
142  return p;
143  }
144  return 0;
145 }
146 
148 ip6_addr_match_range (ip6_address_t * a, ip6_address_t * la,
149  ip6_address_t * ua)
150 {
151  if ((memcmp (a->as_u64, la->as_u64, 2 * sizeof (u64)) >= 0) &&
152  (memcmp (a->as_u64, ua->as_u64, 2 * sizeof (u64)) <= 0))
153  return 1;
154  return 0;
155 }
156 
159  ip6_address_t * sa,
160  ip6_address_t * da, u32 spi)
161 {
162  ipsec_main_t *im = &ipsec_main;
163  ipsec_policy_t *p;
164  ipsec_sa_t *s;
165  u32 *i;
166 
167  vec_foreach (i, spd->policies[IPSEC_SPD_POLICY_IP6_INBOUND_PROTECT])
168  {
169  p = pool_elt_at_index (im->policies, *i);
170  s = pool_elt_at_index (im->sad, p->sa_index);
171 
172  if (spi != s->spi)
173  continue;
174 
175  if (ipsec_sa_is_set_IS_TUNNEL (s))
176  {
177  if (!ip6_address_is_equal (sa, &s->tunnel_src_addr.ip6))
178  continue;
179 
180  if (!ip6_address_is_equal (da, &s->tunnel_dst_addr.ip6))
181  continue;
182 
183  return p;
184  }
185 
186  if (!ip6_addr_match_range (sa, &p->raddr.start.ip6, &p->raddr.stop.ip6))
187  continue;
188 
189  if (!ip6_addr_match_range (da, &p->laddr.start.ip6, &p->laddr.stop.ip6))
190  continue;
191 
192  return p;
193  }
194  return 0;
195 }
196 
198 
202 {
203  u32 n_left_from, *from, thread_index;
204  ipsec_main_t *im = &ipsec_main;
205  u64 ipsec_unprocessed = 0, ipsec_matched = 0;
206  u64 ipsec_dropped = 0, ipsec_bypassed = 0;
208  vlib_buffer_t **b = bufs;
209  u16 nexts[VLIB_FRAME_SIZE], *next;
210 
211  from = vlib_frame_vector_args (frame);
212  n_left_from = frame->n_vectors;
213  next = nexts;
214  vlib_get_buffers (vm, from, bufs, n_left_from);
215  thread_index = vm->thread_index;
216 
217 
218  while (n_left_from > 0)
219  {
220  u32 next32, pi0;
221  ip4_header_t *ip0;
222  esp_header_t *esp0 = NULL;
223  ah_header_t *ah0;
224  ip4_ipsec_config_t *c0;
225  ipsec_spd_t *spd0;
226  ipsec_policy_t *p0 = NULL;
227  u8 has_space0;
228 
229  if (n_left_from > 2)
230  {
231  vlib_prefetch_buffer_data (b[1], LOAD);
232  }
233 
234  b[0]->flags |= VNET_BUFFER_F_IS_IP4;
235  b[0]->flags &= ~VNET_BUFFER_F_IS_IP6;
236  c0 = vnet_feature_next_with_data (&next32, b[0], sizeof (c0[0]));
237  next[0] = (u16) next32;
238 
239  spd0 = pool_elt_at_index (im->spds, c0->spd_index);
240 
241  ip0 = vlib_buffer_get_current (b[0]);
242 
243  if (PREDICT_TRUE
244  (ip0->protocol == IP_PROTOCOL_IPSEC_ESP
245  || ip0->protocol == IP_PROTOCOL_UDP))
246  {
247 
248  esp0 = (esp_header_t *) ((u8 *) ip0 + ip4_header_bytes (ip0));
249  if (PREDICT_FALSE (ip0->protocol == IP_PROTOCOL_UDP))
250  {
251  /* FIXME Skip, if not a UDP encapsulated packet */
252  esp0 = (esp_header_t *) ((u8 *) esp0 + sizeof (udp_header_t));
253  }
254 
256  clib_net_to_host_u32
257  (ip0->src_address.as_u32),
258  clib_net_to_host_u32
259  (ip0->dst_address.as_u32),
260  clib_net_to_host_u32
261  (esp0->spi));
262 
263  has_space0 =
264  vlib_buffer_has_space (b[0],
265  (clib_address_t) (esp0 + 1) -
266  (clib_address_t) ip0);
267 
268  if (PREDICT_TRUE ((p0 != NULL) & (has_space0)))
269  {
270  ipsec_matched += 1;
271 
272  pi0 = p0 - im->policies;
275  thread_index, pi0, 1, clib_net_to_host_u16 (ip0->length));
276 
277  vnet_buffer (b[0])->ipsec.sad_index = p0->sa_index;
278  next[0] = im->esp4_decrypt_next_index;
279  vlib_buffer_advance (b[0], ((u8 *) esp0 - (u8 *) ip0));
280  goto trace0;
281  }
282  else
283  {
284  p0 = 0;
285  pi0 = ~0;
286  };
287 
288  p0 = ipsec_input_policy_match (spd0,
289  clib_net_to_host_u32
290  (ip0->src_address.as_u32),
291  clib_net_to_host_u32
292  (ip0->dst_address.as_u32),
293  IPSEC_SPD_POLICY_IP4_INBOUND_BYPASS);
294  if (PREDICT_TRUE ((p0 != NULL)))
295  {
296  ipsec_bypassed += 1;
297  pi0 = p0 - im->policies;
298  goto trace0;
299  }
300  else
301  {
302  p0 = 0;
303  pi0 = ~0;
304  };
305 
306  p0 = ipsec_input_policy_match (spd0,
307  clib_net_to_host_u32
308  (ip0->src_address.as_u32),
309  clib_net_to_host_u32
310  (ip0->dst_address.as_u32),
311  IPSEC_SPD_POLICY_IP4_INBOUND_DISCARD);
312  if (PREDICT_TRUE ((p0 != NULL)))
313  {
314  ipsec_dropped += 1;
315  pi0 = p0 - im->policies;
316  next[0] = IPSEC_INPUT_NEXT_DROP;
317  goto trace0;
318  }
319  else
320  {
321  p0 = 0;
322  pi0 = ~0;
323  };
324  trace0:
325  if (PREDICT_FALSE (node->flags & VLIB_NODE_FLAG_TRACE) &&
326  PREDICT_FALSE (b[0]->flags & VLIB_BUFFER_IS_TRACED))
327  {
328  ipsec_input_trace_t *tr =
329  vlib_add_trace (vm, node, b[0], sizeof (*tr));
330 
331  tr->proto = ip0->protocol;
332  tr->sa_id = p0 ? p0->sa_id : ~0;
333  tr->spi = has_space0 ? clib_net_to_host_u32 (esp0->spi) : ~0;
334  tr->seq = has_space0 ? clib_net_to_host_u32 (esp0->seq) : ~0;
335  tr->spd = spd0->id;
336  tr->policy_index = pi0;
337  }
338  }
339  else if (ip0->protocol == IP_PROTOCOL_IPSEC_AH)
340  {
341  ah0 = (ah_header_t *) ((u8 *) ip0 + ip4_header_bytes (ip0));
343  clib_net_to_host_u32
344  (ip0->src_address.as_u32),
345  clib_net_to_host_u32
346  (ip0->dst_address.as_u32),
347  clib_net_to_host_u32
348  (ah0->spi));
349 
350  has_space0 =
351  vlib_buffer_has_space (b[0],
352  (clib_address_t) (ah0 + 1) -
353  (clib_address_t) ip0);
354 
355  if (PREDICT_TRUE ((p0 != NULL) & (has_space0)))
356  {
357  ipsec_matched += 1;
358 
359  pi0 = p0 - im->policies;
362  thread_index, pi0, 1, clib_net_to_host_u16 (ip0->length));
363 
364  vnet_buffer (b[0])->ipsec.sad_index = p0->sa_index;
365  next[0] = im->ah4_decrypt_next_index;
366  goto trace1;
367  }
368  else
369  {
370  p0 = 0;
371  pi0 = ~0;
372  }
373 
374  p0 = ipsec_input_policy_match (spd0,
375  clib_net_to_host_u32
376  (ip0->src_address.as_u32),
377  clib_net_to_host_u32
378  (ip0->dst_address.as_u32),
379  IPSEC_SPD_POLICY_IP4_INBOUND_BYPASS);
380  if (PREDICT_TRUE ((p0 != NULL)))
381  {
382  ipsec_bypassed += 1;
383  pi0 = p0 - im->policies;
384  goto trace1;
385  }
386  else
387  {
388  p0 = 0;
389  pi0 = ~0;
390  };
391 
392  p0 = ipsec_input_policy_match (spd0,
393  clib_net_to_host_u32
394  (ip0->src_address.as_u32),
395  clib_net_to_host_u32
396  (ip0->dst_address.as_u32),
397  IPSEC_SPD_POLICY_IP4_INBOUND_DISCARD);
398  if (PREDICT_TRUE ((p0 != NULL)))
399  {
400  ipsec_dropped += 1;
401  pi0 = p0 - im->policies;
402  next[0] = IPSEC_INPUT_NEXT_DROP;
403  goto trace1;
404  }
405  else
406  {
407  p0 = 0;
408  pi0 = ~0;
409  };
410  trace1:
411  if (PREDICT_FALSE (node->flags & VLIB_NODE_FLAG_TRACE) &&
412  PREDICT_FALSE (b[0]->flags & VLIB_BUFFER_IS_TRACED))
413  {
414  ipsec_input_trace_t *tr =
415  vlib_add_trace (vm, node, b[0], sizeof (*tr));
416 
417  tr->proto = ip0->protocol;
418  tr->sa_id = p0 ? p0->sa_id : ~0;
419  tr->spi = has_space0 ? clib_net_to_host_u32 (ah0->spi) : ~0;
420  tr->seq = has_space0 ? clib_net_to_host_u32 (ah0->seq_no) : ~0;
421  tr->spd = spd0->id;
422  tr->policy_index = pi0;
423  }
424  }
425  else
426  {
427  ipsec_unprocessed += 1;
428  }
429  n_left_from -= 1;
430  b += 1;
431  next += 1;
432  }
433 
434  vlib_buffer_enqueue_to_next (vm, node, from, nexts, frame->n_vectors);
435 
437  IPSEC_INPUT_ERROR_RX_PKTS, frame->n_vectors);
438 
440  IPSEC_INPUT_ERROR_RX_POLICY_MATCH,
441  ipsec_matched);
442 
444  IPSEC_INPUT_ERROR_RX_POLICY_NO_MATCH,
445  ipsec_unprocessed);
446 
448  IPSEC_INPUT_ERROR_RX_POLICY_DISCARD,
449  ipsec_dropped);
450 
452  IPSEC_INPUT_ERROR_RX_POLICY_BYPASS,
453  ipsec_bypassed);
454 
455  return frame->n_vectors;
456 }
457 
458 
459 /* *INDENT-OFF* */
461  .name = "ipsec4-input-feature",
462  .vector_size = sizeof (u32),
463  .format_trace = format_ipsec_input_trace,
466  .error_strings = ipsec_input_error_strings,
467  .n_next_nodes = IPSEC_INPUT_N_NEXT,
468  .next_nodes = {
469 #define _(s,n) [IPSEC_INPUT_NEXT_##s] = n,
471 #undef _
472  },
473 };
474 /* *INDENT-ON* */
475 
477 
478 
481  vlib_frame_t * from_frame)
482 {
483  u32 n_left_from, *from, next_index, *to_next, thread_index;
484  ipsec_main_t *im = &ipsec_main;
485  u32 ipsec_unprocessed = 0;
486  u32 ipsec_matched = 0;
487 
488  from = vlib_frame_vector_args (from_frame);
489  n_left_from = from_frame->n_vectors;
490  thread_index = vm->thread_index;
491 
492  next_index = node->cached_next_index;
493 
494  while (n_left_from > 0)
495  {
496  u32 n_left_to_next;
497 
498  vlib_get_next_frame (vm, node, next_index, to_next, n_left_to_next);
499 
500  while (n_left_from > 0 && n_left_to_next > 0)
501  {
502  u32 bi0, next0, pi0;
503  vlib_buffer_t *b0;
504  ip6_header_t *ip0;
505  esp_header_t *esp0;
506  ip4_ipsec_config_t *c0;
507  ipsec_spd_t *spd0;
508  ipsec_policy_t *p0 = 0;
509  ah_header_t *ah0;
510  u32 header_size = sizeof (ip0[0]);
511 
512  bi0 = to_next[0] = from[0];
513  from += 1;
514  n_left_from -= 1;
515  to_next += 1;
516  n_left_to_next -= 1;
517 
518  b0 = vlib_get_buffer (vm, bi0);
519  b0->flags |= VNET_BUFFER_F_IS_IP6;
520  b0->flags &= ~VNET_BUFFER_F_IS_IP4;
521  c0 = vnet_feature_next_with_data (&next0, b0, sizeof (c0[0]));
522 
523  spd0 = pool_elt_at_index (im->spds, c0->spd_index);
524 
525  ip0 = vlib_buffer_get_current (b0);
526  esp0 = (esp_header_t *) ((u8 *) ip0 + header_size);
527  ah0 = (ah_header_t *) ((u8 *) ip0 + header_size);
528 
529  if (PREDICT_TRUE (ip0->protocol == IP_PROTOCOL_IPSEC_ESP))
530  {
531 #if 0
533  ("packet received from %U to %U spi %u size %u spd_id %u",
535  &ip0->dst_address, clib_net_to_host_u32 (esp0->spi),
536  clib_net_to_host_u16 (ip0->payload_length) + header_size,
537  spd0->id);
538 #endif
540  &ip0->src_address,
541  &ip0->dst_address,
542  clib_net_to_host_u32
543  (esp0->spi));
544 
545  if (PREDICT_TRUE (p0 != 0))
546  {
547  ipsec_matched += 1;
548 
549  pi0 = p0 - im->policies;
552  thread_index, pi0, 1,
553  clib_net_to_host_u16 (ip0->payload_length) +
554  header_size);
555 
556  vnet_buffer (b0)->ipsec.sad_index = p0->sa_index;
557  next0 = im->esp6_decrypt_next_index;
558  vlib_buffer_advance (b0, header_size);
559  goto trace0;
560  }
561  else
562  {
563  pi0 = ~0;
564  }
565  }
566  else if (ip0->protocol == IP_PROTOCOL_IPSEC_AH)
567  {
569  &ip0->src_address,
570  &ip0->dst_address,
571  clib_net_to_host_u32
572  (ah0->spi));
573 
574  if (PREDICT_TRUE (p0 != 0))
575  {
576  ipsec_matched += 1;
577  pi0 = p0 - im->policies;
580  thread_index, pi0, 1,
581  clib_net_to_host_u16 (ip0->payload_length) +
582  header_size);
583 
584  vnet_buffer (b0)->ipsec.sad_index = p0->sa_index;
585  next0 = im->ah6_decrypt_next_index;
586  goto trace0;
587  }
588  else
589  {
590  pi0 = ~0;
591  }
592  }
593  else
594  {
595  ipsec_unprocessed += 1;
596  }
597 
598  trace0:
599  if (PREDICT_FALSE (node->flags & VLIB_NODE_FLAG_TRACE) &&
600  PREDICT_FALSE (b0->flags & VLIB_BUFFER_IS_TRACED))
601  {
602  ipsec_input_trace_t *tr =
603  vlib_add_trace (vm, node, b0, sizeof (*tr));
604 
605  if (p0)
606  tr->sa_id = p0->sa_id;
607  tr->proto = ip0->protocol;
608  tr->spi = clib_net_to_host_u32 (esp0->spi);
609  tr->seq = clib_net_to_host_u32 (esp0->seq);
610  tr->spd = spd0->id;
611  }
612 
613  vlib_validate_buffer_enqueue_x1 (vm, node, next_index, to_next,
614  n_left_to_next, bi0, next0);
615  }
616  vlib_put_next_frame (vm, node, next_index, n_left_to_next);
617  }
618 
620  IPSEC_INPUT_ERROR_RX_PKTS,
621  from_frame->n_vectors - ipsec_unprocessed);
622 
624  IPSEC_INPUT_ERROR_RX_POLICY_MATCH,
625  ipsec_matched);
626 
627  return from_frame->n_vectors;
628 }
629 
630 
631 /* *INDENT-OFF* */
633  .name = "ipsec6-input-feature",
634  .vector_size = sizeof (u32),
635  .format_trace = format_ipsec_input_trace,
638  .error_strings = ipsec_input_error_strings,
639  .n_next_nodes = IPSEC_INPUT_N_NEXT,
640  .next_nodes = {
641 #define _(s,n) [IPSEC_INPUT_NEXT_##s] = n,
643 #undef _
644  },
645 };
646 /* *INDENT-ON* */
647 
648 /*
649  * fd.io coding-style-patch-verification: ON
650  *
651  * Local Variables:
652  * eval: (c-set-style "gnu")
653  * End:
654  */
static char * ipsec_input_error_strings[]
Definition: ipsec_input.c:43
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
u32 spi
format_function_t format_ip_protocol
Definition: format.h:45
ipsec_spd_t * spds
Definition: ipsec.h:105
#define CLIB_UNUSED(x)
Definition: clib.h:86
ip46_address_t tunnel_src_addr
Definition: ipsec_sa.h:175
enum ipsec_spd_policy_t_ ipsec_spd_policy_type_t
u32 ah4_decrypt_next_index
Definition: ipsec.h:150
a
Definition: bitmap.h:538
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
ip4_address_t src_address
Definition: ip4_packet.h:170
vlib_node_registration_t ipsec4_input_node
(constructor) VLIB_REGISTER_NODE (ipsec4_input_node)
Definition: ipsec_input.c:460
#define PREDICT_TRUE(x)
Definition: clib.h:119
unsigned long u64
Definition: types.h:89
ip46_address_range_t laddr
u64 clib_address_t
Definition: types.h:121
u32 thread_index
Definition: main.h:218
static ipsec_policy_t * ipsec_input_protect_policy_match(ipsec_spd_t *spd, u32 sa, u32 da, u32 spi)
Definition: ipsec_input.c:104
static uword ip6_addr_match_range(ip6_address_t *a, ip6_address_t *la, ip6_address_t *ua)
Definition: ipsec_input.c:148
u8 * format(u8 *s, const char *fmt,...)
Definition: format.c:424
A Secruity Policy Database.
Definition: ipsec_spd.h:46
#define VLIB_NODE_FN(node)
Definition: node.h:202
static u8 * format_ipsec_input_trace(u8 *s, va_list *args)
Definition: ipsec_input.c:61
ip6_address_t src_address
Definition: ip6_packet.h:310
unsigned char u8
Definition: types.h:56
static ipsec_policy_t * ipsec_input_policy_match(ipsec_spd_t *spd, u32 sa, u32 da, ipsec_spd_policy_type_t policy_type)
Definition: ipsec_input.c:75
ipsec_main_t ipsec_main
Definition: ipsec.c:28
unsigned int seq_no
Definition: ah.h:27
ip4_address_t dst_address
Definition: ip4_packet.h:170
u32 esp4_decrypt_next_index
Definition: ipsec.h:147
vlib_node_registration_t ipsec6_input_node
(constructor) VLIB_REGISTER_NODE (ipsec6_input_node)
Definition: ipsec_input.c:632
unsigned int u32
Definition: types.h:88
#define VLIB_FRAME_SIZE
Definition: node.h:380
vl_api_fib_path_type_t type
Definition: fib_types.api:123
enum ip_protocol ip_protocol_t
static_always_inline void * vnet_feature_next_with_data(u32 *next0, vlib_buffer_t *b0, u32 n_data_bytes)
Definition: feature.h:309
#define pool_elt_at_index(p, i)
Returns pointer to element at given index.
Definition: pool.h:534
vlib_combined_counter_main_t ipsec_spd_policy_counters
Policy packet & bytes counters.
ipsec_input_error_t
Definition: ipsec_input.c:35
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:118
#define always_inline
Definition: ipsec.h:28
#define vlib_validate_buffer_enqueue_x1(vm, node, next_index, to_next, n_left_to_next, bi0, next0)
Finish enqueueing one buffer forward in the graph.
Definition: buffer_node.h:224
#define vlib_get_next_frame(vm, node, next_index, vectors, n_vectors_left)
Get pointer to next frame vector data by (vlib_node_runtime_t, next_index).
Definition: node_funcs.h:338
vlib_main_t * vm
Definition: in2out_ed.c:1599
static void vlib_node_increment_counter(vlib_main_t *vm, u32 node_index, u32 counter_index, u64 increment)
Definition: node_funcs.h:1150
ip46_address_t tunnel_dst_addr
Definition: ipsec_sa.h:176
#define VLIB_REGISTER_NODE(x,...)
Definition: node.h:169
u32 flags
Definition: vhost_user.h:248
format_function_t format_ip6_address
Definition: format.h:91
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
sll srl srl sll sra u16x4 i
Definition: vector_sse42.h:317
ip46_address_t start
#define clib_warning(format, args...)
Definition: error.h:59
#define vlib_prefetch_buffer_data(b, type)
Definition: buffer.h:204
u32 esp6_decrypt_next_index
Definition: ipsec.h:152
#define ARRAY_LEN(x)
Definition: clib.h:66
void vlib_put_next_frame(vlib_main_t *vm, vlib_node_runtime_t *r, u32 next_index, u32 n_vectors_left)
Release pointer to next frame vector data.
Definition: main.c:483
A Secruity Policy.
vlib_main_t vlib_node_runtime_t * node
Definition: in2out_ed.c:1599
ip_protocol_t proto
Definition: ipsec_input.c:51
ipsec_policy_t * policies
Definition: ipsec.h:109
ipsec_sa_t * sad
Definition: ipsec.h:107
u32 * policies[IPSEC_SPD_POLICY_N_TYPES]
vectors for each of the policy types
Definition: ipsec_spd.h:51
u32 seq
Definition: esp.h:29
static void vlib_buffer_advance(vlib_buffer_t *b, word l)
Advance current data pointer by the supplied (signed!) amount.
Definition: buffer.h:248
static uword ip6_address_is_equal(const ip6_address_t *a, const ip6_address_t *b)
Definition: ip6_packet.h:167
u32 spi
Definition: esp.h:26
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
struct _vlib_node_registration vlib_node_registration_t
#define foreach_ipsec_input_error
Definition: ipsec_input.c:28
static u8 vlib_buffer_has_space(vlib_buffer_t *b, word l)
Check if there is enough space in buffer to advance.
Definition: buffer.h:265
u32 ah6_decrypt_next_index
Definition: ipsec.h:155
u16 payload_length
Definition: ip6_packet.h:301
ip46_address_range_t raddr
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
u32 id
the User&#39;s ID for this policy
Definition: ipsec_spd.h:49
#define vnet_buffer(b)
Definition: buffer.h:417
Definition: ah.h:21
#define vec_foreach(var, vec)
Vector iterator.
vlib_main_t vlib_node_runtime_t vlib_frame_t * frame
Definition: in2out_ed.c:1600
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:280
#define VLIB_NODE_FLAG_TRACE
Definition: node.h:304
unsigned int spi
Definition: ah.h:26
static ipsec_policy_t * ipsec6_input_protect_policy_match(ipsec_spd_t *spd, ip6_address_t *sa, ip6_address_t *da, u32 spi)
Definition: ipsec_input.c:158
#define foreach_ipsec_input_next
Definition: ipsec_io.h:29
static vlib_buffer_t * vlib_get_buffer(vlib_main_t *vm, u32 buffer_index)
Translate buffer index into buffer pointer.
Definition: buffer_funcs.h:85
ip6_address_t dst_address
Definition: ip6_packet.h:310