FD.io VPP  v17.04.2-2-ga8f93f8
Vector Packet Processing
ipsec.c
Go to the documentation of this file.
1 /*
2  * decap.c : IPSec tunnel support
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/interface.h>
22 
23 #include <vnet/ipsec/ipsec.h>
24 #include <vnet/ipsec/ikev2.h>
25 #include <vnet/ipsec/esp.h>
26 
27 u32
29 {
30  ipsec_main_t *im = &ipsec_main;
31  uword *p = hash_get (im->sa_index_by_sa_id, sa_id);
32  if (!p)
33  return ~0;
34 
35  return p[0];
36 }
37 
38 int
39 ipsec_set_interface_spd (vlib_main_t * vm, u32 sw_if_index, u32 spd_id,
40  int is_add)
41 {
42  ipsec_main_t *im = &ipsec_main;
43  ip4_ipsec_config_t config;
44 
45  u32 spd_index;
46  uword *p;
47 
48  p = hash_get (im->spd_index_by_spd_id, spd_id);
49  if (!p)
50  return VNET_API_ERROR_SYSCALL_ERROR_1; /* no such spd-id */
51 
52  spd_index = p[0];
53 
54  p = hash_get (im->spd_index_by_sw_if_index, sw_if_index);
55  if (p && is_add)
56  return VNET_API_ERROR_SYSCALL_ERROR_1; /* spd already assigned */
57 
58  if (is_add)
59  {
60  hash_set (im->spd_index_by_sw_if_index, sw_if_index, spd_index);
61  }
62  else
63  {
64  hash_unset (im->spd_index_by_sw_if_index, sw_if_index);
65  }
66 
67  clib_warning ("sw_if_index %u spd_id %u spd_index %u",
68  sw_if_index, spd_id, spd_index);
69 
70  /* enable IPsec on TX */
71  vnet_feature_enable_disable ("ip4-output", "ipsec-output-ip4", sw_if_index,
72  is_add, 0, 0);
73  vnet_feature_enable_disable ("ip6-output", "ipsec-output-ip6", sw_if_index,
74  is_add, 0, 0);
75 
76  /* enable IPsec on RX */
77  vnet_feature_enable_disable ("ip4-unicast", "ipsec-input-ip4", sw_if_index,
78  is_add, &config, sizeof (config));
79  vnet_feature_enable_disable ("ip6-unicast", "ipsec-input-ip6", sw_if_index,
80  is_add, &config, sizeof (config));
81 
82  return 0;
83 }
84 
85 int
86 ipsec_add_del_spd (vlib_main_t * vm, u32 spd_id, int is_add)
87 {
88  ipsec_main_t *im = &ipsec_main;
89  ipsec_spd_t *spd = 0;
90  uword *p;
91  u32 spd_index, k, v;
92 
93  p = hash_get (im->spd_index_by_spd_id, spd_id);
94  if (p && is_add)
95  return VNET_API_ERROR_INVALID_VALUE;
96  if (!p && !is_add)
97  return VNET_API_ERROR_INVALID_VALUE;
98 
99  if (!is_add) /* delete */
100  {
101  spd_index = p[0];
102  spd = pool_elt_at_index (im->spds, spd_index);
103  if (!spd)
104  return VNET_API_ERROR_INVALID_VALUE;
105  /* *INDENT-OFF* */
107  if (v == spd_index)
108  ipsec_set_interface_spd(vm, k, spd_id, 0);
109  }));
110  /* *INDENT-ON* */
111  hash_unset (im->spd_index_by_spd_id, spd_id);
112  pool_free (spd->policies);
117  pool_put (im->spds, spd);
118  }
119  else /* create new SPD */
120  {
121  pool_get (im->spds, spd);
122  memset (spd, 0, sizeof (*spd));
123  spd_index = spd - im->spds;
124  spd->id = spd_id;
125  hash_set (im->spd_index_by_spd_id, spd_id, spd_index);
126  }
127  return 0;
128 }
129 
130 static int
131 ipsec_spd_entry_sort (void *a1, void *a2)
132 {
133  ipsec_main_t *im = &ipsec_main;
134  u32 *id1 = a1;
135  u32 *id2 = a2;
136  ipsec_spd_t *spd;
137  ipsec_policy_t *p1, *p2;
138 
139  /* *INDENT-OFF* */
140  pool_foreach (spd, im->spds, ({
141  p1 = pool_elt_at_index(spd->policies, *id1);
142  p2 = pool_elt_at_index(spd->policies, *id2);
143  if (p1 && p2)
144  return p2->priority - p1->priority;
145  }));
146  /* *INDENT-ON* */
147 
148  return 0;
149 }
150 
151 int
153 {
154  ipsec_main_t *im = &ipsec_main;
155  ipsec_spd_t *spd = 0;
156  ipsec_policy_t *vp;
157  uword *p;
158  u32 spd_index;
159 
160  clib_warning ("policy-id %u priority %d is_outbound %u", policy->id,
161  policy->priority, policy->is_outbound);
162 
163  if (policy->policy == IPSEC_POLICY_ACTION_PROTECT)
164  {
165  p = hash_get (im->sa_index_by_sa_id, policy->sa_id);
166  if (!p)
167  return VNET_API_ERROR_SYSCALL_ERROR_1;
168  policy->sa_index = p[0];
169  }
170 
171  p = hash_get (im->spd_index_by_spd_id, policy->id);
172 
173  if (!p)
174  return VNET_API_ERROR_SYSCALL_ERROR_1;
175 
176  spd_index = p[0];
177  spd = pool_elt_at_index (im->spds, spd_index);
178  if (!spd)
179  return VNET_API_ERROR_SYSCALL_ERROR_1;
180 
181  if (is_add)
182  {
183  u32 policy_index;
184 
185  pool_get (spd->policies, vp);
186  clib_memcpy (vp, policy, sizeof (*vp));
187  policy_index = vp - spd->policies;
188 
189  if (policy->is_outbound)
190  {
191  if (policy->is_ipv6)
192  {
193  vec_add1 (spd->ipv6_outbound_policies, policy_index);
194  clib_memcpy (vp, policy, sizeof (ipsec_policy_t));
197  }
198  else
199  {
200  vec_add1 (spd->ipv4_outbound_policies, policy_index);
201  clib_memcpy (vp, policy, sizeof (ipsec_policy_t));
204  }
205  }
206  else
207  {
208  if (policy->is_ipv6)
209  {
210  if (policy->policy == IPSEC_POLICY_ACTION_PROTECT)
211  {
213  policy_index);
214  clib_memcpy (vp, policy, sizeof (ipsec_policy_t));
218  }
219  else
220  {
221  vec_add1
223  policy_index);
224  clib_memcpy (vp, policy, sizeof (ipsec_policy_t));
228  }
229  }
230  else
231  {
232  if (policy->policy == IPSEC_POLICY_ACTION_PROTECT)
233  {
235  policy_index);
236  clib_memcpy (vp, policy, sizeof (ipsec_policy_t));
240  }
241  else
242  {
243  vec_add1
245  policy_index);
246  clib_memcpy (vp, policy, sizeof (ipsec_policy_t));
250  }
251  }
252  }
253 
254  }
255  else
256  {
257  u32 i, j;
258  /* *INDENT-OFF* */
259  pool_foreach_index(i, spd->policies, ({
260  vp = pool_elt_at_index(spd->policies, i);
261  if (vp->priority != policy->priority)
262  continue;
263  if (vp->is_outbound != policy->is_outbound)
264  continue;
265  if (vp->policy != policy->policy)
266  continue;
267  if (vp->sa_id != policy->sa_id)
268  continue;
269  if (vp->protocol != policy->protocol)
270  continue;
271  if (vp->lport.start != policy->lport.start)
272  continue;
273  if (vp->lport.stop != policy->lport.stop)
274  continue;
275  if (vp->rport.start != policy->rport.start)
276  continue;
277  if (vp->rport.stop != policy->rport.stop)
278  continue;
279  if (vp->is_ipv6 != policy->is_ipv6)
280  continue;
281  if (policy->is_ipv6)
282  {
283  if (vp->laddr.start.ip6.as_u64[0] != policy->laddr.start.ip6.as_u64[0])
284  continue;
285  if (vp->laddr.start.ip6.as_u64[1] != policy->laddr.start.ip6.as_u64[1])
286  continue;
287  if (vp->laddr.stop.ip6.as_u64[0] != policy->laddr.stop.ip6.as_u64[0])
288  continue;
289  if (vp->laddr.stop.ip6.as_u64[1] != policy->laddr.stop.ip6.as_u64[1])
290  continue;
291  if (vp->raddr.start.ip6.as_u64[0] != policy->raddr.start.ip6.as_u64[0])
292  continue;
293  if (vp->raddr.start.ip6.as_u64[1] != policy->raddr.start.ip6.as_u64[1])
294  continue;
295  if (vp->raddr.stop.ip6.as_u64[0] != policy->raddr.stop.ip6.as_u64[0])
296  continue;
297  if (vp->laddr.stop.ip6.as_u64[1] != policy->laddr.stop.ip6.as_u64[1])
298  continue;
299  if (policy->is_outbound)
300  {
301  vec_foreach_index(j, spd->ipv6_outbound_policies) {
302  if (vec_elt(spd->ipv6_outbound_policies, j) == i) {
303  vec_del1 (spd->ipv6_outbound_policies, j);
304  break;
305  }
306  }
307  }
308  else
309  {
310  if (policy->policy == IPSEC_POLICY_ACTION_PROTECT)
311  {
312  vec_foreach_index(j, spd->ipv6_inbound_protect_policy_indices) {
313  if (vec_elt(spd->ipv6_inbound_protect_policy_indices, j) == i) {
314  vec_del1 (spd->ipv6_inbound_protect_policy_indices, j);
315  break;
316  }
317  }
318  }
319  else
320  {
321  vec_foreach_index(j, spd->ipv6_inbound_policy_discard_and_bypass_indices) {
322  if (vec_elt(spd->ipv6_inbound_policy_discard_and_bypass_indices, j) == i) {
323  vec_del1 (spd->ipv6_inbound_policy_discard_and_bypass_indices, j);
324  break;
325  }
326  }
327  }
328  }
329  }
330  else
331  {
332  if (vp->laddr.start.ip4.as_u32 != policy->laddr.start.ip4.as_u32)
333  continue;
334  if (vp->laddr.stop.ip4.as_u32 != policy->laddr.stop.ip4.as_u32)
335  continue;
336  if (vp->raddr.start.ip4.as_u32 != policy->raddr.start.ip4.as_u32)
337  continue;
338  if (vp->raddr.stop.ip4.as_u32 != policy->raddr.stop.ip4.as_u32)
339  continue;
340  if (policy->is_outbound)
341  {
342  vec_foreach_index(j, spd->ipv4_outbound_policies) {
343  if (vec_elt(spd->ipv4_outbound_policies, j) == i) {
344  vec_del1 (spd->ipv4_outbound_policies, j);
345  break;
346  }
347  }
348  }
349  else
350  {
351  if (policy->policy == IPSEC_POLICY_ACTION_PROTECT)
352  {
353  vec_foreach_index(j, spd->ipv4_inbound_protect_policy_indices) {
354  if (vec_elt(spd->ipv4_inbound_protect_policy_indices, j) == i) {
355  vec_del1 (spd->ipv4_inbound_protect_policy_indices, j);
356  break;
357  }
358  }
359  }
360  else
361  {
362  vec_foreach_index(j, spd->ipv4_inbound_policy_discard_and_bypass_indices) {
363  if (vec_elt(spd->ipv4_inbound_policy_discard_and_bypass_indices, j) == i) {
364  vec_del1 (spd->ipv4_inbound_policy_discard_and_bypass_indices, j);
365  break;
366  }
367  }
368  }
369  }
370  pool_put (spd->policies, vp);
371  break;
372  }
373  }));
374  /* *INDENT-ON* */
375  }
376 
377  return 0;
378 }
379 
380 static u8
382 {
383  ipsec_main_t *im = &ipsec_main;
384  ipsec_spd_t *spd;
385  ipsec_policy_t *p;
387 
388  /* *INDENT-OFF* */
389  pool_foreach(spd, im->spds, ({
390  pool_foreach(p, spd->policies, ({
391  if (p->policy == IPSEC_POLICY_ACTION_PROTECT)
392  {
393  if (p->sa_index == sa_index)
394  return 1;
395  }
396  }));
397  }));
398 
399  pool_foreach(t, im->tunnel_interfaces, ({
400  if (t->input_sa_index == sa_index)
401  return 1;
402  if (t->output_sa_index == sa_index)
403  return 1;
404  }));
405  /* *INDENT-ON* */
406 
407  return 0;
408 }
409 
410 int
411 ipsec_add_del_sa (vlib_main_t * vm, ipsec_sa_t * new_sa, int is_add)
412 {
413  ipsec_main_t *im = &ipsec_main;
414  ipsec_sa_t *sa = 0;
415  uword *p;
416  u32 sa_index;
417 
418  clib_warning ("id %u spi %u", new_sa->id, new_sa->spi);
419 
420  p = hash_get (im->sa_index_by_sa_id, new_sa->id);
421  if (p && is_add)
422  return VNET_API_ERROR_SYSCALL_ERROR_1; /* already exists */
423  if (!p && !is_add)
424  return VNET_API_ERROR_SYSCALL_ERROR_1;
425 
426  if (!is_add) /* delete */
427  {
428  sa_index = p[0];
429  sa = pool_elt_at_index (im->sad, sa_index);
430  if (ipsec_is_sa_used (sa_index))
431  {
432  clib_warning ("sa_id %u used in policy", sa->id);
433  return VNET_API_ERROR_SYSCALL_ERROR_1; /* sa used in policy */
434  }
435  hash_unset (im->sa_index_by_sa_id, sa->id);
436  if (im->cb.add_del_sa_sess_cb &&
437  im->cb.add_del_sa_sess_cb (sa_index, is_add) < 0)
438  return VNET_API_ERROR_SYSCALL_ERROR_1;
439  pool_put (im->sad, sa);
440  }
441  else /* create new SA */
442  {
443  pool_get (im->sad, sa);
444  clib_memcpy (sa, new_sa, sizeof (*sa));
445  sa_index = sa - im->sad;
446  hash_set (im->sa_index_by_sa_id, sa->id, sa_index);
447  if (im->cb.add_del_sa_sess_cb &&
448  im->cb.add_del_sa_sess_cb (sa_index, is_add) < 0)
449  return VNET_API_ERROR_SYSCALL_ERROR_1;
450  }
451  return 0;
452 }
453 
454 int
456 {
457  ipsec_main_t *im = &ipsec_main;
458  uword *p;
459  u32 sa_index;
460  ipsec_sa_t *sa = 0;
461 
462  p = hash_get (im->sa_index_by_sa_id, sa_update->id);
463  if (!p)
464  return VNET_API_ERROR_SYSCALL_ERROR_1; /* no such sa-id */
465 
466  sa_index = p[0];
467  sa = pool_elt_at_index (im->sad, sa_index);
468 
469  /* new crypto key */
470  if (0 < sa_update->crypto_key_len)
471  {
472  clib_memcpy (sa->crypto_key, sa_update->crypto_key,
473  sa_update->crypto_key_len);
474  sa->crypto_key_len = sa_update->crypto_key_len;
475  }
476 
477  /* new integ key */
478  if (0 < sa_update->integ_key_len)
479  {
480  clib_memcpy (sa->integ_key, sa_update->integ_key,
481  sa_update->integ_key_len);
482  sa->integ_key_len = sa_update->integ_key_len;
483  }
484 
485  if (sa->crypto_key_len + sa->integ_key_len > 0)
486  {
487  if (im->cb.add_del_sa_sess_cb &&
488  im->cb.add_del_sa_sess_cb (sa_index, 0) < 0)
489  return VNET_API_ERROR_SYSCALL_ERROR_1;
490  }
491 
492  return 0;
493 }
494 
495 static void
497 {
498  struct
499  {
500  time_t time;
501  pid_t pid;
502  void *p;
503  } seed_data;
504 
505  seed_data.time = time (NULL);
506  seed_data.pid = getpid ();
507  seed_data.p = (void *) &seed_data;
508 
509  RAND_seed ((const void *) &seed_data, sizeof (seed_data));
510 }
511 
512 static clib_error_t *
514 {
515  if (sa->crypto_alg == IPSEC_CRYPTO_ALG_AES_GCM_128)
516  return clib_error_return (0, "unsupported aes-gcm-128 crypto-alg");
517  if (sa->integ_alg == IPSEC_INTEG_ALG_NONE)
518  return clib_error_return (0, "unsupported none integ-alg");
519  if (sa->integ_alg == IPSEC_INTEG_ALG_AES_GCM_128)
520  return clib_error_return (0, "unsupported aes-gcm-128 integ-alg");
521 
522  return 0;
523 }
524 
525 static clib_error_t *
527 {
528  clib_error_t *error;
529  ipsec_main_t *im = &ipsec_main;
531  vlib_node_t *node;
532 
533  ipsec_rand_seed ();
534 
535  memset (im, 0, sizeof (im[0]));
536 
537  im->vnet_main = vnet_get_main ();
538  im->vlib_main = vm;
539 
540  im->spd_index_by_spd_id = hash_create (0, sizeof (uword));
541  im->sa_index_by_sa_id = hash_create (0, sizeof (uword));
542  im->spd_index_by_sw_if_index = hash_create (0, sizeof (uword));
543 
546 
547  node = vlib_get_node_by_name (vm, (u8 *) "error-drop");
548  ASSERT (node);
549  im->error_drop_node_index = node->index;
550 
551  node = vlib_get_node_by_name (vm, (u8 *) "esp-encrypt");
552  ASSERT (node);
553  im->esp_encrypt_node_index = node->index;
554 
555  node = vlib_get_node_by_name (vm, (u8 *) "esp-decrypt");
556  ASSERT (node);
557  im->esp_decrypt_node_index = node->index;
558 
559  im->esp_encrypt_next_index = IPSEC_OUTPUT_NEXT_ESP_ENCRYPT;
560  im->esp_decrypt_next_index = IPSEC_INPUT_NEXT_ESP_DECRYPT;
561 
563 
564  if ((error = vlib_call_init_function (vm, ipsec_cli_init)))
565  return error;
566 
567  if ((error = vlib_call_init_function (vm, ipsec_tunnel_if_init)))
568  return error;
569 
570  esp_init ();
571 
572  if ((error = ikev2_init (vm)))
573  return error;
574 
575  return 0;
576 }
577 
579 
580 /*
581  * fd.io coding-style-patch-verification: ON
582  *
583  * Local Variables:
584  * eval: (c-set-style "gnu")
585  * End:
586  */
u32 * ipv6_inbound_protect_policy_indices
Definition: ipsec.h:216
ipsec_spd_t * spds
Definition: ipsec.h:246
#define hash_set(h, key, value)
Definition: hash.h:254
u32 * ipv4_inbound_protect_policy_indices
Definition: ipsec.h:214
sll srl srl sll sra u16x4 i
Definition: vector_sse2.h:343
int ipsec_add_del_policy(vlib_main_t *vm, ipsec_policy_t *policy, int is_add)
Definition: ipsec.c:152
#define hash_unset(h, key)
Definition: hash.h:260
i32(* add_del_sa_sess_cb)(u32 sa_index, u8 is_add)
Definition: ipsec.h:239
u32 id
Definition: ipsec.h:102
vnet_main_t * vnet_get_main(void)
Definition: misc.c:46
i32 priority
Definition: ipsec.h:186
static void ipsec_rand_seed(void)
Definition: ipsec.c:496
int ipsec_set_interface_spd(vlib_main_t *vm, u32 sw_if_index, u32 spd_id, int is_add)
Definition: ipsec.c:39
#define NULL
Definition: clib.h:55
u32 index
Definition: node.h:237
ipsec_integ_alg_t integ_alg
Definition: ipsec.h:110
#define vec_add1(V, E)
Add 1 element to end of vector (unspecified alignment).
Definition: vec.h:522
u32 * ipv4_outbound_policies
Definition: ipsec.h:212
u32 ipsec_get_sa_index_by_sa_id(u32 sa_id)
Definition: ipsec.c:28
#define vec_validate_aligned(V, I, A)
Make sure vector is long enough for given index (no header, specified alignment)
Definition: vec.h:447
#define pool_get(P, E)
Allocate an object E from a pool P (unspecified alignment).
Definition: pool.h:200
u8 crypto_key[128]
Definition: ipsec.h:108
int ipsec_add_del_spd(vlib_main_t *vm, u32 spd_id, int is_add)
Definition: ipsec.c:86
u32 spi
Definition: ipsec.h:103
uword * spd_index_by_sw_if_index
Definition: ipsec.h:266
clib_error_t * ipsec_tunnel_if_init(vlib_main_t *vm)
Definition: ipsec_if.c:385
u8 integ_key[128]
Definition: ipsec.h:112
u32 esp_encrypt_next_index
Definition: ipsec.h:275
#define pool_foreach(VAR, POOL, BODY)
Iterate through pool.
Definition: pool.h:376
#define VLIB_INIT_FUNCTION(x)
Definition: init.h:111
ipsec_main_t ipsec_main
Definition: ipsec.h:282
#define hash_foreach(key_var, value_var, h, body)
Definition: hash.h:418
#define clib_error_return(e, args...)
Definition: error.h:111
ipsec_main_callbacks_t cb
Definition: ipsec.h:279
#define vlib_call_init_function(vm, x)
Definition: init.h:162
ipsec_policy_t * policies
Definition: ipsec.h:210
u32 error_drop_node_index
Definition: ipsec.h:271
#define hash_get(h, key)
Definition: hash.h:248
#define pool_elt_at_index(p, i)
Returns pointer to element at given index.
Definition: pool.h:397
clib_error_t *(* check_support_cb)(ipsec_sa_t *sa)
Definition: ipsec.h:240
vnet_main_t * vnet_main
Definition: ipsec.h:259
#define v
Definition: acl.c:246
#define pool_put(P, E)
Free an object E in pool P.
Definition: pool.h:241
uword * spd_index_by_spd_id
Definition: ipsec.h:265
#define pool_free(p)
Free a pool.
Definition: pool.h:290
vlib_main_t * vm
Definition: buffer.c:276
u32 esp_encrypt_node_index
Definition: ipsec.h:272
int ipsec_add_del_sa(vlib_main_t *vm, ipsec_sa_t *new_sa, int is_add)
Definition: ipsec.c:411
clib_error_t * ipsec_cli_init(vlib_main_t *vm)
Definition: ipsec_cli.c:849
#define vec_free(V)
Free vector&#39;s memory (no header).
Definition: vec.h:340
u32 sa_index
Definition: ipsec.h:200
u32 esp_decrypt_next_index
Definition: ipsec.h:276
#define clib_warning(format, args...)
Definition: error.h:59
#define clib_memcpy(a, b, c)
Definition: string.h:69
uword * sa_index_by_sa_id
Definition: ipsec.h:267
int ipsec_set_sa_key(vlib_main_t *vm, ipsec_sa_t *sa_update)
Definition: ipsec.c:455
vlib_node_t * vlib_get_node_by_name(vlib_main_t *vm, u8 *name)
Definition: node.c:45
vlib_main_t * vlib_main
Definition: ipsec.h:258
static clib_error_t * ipsec_init(vlib_main_t *vm)
Definition: ipsec.c:526
#define hash_create(elts, value_bytes)
Definition: hash.h:658
#define ASSERT(truth)
unsigned int u32
Definition: types.h:88
ipsec_sa_t * sad
Definition: ipsec.h:247
u8 integ_key_len
Definition: ipsec.h:111
u64 uword
Definition: types.h:112
u8 crypto_key_len
Definition: ipsec.h:107
u32 * ipv4_inbound_policy_discard_and_bypass_indices
Definition: ipsec.h:215
unsigned char u8
Definition: types.h:56
u8 is_outbound
Definition: ipsec.h:187
u32 * ipv6_inbound_policy_discard_and_bypass_indices
Definition: ipsec.h:217
#define vec_sort_with_function(vec, f)
Sort a vector using the supplied element comparison function.
Definition: vec.h:960
static u8 ipsec_is_sa_used(u32 sa_index)
Definition: ipsec.c:381
u32 * ipv6_outbound_policies
Definition: ipsec.h:213
static clib_error_t * ipsec_check_support(ipsec_sa_t *sa)
Definition: ipsec.c:513
u32 id
Definition: ipsec.h:208
clib_error_t * ikev2_init(vlib_main_t *vm)
Definition: ikev2.c:3251
ipsec_crypto_alg_t crypto_alg
Definition: ipsec.h:106
static vlib_thread_main_t * vlib_get_thread_main()
Definition: global_funcs.h:32
static int ipsec_spd_entry_sort(void *a1, void *a2)
Definition: ipsec.c:131
#define pool_foreach_index(i, v, body)
Iterate pool by index.
Definition: pool.h:418
#define CLIB_CACHE_LINE_BYTES
Definition: cache.h:67
u32 ** empty_buffers
Definition: ipsec.h:253
static void esp_init()
Definition: esp.h:231
int vnet_feature_enable_disable(const char *arc_name, const char *node_name, u32 sw_if_index, int enable_disable, void *feature_config, u32 n_feature_config_bytes)
Definition: feature.c:225
u32 esp_decrypt_node_index
Definition: ipsec.h:273