FD.io VPP  v21.06-3-gbb25fbf28
Vector Packet Processing
ipsec_handoff.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/ipsec/ipsec.h>
19 #include <vnet/ipsec/ipsec_sa.h>
20 
21 #define foreach_ipsec_handoff_error \
22 _(CONGESTION_DROP, "congestion drop")
23 
24 typedef enum
25 {
26 #define _(sym,str) IPSEC_HANDOFF_ERROR_##sym,
28 #undef _
31 
32 static char *ipsec_handoff_error_strings[] = {
33 #define _(sym,string) string,
35 #undef _
36 };
37 
38 typedef struct ipsec_handoff_trace_t_
39 {
42 
43 static u8 *
44 format_ipsec_handoff_trace (u8 * s, va_list * args)
45 {
46  CLIB_UNUSED (vlib_main_t * vm) = va_arg (*args, vlib_main_t *);
47  CLIB_UNUSED (vlib_node_t * node) = va_arg (*args, vlib_node_t *);
48  ipsec_handoff_trace_t *t = va_arg (*args, ipsec_handoff_trace_t *);
49 
50  s = format (s, "next-worker %d", t->next_worker_index);
51 
52  return s;
53 }
54 
55 /* do worker handoff based on thread_index in NAT HA protcol header */
58  u32 fq_index)
59 {
61  u16 thread_indices[VLIB_FRAME_SIZE], *ti;
62  u32 n_enq, n_left_from, *from;
63 
65  n_left_from = frame->n_vectors;
67 
68  b = bufs;
69  ti = thread_indices;
70 
71  while (n_left_from >= 4)
72  {
73  /* Prefetch next iteration. */
74  if (n_left_from >= 12)
75  {
76  vlib_prefetch_buffer_header (b[8], LOAD);
77  vlib_prefetch_buffer_header (b[9], LOAD);
78  vlib_prefetch_buffer_header (b[10], LOAD);
79  vlib_prefetch_buffer_header (b[11], LOAD);
80  }
81 
82  ti[0] = vnet_buffer (b[0])->ipsec.thread_index;
83  ti[1] = vnet_buffer (b[1])->ipsec.thread_index;
84  ti[2] = vnet_buffer (b[2])->ipsec.thread_index;
85  ti[3] = vnet_buffer (b[3])->ipsec.thread_index;
86 
88  {
89  if (PREDICT_FALSE (b[0]->flags & VLIB_BUFFER_IS_TRACED))
90  {
92  vlib_add_trace (vm, node, b[0], sizeof (*t));
93  t->next_worker_index = ti[0];
94  }
95  if (PREDICT_FALSE (b[1]->flags & VLIB_BUFFER_IS_TRACED))
96  {
98  vlib_add_trace (vm, node, b[1], sizeof (*t));
99  t->next_worker_index = ti[1];
100  }
101  if (PREDICT_FALSE (b[2]->flags & VLIB_BUFFER_IS_TRACED))
102  {
104  vlib_add_trace (vm, node, b[2], sizeof (*t));
105  t->next_worker_index = ti[2];
106  }
107  if (PREDICT_FALSE (b[3]->flags & VLIB_BUFFER_IS_TRACED))
108  {
110  vlib_add_trace (vm, node, b[3], sizeof (*t));
111  t->next_worker_index = ti[3];
112  }
113  }
114 
115  n_left_from -= 4;
116  ti += 4;
117  b += 4;
118  }
119  while (n_left_from > 0)
120  {
121  ti[0] = vnet_buffer (b[0])->ipsec.thread_index;
122 
123  if (PREDICT_FALSE (b[0]->flags & VLIB_BUFFER_IS_TRACED))
124  {
126  vlib_add_trace (vm, node, b[0], sizeof (*t));
127  t->next_worker_index = ti[0];
128  }
129 
130  n_left_from -= 1;
131  ti += 1;
132  b += 1;
133  }
134 
135  n_enq = vlib_buffer_enqueue_to_thread (vm, node, fq_index, from,
136  thread_indices, frame->n_vectors, 1);
137 
138  if (n_enq < frame->n_vectors)
139  vlib_node_increment_counter (vm, node->node_index,
140  IPSEC_HANDOFF_ERROR_CONGESTION_DROP,
141  frame->n_vectors - n_enq);
142 
143  return n_enq;
144 }
145 
149 {
151 
152  return ipsec_handoff (vm, node, from_frame, im->esp4_enc_fq_index);
153 }
154 
158 {
160 
161  return ipsec_handoff (vm, node, from_frame, im->esp6_enc_fq_index);
162 }
163 
167 {
169 
170  return ipsec_handoff (vm, node, from_frame, im->esp4_enc_tun_fq_index);
171 }
172 
176 {
178 
179  return ipsec_handoff (vm, node, from_frame, im->esp6_enc_tun_fq_index);
180 }
181 
184 {
186 
187  return ipsec_handoff (vm, node, from_frame, im->esp_mpls_enc_tun_fq_index);
188 }
189 
193 {
195 
196  return ipsec_handoff (vm, node, from_frame, im->esp4_dec_fq_index);
197 }
198 
202 {
204 
205  return ipsec_handoff (vm, node, from_frame, im->esp6_dec_fq_index);
206 }
207 
211 {
213 
214  return ipsec_handoff (vm, node, from_frame, im->esp4_dec_tun_fq_index);
215 }
216 
220 {
222 
223  return ipsec_handoff (vm, node, from_frame, im->esp6_dec_tun_fq_index);
224 }
225 
229 {
231 
232  return ipsec_handoff (vm, node, from_frame, im->ah4_enc_fq_index);
233 }
234 
238 {
240 
241  return ipsec_handoff (vm, node, from_frame, im->ah6_enc_fq_index);
242 }
243 
247 {
249 
250  return ipsec_handoff (vm, node, from_frame, im->ah4_dec_fq_index);
251 }
252 
256 {
258 
259  return ipsec_handoff (vm, node, from_frame, im->ah6_dec_fq_index);
260 }
261 
262 /* *INDENT-OFF* */
264  .name = "esp4-encrypt-handoff",
265  .vector_size = sizeof (u32),
266  .format_trace = format_ipsec_handoff_trace,
269  .error_strings = ipsec_handoff_error_strings,
270  .n_next_nodes = 1,
271  .next_nodes = {
272  [0] = "error-drop",
273  },
274 };
276  .name = "esp6-encrypt-handoff",
277  .vector_size = sizeof (u32),
278  .format_trace = format_ipsec_handoff_trace,
281  .error_strings = ipsec_handoff_error_strings,
282  .n_next_nodes = 1,
283  .next_nodes = {
284  [0] = "error-drop",
285  },
286 };
288  .name = "esp4-encrypt-tun-handoff",
289  .vector_size = sizeof (u32),
290  .format_trace = format_ipsec_handoff_trace,
293  .error_strings = ipsec_handoff_error_strings,
294  .n_next_nodes = 1,
295  .next_nodes = {
296  [0] = "error-drop",
297  },
298 };
300  .name = "esp6-encrypt-tun-handoff",
301  .vector_size = sizeof (u32),
302  .format_trace = format_ipsec_handoff_trace,
305  .error_strings = ipsec_handoff_error_strings,
306  .n_next_nodes = 1,
307  .next_nodes = {
308  [0] = "error-drop",
309  },
310 };
312  .name = "esp-mpls-encrypt-tun-handoff",
313  .vector_size = sizeof (u32),
314  .format_trace = format_ipsec_handoff_trace,
317  .error_strings = ipsec_handoff_error_strings,
318  .n_next_nodes = 1,
319  .next_nodes = {
320  [0] = "error-drop",
321  },
322 };
324  .name = "esp4-decrypt-handoff",
325  .vector_size = sizeof (u32),
326  .format_trace = format_ipsec_handoff_trace,
329  .error_strings = ipsec_handoff_error_strings,
330  .n_next_nodes = 1,
331  .next_nodes = {
332  [0] = "error-drop",
333  },
334 };
336  .name = "esp6-decrypt-handoff",
337  .vector_size = sizeof (u32),
338  .format_trace = format_ipsec_handoff_trace,
341  .error_strings = ipsec_handoff_error_strings,
342  .n_next_nodes = 1,
343  .next_nodes = {
344  [0] = "error-drop",
345  },
346 };
348  .name = "esp4-decrypt-tun-handoff",
349  .vector_size = sizeof (u32),
350  .format_trace = format_ipsec_handoff_trace,
353  .error_strings = ipsec_handoff_error_strings,
354  .n_next_nodes = 1,
355  .next_nodes = {
356  [0] = "error-drop",
357  },
358 };
360  .name = "esp6-decrypt-tun-handoff",
361  .vector_size = sizeof (u32),
362  .format_trace = format_ipsec_handoff_trace,
365  .error_strings = ipsec_handoff_error_strings,
366  .n_next_nodes = 1,
367  .next_nodes = {
368  [0] = "error-drop",
369  },
370 };
372  .name = "ah4-encrypt-handoff",
373  .vector_size = sizeof (u32),
374  .format_trace = format_ipsec_handoff_trace,
377  .error_strings = ipsec_handoff_error_strings,
378  .n_next_nodes = 1,
379  .next_nodes = {
380  [0] = "error-drop",
381  },
382 };
384  .name = "ah6-encrypt-handoff",
385  .vector_size = sizeof (u32),
386  .format_trace = format_ipsec_handoff_trace,
389  .error_strings = ipsec_handoff_error_strings,
390  .n_next_nodes = 1,
391  .next_nodes = {
392  [0] = "error-drop",
393  },
394 };
396  .name = "ah4-decrypt-handoff",
397  .vector_size = sizeof (u32),
398  .format_trace = format_ipsec_handoff_trace,
401  .error_strings = ipsec_handoff_error_strings,
402  .n_next_nodes = 1,
403  .next_nodes = {
404  [0] = "error-drop",
405  },
406 };
408  .name = "ah6-decrypt-handoff",
409  .vector_size = sizeof (u32),
410  .format_trace = format_ipsec_handoff_trace,
413  .error_strings = ipsec_handoff_error_strings,
414  .n_next_nodes = 1,
415  .next_nodes = {
416  [0] = "error-drop",
417  },
418 };
419 /* *INDENT-ON* */
420 
421 /*
422  * fd.io coding-style-patch-verification: ON
423  *
424  * Local Variables:
425  * eval: (c-set-style "gnu")
426  * End:
427  */
ipsec.h
im
vnet_interface_main_t * im
Definition: interface_output.c:395
ipsec_handoff_trace_t_
Definition: ipsec_handoff.c:38
bufs
vlib_buffer_t * bufs[VLIB_FRAME_SIZE]
Definition: nat44_ei_out2in.c:717
vlib_buffer_enqueue_to_thread
static_always_inline u32 vlib_buffer_enqueue_to_thread(vlib_main_t *vm, vlib_node_runtime_t *node, u32 frame_queue_index, u32 *buffer_indices, u16 *thread_indices, u32 n_packets, int drop_on_congestion)
Definition: buffer_node.h:358
vlib_prefetch_buffer_header
#define vlib_prefetch_buffer_header(b, type)
Prefetch buffer metadata.
Definition: buffer.h:231
frame
vlib_main_t vlib_node_runtime_t vlib_frame_t * frame
Definition: nat44_ei.c:3048
from_frame
vlib_main_t vlib_node_runtime_t vlib_frame_t * from_frame
Definition: ipsec_handoff.c:184
format_ipsec_handoff_trace
static u8 * format_ipsec_handoff_trace(u8 *s, va_list *args)
Definition: ipsec_handoff.c:44
vlib_get_buffers
vlib_get_buffers(vm, from, b, n_left_from)
VLIB_NODE_TYPE_INTERNAL
@ VLIB_NODE_TYPE_INTERNAL
Definition: node.h:72
VLIB_FRAME_SIZE
#define VLIB_FRAME_SIZE
Definition: node.h:368
ipsec_handoff_trace_t_::next_worker_index
u32 next_worker_index
Definition: ipsec_handoff.c:40
u16
unsigned short u16
Definition: types.h:57
esp4_decrypt_tun_handoff
vlib_node_registration_t esp4_decrypt_tun_handoff
(constructor) VLIB_REGISTER_NODE (esp4_decrypt_tun_handoff)
Definition: ipsec_handoff.c:347
vlib_frame_t
Definition: node.h:372
ah4_encrypt_handoff
vlib_node_registration_t ah4_encrypt_handoff
(constructor) VLIB_REGISTER_NODE (ah4_encrypt_handoff)
Definition: ipsec_handoff.c:371
ipsec_sa.h
ah4_decrypt_handoff
vlib_node_registration_t ah4_decrypt_handoff
(constructor) VLIB_REGISTER_NODE (ah4_decrypt_handoff)
Definition: ipsec_handoff.c:395
ti
u32 ti
Definition: interface_output.c:405
foreach_ipsec_handoff_error
#define foreach_ipsec_handoff_error
Definition: ipsec_handoff.c:21
VLIB_NODE_FN
#define VLIB_NODE_FN(node)
Definition: node.h:202
ipsec_handoff
static_always_inline uword ipsec_handoff(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame, u32 fq_index)
Definition: ipsec_handoff.c:57
CLIB_UNUSED
#define CLIB_UNUSED(x)
Definition: clib.h:90
vnet_buffer
#define vnet_buffer(b)
Definition: buffer.h:437
esp4_encrypt_tun_handoff
vlib_node_registration_t esp4_encrypt_tun_handoff
(constructor) VLIB_REGISTER_NODE (esp4_encrypt_tun_handoff)
Definition: ipsec_handoff.c:287
VLIB_NODE_FLAG_TRACE
#define VLIB_NODE_FLAG_TRACE
Definition: node.h:291
esp6_decrypt_handoff
vlib_node_registration_t esp6_decrypt_handoff
(constructor) VLIB_REGISTER_NODE (esp6_decrypt_handoff)
Definition: ipsec_handoff.c:335
PREDICT_FALSE
#define PREDICT_FALSE(x)
Definition: clib.h:124
ARRAY_LEN
#define ARRAY_LEN(x)
Definition: clib.h:70
vlib_frame_vector_args
static void * vlib_frame_vector_args(vlib_frame_t *f)
Get pointer to frame vector data.
Definition: node_funcs.h:301
ipsec_main_t
Definition: ipsec.h:108
static_always_inline
#define static_always_inline
Definition: clib.h:112
ipsec_handoff_error_t
ipsec_handoff_error_t
Definition: ipsec_handoff.c:24
uword
u64 uword
Definition: types.h:112
ipsec_main
ipsec_main_t ipsec_main
Definition: ipsec.c:28
esp6_decrypt_tun_handoff
vlib_node_registration_t esp6_decrypt_tun_handoff
(constructor) VLIB_REGISTER_NODE (esp6_decrypt_tun_handoff)
Definition: ipsec_handoff.c:359
vlib_node_increment_counter
static void vlib_node_increment_counter(vlib_main_t *vm, u32 node_index, u32 counter_index, u64 increment)
Definition: node_funcs.h:1244
NAT44_HANDOFF_N_ERROR
@ NAT44_HANDOFF_N_ERROR
Definition: ipsec_handoff.c:29
ipsec_handoff_trace_t
struct ipsec_handoff_trace_t_ ipsec_handoff_trace_t
vlib_node_registration_t
struct _vlib_node_registration vlib_node_registration_t
node
vlib_main_t vlib_node_runtime_t * node
Definition: ipsec_handoff.c:183
ah6_encrypt_handoff
vlib_node_registration_t ah6_encrypt_handoff
(constructor) VLIB_REGISTER_NODE (ah6_encrypt_handoff)
Definition: ipsec_handoff.c:383
esp4_encrypt_handoff
vlib_node_registration_t esp4_encrypt_handoff
(constructor) VLIB_REGISTER_NODE (esp4_encrypt_handoff)
Definition: ipsec_handoff.c:263
format
description fragment has unexpected format
Definition: map.api:433
esp6_encrypt_tun_handoff
vlib_node_registration_t esp6_encrypt_tun_handoff
(constructor) VLIB_REGISTER_NODE (esp6_encrypt_tun_handoff)
Definition: ipsec_handoff.c:299
u32
unsigned int u32
Definition: types.h:88
esp_mpls_encrypt_tun_handoff
vlib_node_registration_t esp_mpls_encrypt_tun_handoff
(constructor) VLIB_REGISTER_NODE (esp_mpls_encrypt_tun_handoff)
Definition: ipsec_handoff.c:311
esp6_encrypt_handoff
vlib_node_registration_t esp6_encrypt_handoff
(constructor) VLIB_REGISTER_NODE (esp6_encrypt_handoff)
Definition: ipsec_handoff.c:275
n_vectors
return frame n_vectors
Definition: nat44_ei_hairpinning.c:485
ah6_decrypt_handoff
vlib_node_registration_t ah6_decrypt_handoff
(constructor) VLIB_REGISTER_NODE (ah6_decrypt_handoff)
Definition: ipsec_handoff.c:407
ipsec_handoff_error_strings
static char * ipsec_handoff_error_strings[]
Definition: ipsec_handoff.c:32
vlib_main_t
Definition: main.h:102
vlib_node_t
Definition: node.h:247
vlib_add_trace
void * vlib_add_trace(vlib_main_t *vm, vlib_node_runtime_t *r, vlib_buffer_t *b, u32 n_data_bytes)
Definition: trace.c:628
b
vlib_buffer_t ** b
Definition: nat44_ei_out2in.c:717
u8
unsigned char u8
Definition: types.h:56
esp4_decrypt_handoff
vlib_node_registration_t esp4_decrypt_handoff
(constructor) VLIB_REGISTER_NODE (esp4_decrypt_handoff)
Definition: ipsec_handoff.c:323
vlib_node_runtime_t
Definition: node.h:454
from
from
Definition: nat44_ei_hairpinning.c:415
n_left_from
n_left_from
Definition: nat44_ei_hairpinning.c:416
type
vl_api_fib_path_type_t type
Definition: fib_types.api:123
vm
vlib_main_t * vm
Definition: ipsec_handoff.c:183
vlib_buffer_t
VLIB buffer representation.
Definition: buffer.h:111
VLIB_REGISTER_NODE
#define VLIB_REGISTER_NODE(x,...)
Definition: node.h:169
flags
vl_api_wireguard_peer_flags_t flags
Definition: wireguard.api:105