FD.io VPP  v21.06-1-gbb7418cf9
Vector Packet Processing
ipsec.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2017 Intel and/or its affiliates.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at:
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 #include <vnet/vnet.h>
16 #include <vnet/ip/ip.h>
17 #include <vnet/api_errno.h>
18 #include <vnet/ipsec/ipsec.h>
19 #include <vlib/node_funcs.h>
20 #include <vlib/log.h>
21 
22 #include <dpdk/device/dpdk.h>
23 #include <dpdk/buffer.h>
24 #include <dpdk/ipsec/ipsec.h>
25 
27 
28 #define EMPTY_STRUCT {0}
29 #define NUM_CRYPTO_MBUFS 16384
30 
31 static void
32 algos_init (u32 n_mains)
33 {
35  crypto_alg_t *a;
36 
38 
39  {
40 #define _(v,f,str) \
41  dcm->cipher_algs[IPSEC_CRYPTO_ALG_##f].name = str; \
42  dcm->cipher_algs[IPSEC_CRYPTO_ALG_##f].disabled = n_mains;
44 #undef _
45  }
46 
47  /* Minimum boundary for ciphers is 4B, required by ESP */
48  a = &dcm->cipher_algs[IPSEC_CRYPTO_ALG_NONE];
49  a->type = RTE_CRYPTO_SYM_XFORM_CIPHER;
50  a->alg = RTE_CRYPTO_CIPHER_NULL;
51  a->boundary = 4; /* 1 */
52  a->key_len = 0;
53  a->iv_len = 0;
54 
55  a = &dcm->cipher_algs[IPSEC_CRYPTO_ALG_AES_CBC_128];
56  a->type = RTE_CRYPTO_SYM_XFORM_CIPHER;
57  a->alg = RTE_CRYPTO_CIPHER_AES_CBC;
58  a->boundary = 16;
59  a->key_len = 16;
60  a->iv_len = 16;
61 
62  a = &dcm->cipher_algs[IPSEC_CRYPTO_ALG_AES_CBC_192];
63  a->type = RTE_CRYPTO_SYM_XFORM_CIPHER;
64  a->alg = RTE_CRYPTO_CIPHER_AES_CBC;
65  a->boundary = 16;
66  a->key_len = 24;
67  a->iv_len = 16;
68 
69  a = &dcm->cipher_algs[IPSEC_CRYPTO_ALG_AES_CBC_256];
70  a->type = RTE_CRYPTO_SYM_XFORM_CIPHER;
71  a->alg = RTE_CRYPTO_CIPHER_AES_CBC;
72  a->boundary = 16;
73  a->key_len = 32;
74  a->iv_len = 16;
75 
76  a = &dcm->cipher_algs[IPSEC_CRYPTO_ALG_AES_CTR_128];
77  a->type = RTE_CRYPTO_SYM_XFORM_CIPHER;
78  a->alg = RTE_CRYPTO_CIPHER_AES_CTR;
79  a->boundary = 4; /* 1 */
80  a->key_len = 16;
81  a->iv_len = 8;
82 
83  a = &dcm->cipher_algs[IPSEC_CRYPTO_ALG_AES_CTR_192];
84  a->type = RTE_CRYPTO_SYM_XFORM_CIPHER;
85  a->alg = RTE_CRYPTO_CIPHER_AES_CTR;
86  a->boundary = 4; /* 1 */
87  a->key_len = 24;
88  a->iv_len = 8;
89 
90  a = &dcm->cipher_algs[IPSEC_CRYPTO_ALG_AES_CTR_256];
91  a->type = RTE_CRYPTO_SYM_XFORM_CIPHER;
92  a->alg = RTE_CRYPTO_CIPHER_AES_CTR;
93  a->boundary = 4; /* 1 */
94  a->key_len = 32;
95  a->iv_len = 8;
96 
97 #define AES_GCM_TYPE RTE_CRYPTO_SYM_XFORM_AEAD
98 #define AES_GCM_ALG RTE_CRYPTO_AEAD_AES_GCM
99 
100  a = &dcm->cipher_algs[IPSEC_CRYPTO_ALG_AES_GCM_128];
101  a->type = AES_GCM_TYPE;
102  a->alg = AES_GCM_ALG;
103  a->boundary = 4; /* 1 */
104  a->key_len = 16;
105  a->iv_len = 8;
106  a->trunc_size = 16;
107 
108  a = &dcm->cipher_algs[IPSEC_CRYPTO_ALG_AES_GCM_192];
109  a->type = AES_GCM_TYPE;
110  a->alg = AES_GCM_ALG;
111  a->boundary = 4; /* 1 */
112  a->key_len = 24;
113  a->iv_len = 8;
114  a->trunc_size = 16;
115 
116  a = &dcm->cipher_algs[IPSEC_CRYPTO_ALG_AES_GCM_256];
117  a->type = AES_GCM_TYPE;
118  a->alg = AES_GCM_ALG;
119  a->boundary = 4; /* 1 */
120  a->key_len = 32;
121  a->iv_len = 8;
122  a->trunc_size = 16;
123 
125 
126  {
127 #define _(v,f,str) \
128  dcm->auth_algs[IPSEC_INTEG_ALG_##f].name = str; \
129  dcm->auth_algs[IPSEC_INTEG_ALG_##f].disabled = n_mains;
131 #undef _
132  }
133 
134  a = &dcm->auth_algs[IPSEC_INTEG_ALG_NONE];
135  a->type = RTE_CRYPTO_SYM_XFORM_AUTH;
136  a->alg = RTE_CRYPTO_AUTH_NULL;
137  a->key_len = 0;
138  a->trunc_size = 0;
139 
140  a = &dcm->auth_algs[IPSEC_INTEG_ALG_MD5_96];
141  a->type = RTE_CRYPTO_SYM_XFORM_AUTH;
142  a->alg = RTE_CRYPTO_AUTH_MD5_HMAC;
143  a->key_len = 16;
144  a->trunc_size = 12;
145 
146  a = &dcm->auth_algs[IPSEC_INTEG_ALG_SHA1_96];
147  a->type = RTE_CRYPTO_SYM_XFORM_AUTH;
148  a->alg = RTE_CRYPTO_AUTH_SHA1_HMAC;
149  a->key_len = 20;
150  a->trunc_size = 12;
151 
152  a = &dcm->auth_algs[IPSEC_INTEG_ALG_SHA_256_96];
153  a->type = RTE_CRYPTO_SYM_XFORM_AUTH;
154  a->alg = RTE_CRYPTO_AUTH_SHA256_HMAC;
155  a->key_len = 32;
156  a->trunc_size = 12;
157 
158  a = &dcm->auth_algs[IPSEC_INTEG_ALG_SHA_256_128];
159  a->type = RTE_CRYPTO_SYM_XFORM_AUTH;
160  a->alg = RTE_CRYPTO_AUTH_SHA256_HMAC;
161  a->key_len = 32;
162  a->trunc_size = 16;
163 
164  a = &dcm->auth_algs[IPSEC_INTEG_ALG_SHA_384_192];
165  a->type = RTE_CRYPTO_SYM_XFORM_AUTH;
166  a->alg = RTE_CRYPTO_AUTH_SHA384_HMAC;
167  a->key_len = 48;
168  a->trunc_size = 24;
169 
170  a = &dcm->auth_algs[IPSEC_INTEG_ALG_SHA_512_256];
171  a->type = RTE_CRYPTO_SYM_XFORM_AUTH;
172  a->alg = RTE_CRYPTO_AUTH_SHA512_HMAC;
173  a->key_len = 64;
174  a->trunc_size = 32;
175 }
176 
177 static u8
179 {
181 
182  return (alg - dcm->cipher_algs);
183 }
184 
185 static u8
187 {
189 
190  return (alg - dcm->auth_algs);
191 }
192 
193 static crypto_alg_t *
194 cipher_cap_to_alg (const struct rte_cryptodev_capabilities *cap, u8 key_len)
195 {
197  crypto_alg_t *alg;
198 
199  if (cap->op != RTE_CRYPTO_OP_TYPE_SYMMETRIC)
200  return NULL;
201 
202  /* *INDENT-OFF* */
203  vec_foreach (alg, dcm->cipher_algs)
204  {
205  if ((cap->sym.xform_type == RTE_CRYPTO_SYM_XFORM_CIPHER) &&
206  (alg->type == RTE_CRYPTO_SYM_XFORM_CIPHER) &&
207  (cap->sym.cipher.algo == alg->alg) &&
208  (alg->key_len == key_len))
209  return alg;
210  if ((cap->sym.xform_type == RTE_CRYPTO_SYM_XFORM_AEAD) &&
211  (alg->type == RTE_CRYPTO_SYM_XFORM_AEAD) &&
212  (cap->sym.aead.algo == alg->alg) &&
213  (alg->key_len == key_len))
214  return alg;
215  }
216  /* *INDENT-ON* */
217 
218  return NULL;
219 }
220 
221 static crypto_alg_t *
222 auth_cap_to_alg (const struct rte_cryptodev_capabilities *cap, u8 trunc_size)
223 {
225  crypto_alg_t *alg;
226 
227  if ((cap->op != RTE_CRYPTO_OP_TYPE_SYMMETRIC) ||
228  (cap->sym.xform_type != RTE_CRYPTO_SYM_XFORM_AUTH))
229  return NULL;
230 
231  /* *INDENT-OFF* */
232  vec_foreach (alg, dcm->auth_algs)
233  {
234  if ((cap->sym.auth.algo == alg->alg) &&
235  (alg->trunc_size == trunc_size))
236  return alg;
237  }
238  /* *INDENT-ON* */
239 
240  return NULL;
241 }
242 
243 static void
244 crypto_set_aead_xform (struct rte_crypto_sym_xform *xform,
245  ipsec_sa_t * sa, u8 is_outbound)
246 {
248  crypto_alg_t *c;
249 
250  c = vec_elt_at_index (dcm->cipher_algs, sa->crypto_alg);
251 
252  ASSERT (c->type == RTE_CRYPTO_SYM_XFORM_AEAD);
253 
254  xform->type = RTE_CRYPTO_SYM_XFORM_AEAD;
255  xform->aead.algo = c->alg;
256  xform->aead.key.data = sa->crypto_key.data;
257  xform->aead.key.length = c->key_len;
258  xform->aead.iv.offset =
259  crypto_op_get_priv_offset () + offsetof (dpdk_op_priv_t, cb);
260  xform->aead.iv.length = 12;
261  xform->aead.digest_length = c->trunc_size;
262  xform->aead.aad_length = ipsec_sa_is_set_USE_ESN (sa) ? 12 : 8;
263  xform->next = NULL;
264 
265  if (is_outbound)
266  xform->aead.op = RTE_CRYPTO_AEAD_OP_ENCRYPT;
267  else
268  xform->aead.op = RTE_CRYPTO_AEAD_OP_DECRYPT;
269 }
270 
271 static void
272 crypto_set_cipher_xform (struct rte_crypto_sym_xform *xform,
273  ipsec_sa_t * sa, u8 is_outbound)
274 {
276  crypto_alg_t *c;
277 
278  c = vec_elt_at_index (dcm->cipher_algs, sa->crypto_alg);
279 
280  ASSERT (c->type == RTE_CRYPTO_SYM_XFORM_CIPHER);
281 
282  xform->type = RTE_CRYPTO_SYM_XFORM_CIPHER;
283  xform->cipher.algo = c->alg;
284  xform->cipher.key.data = sa->crypto_key.data;
285  xform->cipher.key.length = c->key_len;
286  xform->cipher.iv.offset =
287  crypto_op_get_priv_offset () + offsetof (dpdk_op_priv_t, cb);
288  xform->cipher.iv.length = c->iv_len;
289  xform->next = NULL;
290 
291  if (is_outbound)
292  xform->cipher.op = RTE_CRYPTO_CIPHER_OP_ENCRYPT;
293  else
294  xform->cipher.op = RTE_CRYPTO_CIPHER_OP_DECRYPT;
295 }
296 
297 static void
298 crypto_set_auth_xform (struct rte_crypto_sym_xform *xform,
299  ipsec_sa_t * sa, u8 is_outbound)
300 {
302  crypto_alg_t *a;
303 
304  a = vec_elt_at_index (dcm->auth_algs, sa->integ_alg);
305 
306  ASSERT (a->type == RTE_CRYPTO_SYM_XFORM_AUTH);
307 
308  xform->type = RTE_CRYPTO_SYM_XFORM_AUTH;
309  xform->auth.algo = a->alg;
310  xform->auth.key.data = sa->integ_key.data;
311  xform->auth.key.length = a->key_len;
312  xform->auth.digest_length = a->trunc_size;
313  xform->next = NULL;
314 
315  if (is_outbound)
316  xform->auth.op = RTE_CRYPTO_AUTH_OP_GENERATE;
317  else
318  xform->auth.op = RTE_CRYPTO_AUTH_OP_VERIFY;
319 }
320 
321 clib_error_t *
322 create_sym_session (struct rte_cryptodev_sym_session **session,
323  u32 sa_idx,
324  crypto_resource_t * res,
326 {
329  ipsec_sa_t *sa;
330  struct rte_crypto_sym_xform cipher_xform = { 0 };
331  struct rte_crypto_sym_xform auth_xform = { 0 };
332  struct rte_crypto_sym_xform *xfs;
333  struct rte_cryptodev_sym_session **s;
334  clib_error_t *error = 0;
335 
336  sa = ipsec_sa_get (sa_idx);
337 
338  if ((sa->crypto_alg == IPSEC_CRYPTO_ALG_AES_GCM_128) |
339  (sa->crypto_alg == IPSEC_CRYPTO_ALG_AES_GCM_192) |
340  (sa->crypto_alg == IPSEC_CRYPTO_ALG_AES_GCM_256))
341  {
342  crypto_set_aead_xform (&cipher_xform, sa, is_outbound);
343  xfs = &cipher_xform;
344  }
345  else
346  {
347  crypto_set_cipher_xform (&cipher_xform, sa, is_outbound);
348  crypto_set_auth_xform (&auth_xform, sa, is_outbound);
349 
350  if (is_outbound)
351  {
352  cipher_xform.next = &auth_xform;
353  xfs = &cipher_xform;
354  }
355  else
356  {
357  auth_xform.next = &cipher_xform;
358  xfs = &auth_xform;
359  }
360  }
361 
362  data = vec_elt_at_index (dcm->data, res->numa);
364 
365  /*
366  * DPDK_VER >= 1708:
367  * Multiple worker/threads share the session for an SA
368  * Single session per SA, initialized for each device driver
369  */
370  s = (void *) hash_get (data->session_by_sa_index, sa_idx);
371 
372  if (!s)
373  {
374  session[0] = rte_cryptodev_sym_session_create (data->session_h);
375  if (!session[0])
376  {
377  data->session_h_failed += 1;
378  error = clib_error_return (0, "failed to create session header");
379  goto done;
380  }
381  hash_set (data->session_by_sa_index, sa_idx, session[0]);
382  }
383  else
384  session[0] = s[0];
385 
386  struct rte_mempool **mp;
387  mp = vec_elt_at_index (data->session_drv, res->drv_id);
388  ASSERT (mp[0] != NULL);
389 
390  i32 ret =
391  rte_cryptodev_sym_session_init (res->dev_id, session[0], xfs, mp[0]);
392  if (ret)
393  {
394  data->session_drv_failed[res->drv_id] += 1;
395  error = clib_error_return (0, "failed to init session for drv %u",
396  res->drv_id);
397  goto done;
398  }
399 
400  add_session_by_drv_and_sa_idx (session[0], data, res->drv_id, sa_idx);
401 
402 done:
404  return error;
405 }
406 
407 static void __attribute__ ((unused)) clear_and_free_obj (void *obj)
408 {
409  struct rte_mempool *mp = rte_mempool_from_obj (obj);
410 
411  clib_memset (obj, 0, mp->elt_size);
412 
413  rte_mempool_put (mp, obj);
414 }
415 
416 /* This is from rte_cryptodev_pmd.h */
417 static inline void *
418 get_session_private_data (const struct rte_cryptodev_sym_session *sess,
419  uint8_t driver_id)
420 {
421 #if RTE_VERSION < RTE_VERSION_NUM(19, 2, 0, 0)
422  return sess->sess_private_data[driver_id];
423 #else
424  if (unlikely (sess->nb_drivers <= driver_id))
425  return 0;
426 
427  return sess->sess_data[driver_id].data;
428 #endif
429 }
430 
431 /* This is from rte_cryptodev_pmd.h */
432 static inline void
433 set_session_private_data (struct rte_cryptodev_sym_session *sess,
434  uint8_t driver_id, void *private_data)
435 {
436 #if RTE_VERSION < RTE_VERSION_NUM(19, 2, 0, 0)
437  sess->sess_private_data[driver_id] = private_data;
438 #else
439  if (unlikely (sess->nb_drivers <= driver_id))
440  return;
441  sess->sess_data[driver_id].data = private_data;
442 #endif
443 }
444 
445 static clib_error_t *
447 {
450  void *drv_session;
451  u32 drv_id;
452  i32 ret;
453 
454  /* *INDENT-OFF* */
455  vec_foreach (s, v)
456  {
457  /* ordered vector by timestamp */
458  if (!(s->ts + dcm->session_timeout < ts))
459  break;
460 
461  vec_foreach_index (drv_id, dcm->drv)
462  {
463  drv_session = get_session_private_data (s->session, drv_id);
464  if (!drv_session)
465  continue;
466 
467  /*
468  * Custom clear to avoid finding a dev_id for drv_id:
469  * ret = rte_cryptodev_sym_session_clear (dev_id, drv_session);
470  * ASSERT (!ret);
471  */
472  clear_and_free_obj (drv_session);
473 
474  set_session_private_data (s->session, drv_id, NULL);
475  }
476 
477  if (rte_mempool_from_obj(s->session))
478  {
479  ret = rte_cryptodev_sym_session_free (s->session);
480  ASSERT (!ret);
481  }
482  }
483  /* *INDENT-ON* */
484 
485  if (s < vec_end (v))
486  vec_delete (v, s - v, 0);
487  else
488  vec_reset_length (v);
489 
490  return 0;
491 }
492 
493 static clib_error_t *
494 add_del_sa_session (u32 sa_index, u8 is_add)
495 {
498  struct rte_cryptodev_sym_session *s;
499  uword *val;
500  u32 drv_id;
501 
502  if (is_add)
503  return 0;
504 
505  /* *INDENT-OFF* */
506  vec_foreach (data, dcm->data)
507  {
509  val = hash_get (data->session_by_sa_index, sa_index);
510  if (val)
511  {
512  s = (struct rte_cryptodev_sym_session *) val[0];
513  vec_foreach_index (drv_id, dcm->drv)
514  {
515  val = (uword*) get_session_by_drv_and_sa_idx (data, drv_id, sa_index);
516  if (val)
517  add_session_by_drv_and_sa_idx(NULL, data, drv_id, sa_index);
518  }
519 
520  hash_unset (data->session_by_sa_index, sa_index);
521 
522  u64 ts = unix_time_now_nsec ();
524 
526  sd.ts = ts;
527  sd.session = s;
528 
529  vec_add1 (data->session_disposal, sd);
530  }
532  }
533  /* *INDENT-ON* */
534 
535  return 0;
536 }
537 
538 static clib_error_t *
540 {
542 
543  if (sa->integ_alg == IPSEC_INTEG_ALG_NONE)
544  switch (sa->crypto_alg)
545  {
546  case IPSEC_CRYPTO_ALG_NONE:
547  case IPSEC_CRYPTO_ALG_AES_GCM_128:
548  case IPSEC_CRYPTO_ALG_AES_GCM_192:
549  case IPSEC_CRYPTO_ALG_AES_GCM_256:
550  break;
551  default:
552  return clib_error_return (0, "unsupported integ-alg %U crypto-alg %U",
555  }
556 
557  /* XXX do we need the NONE check? */
558  if (sa->crypto_alg != IPSEC_CRYPTO_ALG_NONE &&
559  dcm->cipher_algs[sa->crypto_alg].disabled)
560  return clib_error_return (0, "disabled crypto-alg %U",
562 
563  /* XXX do we need the NONE check? */
564  if (sa->integ_alg != IPSEC_INTEG_ALG_NONE &&
565  dcm->auth_algs[sa->integ_alg].disabled)
566  return clib_error_return (0, "disabled integ-alg %U",
568  return NULL;
569 }
570 
571 static void
573  const struct rte_cryptodev_capabilities *cap,
574  u32 n_mains)
575 {
577  crypto_alg_t *alg;
578  u8 len, inc;
579 
580  for (; cap->op != RTE_CRYPTO_OP_TYPE_UNDEFINED; cap++)
581  {
582  /* A single capability maps to multiple cipher/auth algorithms */
583  switch (cap->sym.xform_type)
584  {
585  case RTE_CRYPTO_SYM_XFORM_AEAD:
586  case RTE_CRYPTO_SYM_XFORM_CIPHER:
587  inc = cap->sym.cipher.key_size.increment;
588  inc = inc ? inc : 1;
589  for (len = cap->sym.cipher.key_size.min;
590  len <= cap->sym.cipher.key_size.max; len += inc)
591  {
592  alg = cipher_cap_to_alg (cap, len);
593  if (!alg)
594  continue;
595  dev->cipher_support[cipher_alg_index (alg)] = 1;
596  alg->resources += vec_len (dev->free_resources);
597  /* At least enough resources to support one algo */
598  dcm->enabled |= (alg->resources >= n_mains);
599  }
600  break;
601  case RTE_CRYPTO_SYM_XFORM_AUTH:
602  inc = cap->sym.auth.digest_size.increment;
603  inc = inc ? inc : 1;
604  for (len = cap->sym.auth.digest_size.min;
605  len <= cap->sym.auth.digest_size.max; len += inc)
606  {
607  alg = auth_cap_to_alg (cap, len);
608  if (!alg)
609  continue;
610  dev->auth_support[auth_alg_index (alg)] = 1;
611  alg->resources += vec_len (dev->free_resources);
612  /* At least enough resources to support one algo */
613  dcm->enabled |= (alg->resources >= n_mains);
614  }
615  break;
616  default:
617  ;
618  }
619  }
620 }
621 
622 static clib_error_t *
623 crypto_dev_conf (u8 dev, u16 n_qp, u8 numa)
624 {
625  struct rte_cryptodev_config dev_conf = { 0 };
626  struct rte_cryptodev_qp_conf qp_conf = { 0 };
627  i32 ret;
628  u16 qp;
629  char *error_str;
630 
631  dev_conf.socket_id = numa;
632  dev_conf.nb_queue_pairs = n_qp;
633 
634  error_str = "failed to configure crypto device %u";
635  ret = rte_cryptodev_configure (dev, &dev_conf);
636  if (ret < 0)
637  return clib_error_return (0, error_str, dev);
638 
639  error_str = "failed to setup crypto device %u queue pair %u";
640  qp_conf.nb_descriptors = DPDK_CRYPTO_N_QUEUE_DESC;
641  for (qp = 0; qp < n_qp; qp++)
642  {
643 #if RTE_VERSION < RTE_VERSION_NUM(19, 2, 0, 0)
644  ret = rte_cryptodev_queue_pair_setup (dev, qp, &qp_conf, numa, NULL);
645 #else
646  ret = rte_cryptodev_queue_pair_setup (dev, qp, &qp_conf, numa);
647 #endif
648  if (ret < 0)
649  return clib_error_return (0, error_str, dev, qp);
650  }
651 
652  error_str = "failed to start crypto device %u";
653  if (rte_cryptodev_start (dev))
654  return clib_error_return (0, error_str, dev);
655 
656  return 0;
657 }
658 
659 static void
661 {
663  struct rte_cryptodev *cryptodev;
664  struct rte_cryptodev_info info = { 0 };
665  crypto_dev_t *dev;
666  crypto_resource_t *res;
668  u32 i;
669  u16 max_res_idx, res_idx, j;
670  u8 drv_id;
671 
672  vec_validate_init_empty (dcm->dev, rte_cryptodev_count () - 1,
674 
675  for (i = 0; i < rte_cryptodev_count (); i++)
676  {
677  dev = vec_elt_at_index (dcm->dev, i);
678 
679  cryptodev = &rte_cryptodevs[i];
680  rte_cryptodev_info_get (i, &info);
681 
682  dev->id = i;
683  dev->name = cryptodev->data->name;
684  dev->numa = rte_cryptodev_socket_id (i);
685  dev->features = info.feature_flags;
686  dev->max_qp = info.max_nb_queue_pairs;
687  drv_id = info.driver_id;
688  if (drv_id >= vec_len (dcm->drv))
689  vec_validate_init_empty (dcm->drv, drv_id,
690  (crypto_drv_t) EMPTY_STRUCT);
691  vec_elt_at_index (dcm->drv, drv_id)->name = info.driver_name;
692  dev->drv_id = drv_id;
693  vec_add1 (vec_elt_at_index (dcm->drv, drv_id)->devs, i);
694 
695  if (!(info.feature_flags & RTE_CRYPTODEV_FF_SYM_OPERATION_CHAINING))
696  continue;
697 
698  if ((error = crypto_dev_conf (i, dev->max_qp, dev->numa)))
699  {
700  clib_error_report (error);
701  continue;
702  }
703 
704  max_res_idx = dev->max_qp - 1;
705 
706  vec_validate (dev->free_resources, max_res_idx);
707 
708  res_idx = vec_len (dcm->resource);
709  vec_validate_init_empty_aligned (dcm->resource, res_idx + max_res_idx,
710  (crypto_resource_t) EMPTY_STRUCT,
712 
713  for (j = 0; j <= max_res_idx; j++)
714  {
715  vec_elt (dev->free_resources, max_res_idx - j) = res_idx + j;
716  res = &dcm->resource[res_idx + j];
717  res->dev_id = i;
718  res->drv_id = drv_id;
719  res->qp_id = j;
720  res->numa = dev->numa;
721  res->thread_idx = (u16) ~ 0;
722  }
723 
724  crypto_parse_capabilities (dev, info.capabilities, n_mains);
725  }
726 }
727 
728 void
730 {
732  crypto_resource_t *res;
734  crypto_dev_t *dev;
735  u32 thread_idx, skip_master;
736  u16 res_idx, *idx;
737  u8 used;
738  u16 i;
739 
740  skip_master = vlib_num_workers () > 0;
741 
742  /* *INDENT-OFF* */
743  vec_foreach (dev, dcm->dev)
744  {
745  vec_foreach_index (thread_idx, dcm->workers_main)
746  {
747  if (vec_len (dev->free_resources) == 0)
748  break;
749 
750  if (thread_idx < skip_master)
751  continue;
752 
753  /* Check thread is not already using the device */
754  vec_foreach (idx, dev->used_resources)
755  if (dcm->resource[idx[0]].thread_idx == thread_idx)
756  continue;
757 
758  cwm = vec_elt_at_index (dcm->workers_main, thread_idx);
759 
760  used = 0;
761  res_idx = vec_pop (dev->free_resources);
762 
763  /* Set device only for supported algos */
764  for (i = 0; i < IPSEC_CRYPTO_N_ALG; i++)
765  if (dev->cipher_support[i] &&
766  cwm->cipher_resource_idx[i] == (u16) ~0)
767  {
768  dcm->cipher_algs[i].disabled--;
769  cwm->cipher_resource_idx[i] = res_idx;
770  used = 1;
771  }
772 
773  for (i = 0; i < IPSEC_INTEG_N_ALG; i++)
774  if (dev->auth_support[i] &&
775  cwm->auth_resource_idx[i] == (u16) ~0)
776  {
777  dcm->auth_algs[i].disabled--;
778  cwm->auth_resource_idx[i] = res_idx;
779  used = 1;
780  }
781 
782  if (!used)
783  {
784  vec_add1 (dev->free_resources, res_idx);
785  continue;
786  }
787 
788  vec_add1 (dev->used_resources, res_idx);
789 
790  res = vec_elt_at_index (dcm->resource, res_idx);
791 
792  ASSERT (res->thread_idx == (u16) ~0);
793  res->thread_idx = thread_idx;
794 
795  /* Add device to vector of polling resources */
796  vec_add1 (cwm->resource_idx, res_idx);
797  }
798  }
799  /* *INDENT-ON* */
800 }
801 
802 static void
803 crypto_op_init (struct rte_mempool *mempool,
804  void *_arg __attribute__ ((unused)),
805  void *_obj, unsigned i __attribute__ ((unused)))
806 {
807  struct rte_crypto_op *op = _obj;
808 
809  op->sess_type = RTE_CRYPTO_OP_WITH_SESSION;
810  op->type = RTE_CRYPTO_OP_TYPE_SYMMETRIC;
811  op->status = RTE_CRYPTO_OP_STATUS_NOT_PROCESSED;
812  op->phys_addr = rte_mempool_virt2iova (_obj);
813  op->mempool = mempool;
814 }
815 
816 static clib_error_t *
818 {
822  u8 *pool_name;
823  u32 pool_priv_size = sizeof (struct rte_crypto_op_pool_private);
824  struct rte_crypto_op_pool_private *priv;
825  struct rte_mempool *mp;
826 
827  data = vec_elt_at_index (dcm->data, numa);
828 
829  /* Already allocated */
830  if (data->crypto_op)
831  return NULL;
832 
833  pool_name = format (0, "crypto_pool_numa%u%c", numa, 0);
834 
835  if (conf->num_crypto_mbufs == 0)
837 
838  mp = rte_mempool_create ((char *) pool_name, conf->num_crypto_mbufs,
839  crypto_op_len (), 512, pool_priv_size, NULL, NULL,
840  crypto_op_init, NULL, numa, 0);
841 
842  vec_free (pool_name);
843 
844  if (!mp)
845  return clib_error_return (0, "failed to create crypto op mempool");
846 
847  /* Initialize mempool private data */
848  priv = rte_mempool_get_priv (mp);
849  priv->priv_size = pool_priv_size;
850  priv->type = RTE_CRYPTO_OP_TYPE_SYMMETRIC;
851 
852  data->crypto_op = mp;
853 
854  return NULL;
855 }
856 
857 static clib_error_t *
859 {
862  u8 *pool_name;
863  struct rte_mempool *mp;
864  u32 elt_size;
865 
866  data = vec_elt_at_index (dcm->data, numa);
867 
868  if (data->session_h)
869  return NULL;
870 
871  pool_name = format (0, "session_h_pool_numa%u%c", numa, 0);
872 
873 
874  elt_size = rte_cryptodev_sym_get_header_session_size ();
875 
876 #if RTE_VERSION < RTE_VERSION_NUM(19, 2, 0, 0)
877  mp = rte_mempool_create ((char *) pool_name, DPDK_CRYPTO_NB_SESS_OBJS,
878  elt_size, 512, 0, NULL, NULL, NULL, NULL, numa, 0);
879 #else
880  /* XXX Experimental tag in DPDK 19.02 */
881  mp = rte_cryptodev_sym_session_pool_create ((char *) pool_name,
883  elt_size, 512, 0, numa);
884 #endif
885  vec_free (pool_name);
886 
887  if (!mp)
888  return clib_error_return (0, "failed to create crypto session mempool");
889 
890  data->session_h = mp;
891 
892  return NULL;
893 }
894 
895 static clib_error_t *
897 {
900  u8 *pool_name;
901  struct rte_mempool *mp;
902  u32 elt_size;
903  u8 numa = dev->numa;
904 
905  data = vec_elt_at_index (dcm->data, numa);
906 
907  vec_validate (data->session_drv, dev->drv_id);
908  vec_validate (data->session_drv_failed, dev->drv_id);
911 
912  if (data->session_drv[dev->drv_id])
913  return NULL;
914 
915  pool_name = format (0, "session_drv%u_pool_numa%u%c", dev->drv_id, numa, 0);
916 
917  elt_size = rte_cryptodev_sym_get_private_session_size (dev->id);
918  mp =
919  rte_mempool_create ((char *) pool_name, DPDK_CRYPTO_NB_SESS_OBJS,
920  elt_size, 512, 0, NULL, NULL, NULL, NULL, numa, 0);
921 
922  vec_free (pool_name);
923 
924  if (!mp)
925  return clib_error_return (0, "failed to create session drv mempool");
926 
927  data->session_drv[dev->drv_id] = mp;
928  clib_spinlock_init (&data->lockp);
929 
930  return NULL;
931 }
932 
933 static clib_error_t *
935 {
937  clib_error_t *error = NULL;
938  crypto_dev_t *dev;
939 
940  /* *INDENT-OFF* */
941  vec_foreach (dev, dcm->dev)
942  {
944 
945  error = crypto_create_crypto_op_pool (vm, dev->numa);
946  if (error)
947  return error;
948 
949  error = crypto_create_session_h_pool (vm, dev->numa);
950  if (error)
951  return error;
952 
953  error = crypto_create_session_drv_pool (vm, dev);
954  if (error)
955  return error;
956  }
957  /* *INDENT-ON* */
958 
959  return NULL;
960 }
961 
962 static void
964 {
967  u8 i;
968 
969  dcm->enabled = 0;
970 
971  /* *INDENT-OFF* */
972  vec_foreach (data, dcm->data)
973  {
974  rte_mempool_free (data->crypto_op);
975  rte_mempool_free (data->session_h);
976 
977  vec_foreach_index (i, data->session_drv)
978  rte_mempool_free (data->session_drv[i]);
979 
980  vec_free (data->session_drv);
981  clib_spinlock_free (&data->lockp);
982  }
983  /* *INDENT-ON* */
984 
985  vec_free (dcm->data);
986  vec_free (dcm->workers_main);
987  vec_free (dcm->dev);
988  vec_free (dcm->resource);
989  vec_free (dcm->cipher_algs);
990  vec_free (dcm->auth_algs);
991 }
992 
993 static clib_error_t *
995 {
998  vlib_node_t *node = vlib_get_node_by_name (vm, (u8 *) "dpdk-crypto-input");
999  u32 skip_master = vlib_num_workers () > 0;
1000  u32 n_mains = tm->n_vlib_mains;
1001  u32 i;
1002 
1003  ASSERT (node);
1004  for (i = skip_master; i < n_mains; i++)
1005  vlib_node_set_state (vlib_mains[i], node->index, is_enable != 0 ?
1006  VLIB_NODE_STATE_POLLING : VLIB_NODE_STATE_DISABLED);
1007 
1008  return 0;
1009 }
1010 
1011 static clib_error_t *
1013 {
1017  crypto_worker_main_t *cwm;
1018  clib_error_t *error = NULL;
1019  u32 skip_master, n_mains;
1020 
1021  n_mains = tm->n_vlib_mains;
1022  skip_master = vlib_num_workers () > 0;
1023 
1024  algos_init (n_mains - skip_master);
1025 
1026  crypto_scan_devs (n_mains - skip_master);
1027 
1028  if (!(dcm->enabled))
1029  {
1031  "not enough DPDK crypto resources");
1032  crypto_disable ();
1033  return 0;
1034  }
1035 
1036  dcm->session_timeout = 10e9;
1037 
1038  vec_validate_init_empty_aligned (dcm->workers_main, n_mains - 1,
1041 
1042  /* *INDENT-OFF* */
1043  vec_foreach (cwm, dcm->workers_main)
1044  {
1047  clib_memset (cwm->cipher_resource_idx, ~0,
1048  IPSEC_CRYPTO_N_ALG * sizeof(*cwm->cipher_resource_idx));
1049  clib_memset (cwm->auth_resource_idx, ~0,
1050  IPSEC_INTEG_N_ALG * sizeof(*cwm->auth_resource_idx));
1051  }
1052  /* *INDENT-ON* */
1053 
1055 
1056  error = crypto_create_pools (vm);
1057  if (error)
1058  {
1059  clib_error_report (error);
1060  crypto_disable ();
1061  return 0;
1062  }
1063 
1065  vm, im, "dpdk backend", "dpdk-esp4-encrypt", "dpdk-esp4-encrypt-tun",
1066  "dpdk-esp4-decrypt", "dpdk-esp4-decrypt", "dpdk-esp6-encrypt",
1067  "dpdk-esp6-encrypt-tun", "dpdk-esp6-decrypt", "dpdk-esp6-decrypt",
1070  int rv;
1071  if (im->esp_current_backend == ~0)
1072  {
1073  rv = ipsec_select_esp_backend (im, idx);
1074  ASSERT (rv == 0);
1075  }
1076  return 0;
1077 }
1078 
1080 
1081 /*
1082  * fd.io coding-style-patch-verification: ON
1083  *
1084  * Local Variables:
1085  * eval: (c-set-style "gnu")
1086  * End:
1087  */
#define vec_validate(V, I)
Make sure vector is long enough for given index (no header, unspecified alignment) ...
Definition: vec.h:524
u32 alg
Definition: ipsec.h:88
u8 * format_ipsec_integ_alg(u8 *s, va_list *args)
Definition: ipsec_format.c:111
#define vec_foreach_index(var, v)
Iterate over vector indices.
#define hash_set(h, key, value)
Definition: hash.h:255
#define hash_unset(h, key)
Definition: hash.h:261
a
Definition: bitmap.h:544
static clib_error_t * dpdk_ipsec_enable_disable(int is_enable)
Definition: ipsec.c:994
dpdk_main_t dpdk_main
Definition: init.c:48
#define VLIB_MAIN_LOOP_ENTER_FUNCTION(x)
Definition: init.h:175
unsigned long u64
Definition: types.h:89
clib_memset(h->entries, 0, sizeof(h->entries[0]) *entries)
u32 index
Definition: node.h:270
u64 session_h_failed
Definition: ipsec.h:154
#define foreach_ipsec_crypto_alg
Definition: ipsec_sa.h:24
static void crypto_parse_capabilities(crypto_dev_t *dev, const struct rte_cryptodev_capabilities *cap, u32 n_mains)
Definition: ipsec.c:572
ipsec_key_t crypto_key
Definition: ipsec_sa.h:221
static clib_error_t * dpdk_ipsec_check_support(ipsec_sa_t *sa)
Definition: ipsec.c:539
static_always_inline void clib_spinlock_unlock_if_init(clib_spinlock_t *p)
Definition: lock.h:129
ipsec_integ_alg_t integ_alg
Definition: ipsec_sa.h:218
#define thread_idx
Definition: tls_async.c:40
#define vec_add1(V, E)
Add 1 element to end of vector (unspecified alignment).
Definition: vec.h:607
u16 key_len
Definition: ikev2_types.api:95
#define foreach_ipsec_integ_alg
Definition: ipsec_sa.h:56
struct rte_cryptodev_sym_session * session
Definition: ipsec.h:136
u8 disabled
Definition: ipsec.h:93
static clib_error_t * dpdk_crypto_session_disposal(crypto_session_disposal_t *v, u64 ts)
Definition: ipsec.c:446
static void set_session_private_data(struct rte_cryptodev_sym_session *sess, uint8_t driver_id, void *private_data)
Definition: ipsec.c:433
static void clear_and_free_obj(void *obj)
Definition: ipsec.c:407
#define vec_validate_aligned(V, I, A)
Make sure vector is long enough for given index (no header, specified alignment)
Definition: vec.h:535
u32 esp_current_backend
Definition: ipsec.h:178
unsigned char u8
Definition: types.h:56
#define vec_pop(V)
Returns last element of a vector and decrements its length.
Definition: vec.h:706
u8 data[128]
Definition: ipsec_types.api:92
#define vec_reset_length(v)
Reset vector length to zero NULL-pointer tolerant.
static void clib_spinlock_free(clib_spinlock_t *p)
Definition: lock.h:72
unsigned int u32
Definition: types.h:88
u16 * resource_idx
Definition: ipsec.h:76
bool is_outbound
Definition: ipsec.api:96
u16 cipher_resource_idx[IPSEC_CRYPTO_N_ALG]
Definition: ipsec.h:78
dpdk_config_main_t dpdk_config_main
Definition: init.c:49
u8 resources
Definition: ipsec.h:94
description fragment has unexpected format
Definition: map.api:433
crypto_drv_t * drv
Definition: ipsec.h:170
#define vec_elt_at_index(v, i)
Get vector value at index i checking that i is in bounds.
u8 drv_id
Definition: ipsec.h:103
#define clib_error_return(e, args...)
Definition: error.h:99
static clib_error_t * crypto_create_pools(vlib_main_t *vm)
Definition: ipsec.c:934
u16 * free_resources
Definition: ipsec.h:99
u8 * format_ipsec_crypto_alg(u8 *s, va_list *args)
Definition: ipsec_format.c:79
#define vec_end(v)
End (last data address) of vector.
static clib_error_t * crypto_dev_conf(u8 dev, u16 n_qp, u8 numa)
Definition: ipsec.c:623
int __clib_unused rv
Definition: application.c:491
crypto_alg_t * auth_algs
Definition: ipsec.h:168
#define VLIB_FRAME_SIZE
Definition: node.h:369
u8 trunc_size
Definition: ipsec.h:91
static crypto_alg_t * auth_cap_to_alg(const struct rte_cryptodev_capabilities *cap, u8 trunc_size)
Definition: ipsec.c:222
static clib_error_t * dpdk_ipsec_main_init(vlib_main_t *vm)
Definition: ipsec.c:1012
#define AES_GCM_ALG
static void crypto_scan_devs(u32 n_mains)
Definition: ipsec.c:660
static void crypto_set_cipher_xform(struct rte_crypto_sym_xform *xform, ipsec_sa_t *sa, u8 is_outbound)
Definition: ipsec.c:272
static void clib_spinlock_init(clib_spinlock_t *p)
Definition: lock.h:65
clib_spinlock_t lockp
Definition: ipsec.h:157
Definition: cJSON.c:88
u16 * used_resources
Definition: ipsec.h:100
#define hash_get(h, key)
Definition: hash.h:249
static crypto_alg_t * cipher_cap_to_alg(const struct rte_cryptodev_capabilities *cap, u8 key_len)
Definition: ipsec.c:194
dpdk_crypto_main_t dpdk_crypto_main
Definition: ipsec.c:26
vlib_node_t * vlib_get_node_by_name(vlib_main_t *vm, u8 *name)
Definition: node.c:45
static clib_error_t * crypto_create_crypto_op_pool(vlib_main_t *vm, u8 numa)
Definition: ipsec.c:817
crypto_alg_t * cipher_algs
Definition: ipsec.h:167
unsigned short u16
Definition: types.h:57
#define DPDK_CRYPTO_N_QUEUE_DESC
Definition: ipsec.h:34
static void algos_init(u32 n_mains)
Definition: ipsec.c:32
u64 features
Definition: ipsec.h:108
#define NUM_CRYPTO_MBUFS
Definition: ipsec.c:29
u64 session_timeout
Definition: ipsec.h:171
static_always_inline u32 crypto_op_get_priv_offset(void)
Definition: ipsec.h:197
vlib_main_t * vm
X-connect all packets from the HOST to the PHY.
Definition: nat44_ei.c:3047
static clib_error_t * crypto_create_session_drv_pool(vlib_main_t *vm, crypto_dev_t *dev)
Definition: ipsec.c:896
static u8 auth_alg_index(const crypto_alg_t *alg)
Definition: ipsec.c:186
#define AES_GCM_TYPE
struct rte_mempool ** session_drv
Definition: ipsec.h:150
u8 len
Definition: ip_types.api:103
vlib node functions
#define EMPTY_STRUCT
Definition: ipsec.c:28
crypto_session_by_drv_t * session_by_drv_id_and_sa_index
Definition: ipsec.h:156
u32 num_crypto_mbufs
Definition: dpdk.h:317
svmdb_client_t * c
sll srl srl sll sra u16x4 i
Definition: vector_sse42.h:261
#define vec_free(V)
Free vector&#39;s memory (no header).
Definition: vec.h:395
vnet_interface_main_t * im
static u64 unix_time_now_nsec(void)
Definition: time.h:270
crypto_session_disposal_t * session_disposal
Definition: ipsec.h:151
u16 id
Definition: ipsec.h:105
u8 iv_len
Definition: ipsec.h:90
clib_error_t * create_sym_session(struct rte_cryptodev_sym_session **session, u32 sa_idx, crypto_resource_t *res, crypto_worker_main_t *cwm, u8 is_outbound)
Definition: ipsec.c:322
signed int i32
Definition: types.h:77
u8 data[IPSEC_KEY_MAX_LEN]
Definition: ipsec_sa.h:83
#define ASSERT(truth)
static clib_error_t * add_del_sa_session(u32 sa_index, u8 is_add)
Definition: ipsec.c:494
static u8 cipher_alg_index(const crypto_alg_t *alg)
Definition: ipsec.c:178
static_always_inline u32 crypto_op_len(void)
Definition: ipsec.h:187
#define vec_delete(V, N, M)
Delete N elements starting at element M.
Definition: vec.h:876
static void crypto_op_init(struct rte_mempool *mempool, void *_arg, void *_obj, unsigned i)
Definition: ipsec.c:803
struct rte_mempool * crypto_op
Definition: ipsec.h:148
u32 max_qp
Definition: ipsec.h:107
vlib_log_class_t log_default
Definition: dpdk.h:382
crypto_worker_main_t * workers_main
Definition: ipsec.h:164
#define clib_error_report(e)
Definition: error.h:113
u32 ipsec_register_esp_backend(vlib_main_t *vm, ipsec_main_t *im, const char *name, const char *esp4_encrypt_node_name, const char *esp4_encrypt_node_tun_name, const char *esp4_decrypt_node_name, const char *esp4_decrypt_tun_node_name, const char *esp6_encrypt_node_name, const char *esp6_encrypt_node_tun_name, const char *esp6_decrypt_node_name, const char *esp6_decrypt_tun_node_name, const char *esp_mpls_encrypt_node_tun_name, check_support_cb_t esp_check_support_cb, add_del_sa_sess_cb_t esp_add_del_sa_sess_cb, enable_disable_cb_t enable_disable_cb)
Definition: ipsec.c:200
static void vlib_node_set_state(vlib_main_t *vm, u32 node_index, vlib_node_state_t new_state)
Set node dispatch state.
Definition: node_funcs.h:175
static_always_inline struct rte_cryptodev_sym_session * get_session_by_drv_and_sa_idx(crypto_data_t *data, u32 drv_id, u32 sa_idx)
Definition: ipsec.h:228
static void crypto_set_aead_xform(struct rte_crypto_sym_xform *xform, ipsec_sa_t *sa, u8 is_outbound)
Definition: ipsec.c:244
static void * get_session_private_data(const struct rte_cryptodev_sym_session *sess, uint8_t driver_id)
Definition: ipsec.c:418
crypto_resource_t * resource
Definition: ipsec.h:166
static vlib_main_t * vlib_get_main(void)
Definition: global_funcs.h:38
#define vec_elt(v, i)
Get vector value at index i.
struct rte_mempool * session_h
Definition: ipsec.h:149
void crypto_auto_placement(void)
Definition: ipsec.c:729
static void crypto_disable(void)
Definition: ipsec.c:963
static ipsec_sa_t * ipsec_sa_get(u32 sa_index)
Definition: ipsec_sa.h:519
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
vlib_main_t vlib_node_runtime_t * node
Definition: nat44_ei.c:3047
ipsec_main_t ipsec_main
Definition: ipsec.c:28
u64 * session_drv_failed
Definition: ipsec.h:155
u64 uword
Definition: types.h:112
uword * session_by_sa_index
Definition: ipsec.h:152
static_always_inline void add_session_by_drv_and_sa_idx(struct rte_cryptodev_sym_session *session, crypto_data_t *data, u32 drv_id, u32 sa_idx)
Definition: ipsec.h:216
const char * name
Definition: ipsec.h:106
struct rte_crypto_op ** ops
Definition: ipsec.h:77
int ipsec_select_esp_backend(ipsec_main_t *im, u32 backend_idx)
Definition: ipsec.c:280
crypto_dev_t * dev
Definition: ipsec.h:165
enum rte_crypto_sym_xform_type type
Definition: ipsec.h:87
static void crypto_set_auth_xform(struct rte_crypto_sym_xform *xform, ipsec_sa_t *sa, u8 is_outbound)
Definition: ipsec.c:298
crypto_data_t * data
Definition: ipsec.h:169
ipsec_crypto_alg_t crypto_alg
Definition: ipsec_sa.h:217
static vlib_thread_main_t * vlib_get_thread_main()
Definition: global_funcs.h:56
static u32 vlib_num_workers()
Definition: threads.h:354
#define DPDK_CRYPTO_NB_SESS_OBJS
Definition: ipsec.h:35
u16 auth_resource_idx[IPSEC_INTEG_N_ALG]
Definition: ipsec.h:79
u8 auth_support[IPSEC_INTEG_N_ALG]
Definition: ipsec.h:102
#define vec_validate_init_empty_aligned(V, I, INIT, A)
Make sure vector is long enough for given index and initialize empty space (no header, alignment alignment)
Definition: vec.h:583
#define vec_foreach(var, vec)
Vector iterator.
u8 key_len
Definition: ipsec.h:89
#define vec_validate_init_empty(V, I, INIT)
Make sure vector is long enough for given index and initialize empty space (no header, unspecified alignment)
Definition: vec.h:571
#define CLIB_CACHE_LINE_BYTES
Definition: cache.h:59
ipsec_key_t integ_key
Definition: ipsec_sa.h:220
static_always_inline void clib_spinlock_lock_if_init(clib_spinlock_t *p)
Definition: lock.h:106
#define vlib_log_warn(...)
Definition: log.h:134
u8 cipher_support[IPSEC_CRYPTO_N_ALG]
Definition: ipsec.h:101
static clib_error_t * crypto_create_session_h_pool(vlib_main_t *vm, u8 numa)
Definition: ipsec.c:858