blob: 8bd6d22a5888f38d16bc27a7f4c9f13530b8de37 [file] [log] [blame]
Neale Rannsf62a8c02019-04-02 08:13:33 +00001/*
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
24typedef enum
25{
26#define _(sym,str) IPSEC_HANDOFF_ERROR_##sym,
27 foreach_ipsec_handoff_error
28#undef _
29 NAT44_HANDOFF_N_ERROR,
30} ipsec_handoff_error_t;
31
32static char *ipsec_handoff_error_strings[] = {
33#define _(sym,string) string,
34 foreach_ipsec_handoff_error
35#undef _
36};
37
38typedef struct ipsec_handoff_trace_t_
39{
40 u32 next_worker_index;
41} ipsec_handoff_trace_t;
42
43static u8 *
44format_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 */
56static_always_inline uword
Neale Ranns1a52d372021-02-04 11:33:32 +000057ipsec_handoff (vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame,
58 u32 fq_index)
Neale Rannsf62a8c02019-04-02 08:13:33 +000059{
60 vlib_buffer_t *bufs[VLIB_FRAME_SIZE], **b;
61 u16 thread_indices[VLIB_FRAME_SIZE], *ti;
62 u32 n_enq, n_left_from, *from;
63 ipsec_main_t *im;
64
65 im = &ipsec_main;
66 from = vlib_frame_vector_args (frame);
67 n_left_from = frame->n_vectors;
68 vlib_get_buffers (vm, from, bufs, n_left_from);
69
70 b = bufs;
71 ti = thread_indices;
72
73 while (n_left_from >= 4)
74 {
75 ipsec_sa_t *sa0, *sa1, *sa2, *sa3;
76 u32 sai0, sai1, sai2, sai3;
77
78 /* Prefetch next iteration. */
79 if (n_left_from >= 12)
80 {
81 vlib_prefetch_buffer_header (b[8], LOAD);
82 vlib_prefetch_buffer_header (b[9], LOAD);
83 vlib_prefetch_buffer_header (b[10], LOAD);
84 vlib_prefetch_buffer_header (b[11], LOAD);
85
86 vlib_prefetch_buffer_data (b[4], LOAD);
87 vlib_prefetch_buffer_data (b[5], LOAD);
88 vlib_prefetch_buffer_data (b[6], LOAD);
89 vlib_prefetch_buffer_data (b[7], LOAD);
90 }
91
92 sai0 = vnet_buffer (b[0])->ipsec.sad_index;
93 sai1 = vnet_buffer (b[1])->ipsec.sad_index;
94 sai2 = vnet_buffer (b[2])->ipsec.sad_index;
95 sai3 = vnet_buffer (b[3])->ipsec.sad_index;
96 sa0 = pool_elt_at_index (im->sad, sai0);
97 sa1 = pool_elt_at_index (im->sad, sai1);
98 sa2 = pool_elt_at_index (im->sad, sai2);
99 sa3 = pool_elt_at_index (im->sad, sai3);
100
Neale Ranns1a52d372021-02-04 11:33:32 +0000101 ti[0] = sa0->thread_index;
102 ti[1] = sa1->thread_index;
103 ti[2] = sa2->thread_index;
104 ti[3] = sa3->thread_index;
Neale Rannsf62a8c02019-04-02 08:13:33 +0000105
106 if (node->flags & VLIB_NODE_FLAG_TRACE)
107 {
108 if (PREDICT_FALSE (b[0]->flags & VLIB_BUFFER_IS_TRACED))
109 {
110 ipsec_handoff_trace_t *t =
111 vlib_add_trace (vm, node, b[0], sizeof (*t));
112 t->next_worker_index = ti[0];
113 }
114 if (PREDICT_FALSE (b[1]->flags & VLIB_BUFFER_IS_TRACED))
115 {
116 ipsec_handoff_trace_t *t =
117 vlib_add_trace (vm, node, b[1], sizeof (*t));
118 t->next_worker_index = ti[1];
119 }
120 if (PREDICT_FALSE (b[2]->flags & VLIB_BUFFER_IS_TRACED))
121 {
122 ipsec_handoff_trace_t *t =
123 vlib_add_trace (vm, node, b[2], sizeof (*t));
124 t->next_worker_index = ti[2];
125 }
126 if (PREDICT_FALSE (b[3]->flags & VLIB_BUFFER_IS_TRACED))
127 {
128 ipsec_handoff_trace_t *t =
129 vlib_add_trace (vm, node, b[3], sizeof (*t));
130 t->next_worker_index = ti[3];
131 }
132 }
133
134 n_left_from -= 4;
135 ti += 4;
136 b += 4;
137 }
138 while (n_left_from > 0)
139 {
140 ipsec_sa_t *sa0;
141 u32 sai0;
142
143 sai0 = vnet_buffer (b[0])->ipsec.sad_index;
144 sa0 = pool_elt_at_index (im->sad, sai0);
145
Neale Ranns1a52d372021-02-04 11:33:32 +0000146 ti[0] = sa0->thread_index;
Neale Rannsf62a8c02019-04-02 08:13:33 +0000147
148 if (PREDICT_FALSE (b[0]->flags & VLIB_BUFFER_IS_TRACED))
149 {
150 ipsec_handoff_trace_t *t =
151 vlib_add_trace (vm, node, b[0], sizeof (*t));
152 t->next_worker_index = ti[0];
153 }
154
155 n_left_from -= 1;
156 ti += 1;
157 b += 1;
158 }
159
160 n_enq = vlib_buffer_enqueue_to_thread (vm, fq_index, from,
161 thread_indices, frame->n_vectors, 1);
162
163 if (n_enq < frame->n_vectors)
164 vlib_node_increment_counter (vm, node->node_index,
165 IPSEC_HANDOFF_ERROR_CONGESTION_DROP,
166 frame->n_vectors - n_enq);
167
168 return n_enq;
169}
170
171VLIB_NODE_FN (esp4_encrypt_handoff) (vlib_main_t * vm,
172 vlib_node_runtime_t * node,
173 vlib_frame_t * from_frame)
174{
175 ipsec_main_t *im = &ipsec_main;
176
Neale Ranns1a52d372021-02-04 11:33:32 +0000177 return ipsec_handoff (vm, node, from_frame, im->esp4_enc_fq_index);
Neale Rannsf62a8c02019-04-02 08:13:33 +0000178}
179
180VLIB_NODE_FN (esp6_encrypt_handoff) (vlib_main_t * vm,
181 vlib_node_runtime_t * node,
182 vlib_frame_t * from_frame)
183{
184 ipsec_main_t *im = &ipsec_main;
185
Neale Ranns1a52d372021-02-04 11:33:32 +0000186 return ipsec_handoff (vm, node, from_frame, im->esp6_enc_fq_index);
Neale Rannsf62a8c02019-04-02 08:13:33 +0000187}
188
189VLIB_NODE_FN (esp4_encrypt_tun_handoff) (vlib_main_t * vm,
190 vlib_node_runtime_t * node,
191 vlib_frame_t * from_frame)
192{
193 ipsec_main_t *im = &ipsec_main;
194
Neale Ranns1a52d372021-02-04 11:33:32 +0000195 return ipsec_handoff (vm, node, from_frame, im->esp4_enc_tun_fq_index);
Neale Rannsf62a8c02019-04-02 08:13:33 +0000196}
197
198VLIB_NODE_FN (esp6_encrypt_tun_handoff) (vlib_main_t * vm,
199 vlib_node_runtime_t * node,
200 vlib_frame_t * from_frame)
201{
202 ipsec_main_t *im = &ipsec_main;
203
Neale Ranns1a52d372021-02-04 11:33:32 +0000204 return ipsec_handoff (vm, node, from_frame, im->esp6_enc_tun_fq_index);
Neale Rannsf62a8c02019-04-02 08:13:33 +0000205}
206
Neale Ranns4a58e492020-12-21 13:19:10 +0000207VLIB_NODE_FN (esp_mpls_encrypt_tun_handoff)
208(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *from_frame)
209{
210 ipsec_main_t *im = &ipsec_main;
211
Neale Ranns1a52d372021-02-04 11:33:32 +0000212 return ipsec_handoff (vm, node, from_frame, im->esp_mpls_enc_tun_fq_index);
Neale Ranns4a58e492020-12-21 13:19:10 +0000213}
214
Neale Rannsf62a8c02019-04-02 08:13:33 +0000215VLIB_NODE_FN (esp4_decrypt_handoff) (vlib_main_t * vm,
216 vlib_node_runtime_t * node,
217 vlib_frame_t * from_frame)
218{
219 ipsec_main_t *im = &ipsec_main;
220
Neale Ranns1a52d372021-02-04 11:33:32 +0000221 return ipsec_handoff (vm, node, from_frame, im->esp4_dec_fq_index);
Neale Rannsf62a8c02019-04-02 08:13:33 +0000222}
223
224VLIB_NODE_FN (esp6_decrypt_handoff) (vlib_main_t * vm,
225 vlib_node_runtime_t * node,
226 vlib_frame_t * from_frame)
227{
228 ipsec_main_t *im = &ipsec_main;
229
Neale Ranns1a52d372021-02-04 11:33:32 +0000230 return ipsec_handoff (vm, node, from_frame, im->esp6_dec_fq_index);
Neale Rannsf62a8c02019-04-02 08:13:33 +0000231}
232
233VLIB_NODE_FN (esp4_decrypt_tun_handoff) (vlib_main_t * vm,
234 vlib_node_runtime_t * node,
235 vlib_frame_t * from_frame)
236{
237 ipsec_main_t *im = &ipsec_main;
238
Neale Ranns1a52d372021-02-04 11:33:32 +0000239 return ipsec_handoff (vm, node, from_frame, im->esp4_dec_tun_fq_index);
Neale Rannsf62a8c02019-04-02 08:13:33 +0000240}
241
242VLIB_NODE_FN (esp6_decrypt_tun_handoff) (vlib_main_t * vm,
243 vlib_node_runtime_t * node,
244 vlib_frame_t * from_frame)
245{
246 ipsec_main_t *im = &ipsec_main;
247
Neale Ranns1a52d372021-02-04 11:33:32 +0000248 return ipsec_handoff (vm, node, from_frame, im->esp6_dec_tun_fq_index);
Neale Rannsf62a8c02019-04-02 08:13:33 +0000249}
250
251VLIB_NODE_FN (ah4_encrypt_handoff) (vlib_main_t * vm,
252 vlib_node_runtime_t * node,
253 vlib_frame_t * from_frame)
254{
255 ipsec_main_t *im = &ipsec_main;
256
Neale Ranns1a52d372021-02-04 11:33:32 +0000257 return ipsec_handoff (vm, node, from_frame, im->ah4_enc_fq_index);
Neale Rannsf62a8c02019-04-02 08:13:33 +0000258}
259
260VLIB_NODE_FN (ah6_encrypt_handoff) (vlib_main_t * vm,
261 vlib_node_runtime_t * node,
262 vlib_frame_t * from_frame)
263{
264 ipsec_main_t *im = &ipsec_main;
265
Neale Ranns1a52d372021-02-04 11:33:32 +0000266 return ipsec_handoff (vm, node, from_frame, im->ah6_enc_fq_index);
Neale Rannsf62a8c02019-04-02 08:13:33 +0000267}
268
269VLIB_NODE_FN (ah4_decrypt_handoff) (vlib_main_t * vm,
270 vlib_node_runtime_t * node,
271 vlib_frame_t * from_frame)
272{
273 ipsec_main_t *im = &ipsec_main;
274
Neale Ranns1a52d372021-02-04 11:33:32 +0000275 return ipsec_handoff (vm, node, from_frame, im->ah4_dec_fq_index);
Neale Rannsf62a8c02019-04-02 08:13:33 +0000276}
277
278VLIB_NODE_FN (ah6_decrypt_handoff) (vlib_main_t * vm,
279 vlib_node_runtime_t * node,
280 vlib_frame_t * from_frame)
281{
282 ipsec_main_t *im = &ipsec_main;
283
Neale Ranns1a52d372021-02-04 11:33:32 +0000284 return ipsec_handoff (vm, node, from_frame, im->ah6_dec_fq_index);
Neale Rannsf62a8c02019-04-02 08:13:33 +0000285}
286
287/* *INDENT-OFF* */
288VLIB_REGISTER_NODE (esp4_encrypt_handoff) = {
289 .name = "esp4-encrypt-handoff",
290 .vector_size = sizeof (u32),
291 .format_trace = format_ipsec_handoff_trace,
292 .type = VLIB_NODE_TYPE_INTERNAL,
293 .n_errors = ARRAY_LEN(ipsec_handoff_error_strings),
294 .error_strings = ipsec_handoff_error_strings,
295 .n_next_nodes = 1,
296 .next_nodes = {
297 [0] = "error-drop",
298 },
299};
300VLIB_REGISTER_NODE (esp6_encrypt_handoff) = {
301 .name = "esp6-encrypt-handoff",
302 .vector_size = sizeof (u32),
303 .format_trace = format_ipsec_handoff_trace,
304 .type = VLIB_NODE_TYPE_INTERNAL,
305 .n_errors = ARRAY_LEN(ipsec_handoff_error_strings),
306 .error_strings = ipsec_handoff_error_strings,
307 .n_next_nodes = 1,
308 .next_nodes = {
309 [0] = "error-drop",
310 },
311};
312VLIB_REGISTER_NODE (esp4_encrypt_tun_handoff) = {
313 .name = "esp4-encrypt-tun-handoff",
314 .vector_size = sizeof (u32),
315 .format_trace = format_ipsec_handoff_trace,
316 .type = VLIB_NODE_TYPE_INTERNAL,
317 .n_errors = ARRAY_LEN(ipsec_handoff_error_strings),
318 .error_strings = ipsec_handoff_error_strings,
319 .n_next_nodes = 1,
320 .next_nodes = {
321 [0] = "error-drop",
322 },
323};
324VLIB_REGISTER_NODE (esp6_encrypt_tun_handoff) = {
325 .name = "esp6-encrypt-tun-handoff",
326 .vector_size = sizeof (u32),
327 .format_trace = format_ipsec_handoff_trace,
328 .type = VLIB_NODE_TYPE_INTERNAL,
329 .n_errors = ARRAY_LEN(ipsec_handoff_error_strings),
330 .error_strings = ipsec_handoff_error_strings,
331 .n_next_nodes = 1,
332 .next_nodes = {
333 [0] = "error-drop",
334 },
335};
Neale Ranns4a58e492020-12-21 13:19:10 +0000336VLIB_REGISTER_NODE (esp_mpls_encrypt_tun_handoff) = {
337 .name = "esp-mpls-encrypt-tun-handoff",
338 .vector_size = sizeof (u32),
339 .format_trace = format_ipsec_handoff_trace,
340 .type = VLIB_NODE_TYPE_INTERNAL,
341 .n_errors = ARRAY_LEN(ipsec_handoff_error_strings),
342 .error_strings = ipsec_handoff_error_strings,
343 .n_next_nodes = 1,
344 .next_nodes = {
345 [0] = "error-drop",
346 },
347};
Neale Rannsf62a8c02019-04-02 08:13:33 +0000348VLIB_REGISTER_NODE (esp4_decrypt_handoff) = {
349 .name = "esp4-decrypt-handoff",
350 .vector_size = sizeof (u32),
351 .format_trace = format_ipsec_handoff_trace,
352 .type = VLIB_NODE_TYPE_INTERNAL,
353 .n_errors = ARRAY_LEN(ipsec_handoff_error_strings),
354 .error_strings = ipsec_handoff_error_strings,
355 .n_next_nodes = 1,
356 .next_nodes = {
357 [0] = "error-drop",
358 },
359};
360VLIB_REGISTER_NODE (esp6_decrypt_handoff) = {
361 .name = "esp6-decrypt-handoff",
362 .vector_size = sizeof (u32),
363 .format_trace = format_ipsec_handoff_trace,
364 .type = VLIB_NODE_TYPE_INTERNAL,
365 .n_errors = ARRAY_LEN(ipsec_handoff_error_strings),
366 .error_strings = ipsec_handoff_error_strings,
367 .n_next_nodes = 1,
368 .next_nodes = {
369 [0] = "error-drop",
370 },
371};
372VLIB_REGISTER_NODE (esp4_decrypt_tun_handoff) = {
373 .name = "esp4-decrypt-tun-handoff",
374 .vector_size = sizeof (u32),
375 .format_trace = format_ipsec_handoff_trace,
376 .type = VLIB_NODE_TYPE_INTERNAL,
377 .n_errors = ARRAY_LEN(ipsec_handoff_error_strings),
378 .error_strings = ipsec_handoff_error_strings,
379 .n_next_nodes = 1,
380 .next_nodes = {
381 [0] = "error-drop",
382 },
383};
384VLIB_REGISTER_NODE (esp6_decrypt_tun_handoff) = {
385 .name = "esp6-decrypt-tun-handoff",
386 .vector_size = sizeof (u32),
387 .format_trace = format_ipsec_handoff_trace,
388 .type = VLIB_NODE_TYPE_INTERNAL,
389 .n_errors = ARRAY_LEN(ipsec_handoff_error_strings),
390 .error_strings = ipsec_handoff_error_strings,
391 .n_next_nodes = 1,
392 .next_nodes = {
393 [0] = "error-drop",
394 },
395};
396VLIB_REGISTER_NODE (ah4_encrypt_handoff) = {
397 .name = "ah4-encrypt-handoff",
398 .vector_size = sizeof (u32),
399 .format_trace = format_ipsec_handoff_trace,
400 .type = VLIB_NODE_TYPE_INTERNAL,
401 .n_errors = ARRAY_LEN(ipsec_handoff_error_strings),
402 .error_strings = ipsec_handoff_error_strings,
403 .n_next_nodes = 1,
404 .next_nodes = {
405 [0] = "error-drop",
406 },
407};
408VLIB_REGISTER_NODE (ah6_encrypt_handoff) = {
409 .name = "ah6-encrypt-handoff",
410 .vector_size = sizeof (u32),
411 .format_trace = format_ipsec_handoff_trace,
412 .type = VLIB_NODE_TYPE_INTERNAL,
413 .n_errors = ARRAY_LEN(ipsec_handoff_error_strings),
414 .error_strings = ipsec_handoff_error_strings,
415 .n_next_nodes = 1,
416 .next_nodes = {
417 [0] = "error-drop",
418 },
419};
420VLIB_REGISTER_NODE (ah4_decrypt_handoff) = {
421 .name = "ah4-decrypt-handoff",
422 .vector_size = sizeof (u32),
423 .format_trace = format_ipsec_handoff_trace,
424 .type = VLIB_NODE_TYPE_INTERNAL,
425 .n_errors = ARRAY_LEN(ipsec_handoff_error_strings),
426 .error_strings = ipsec_handoff_error_strings,
427 .n_next_nodes = 1,
428 .next_nodes = {
429 [0] = "error-drop",
430 },
431};
432VLIB_REGISTER_NODE (ah6_decrypt_handoff) = {
433 .name = "ah6-decrypt-handoff",
434 .vector_size = sizeof (u32),
435 .format_trace = format_ipsec_handoff_trace,
436 .type = VLIB_NODE_TYPE_INTERNAL,
437 .n_errors = ARRAY_LEN(ipsec_handoff_error_strings),
438 .error_strings = ipsec_handoff_error_strings,
439 .n_next_nodes = 1,
440 .next_nodes = {
441 [0] = "error-drop",
442 },
443};
444/* *INDENT-ON* */
445
446/*
447 * fd.io coding-style-patch-verification: ON
448 *
449 * Local Variables:
450 * eval: (c-set-style "gnu")
451 * End:
452 */