FD.io VPP  v21.01.1
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 {
328  ipsec_main_t *im = &ipsec_main;
330  ipsec_sa_t *sa;
331  struct rte_crypto_sym_xform cipher_xform = { 0 };
332  struct rte_crypto_sym_xform auth_xform = { 0 };
333  struct rte_crypto_sym_xform *xfs;
334  struct rte_cryptodev_sym_session **s;
335  clib_error_t *error = 0;
336 
337 
338  sa = pool_elt_at_index (im->sad, sa_idx);
339 
340  if ((sa->crypto_alg == IPSEC_CRYPTO_ALG_AES_GCM_128) |
341  (sa->crypto_alg == IPSEC_CRYPTO_ALG_AES_GCM_192) |
342  (sa->crypto_alg == IPSEC_CRYPTO_ALG_AES_GCM_256))
343  {
344  crypto_set_aead_xform (&cipher_xform, sa, is_outbound);
345  xfs = &cipher_xform;
346  }
347  else
348  {
349  crypto_set_cipher_xform (&cipher_xform, sa, is_outbound);
350  crypto_set_auth_xform (&auth_xform, sa, is_outbound);
351 
352  if (is_outbound)
353  {
354  cipher_xform.next = &auth_xform;
355  xfs = &cipher_xform;
356  }
357  else
358  {
359  auth_xform.next = &cipher_xform;
360  xfs = &auth_xform;
361  }
362  }
363 
364  data = vec_elt_at_index (dcm->data, res->numa);
366 
367  /*
368  * DPDK_VER >= 1708:
369  * Multiple worker/threads share the session for an SA
370  * Single session per SA, initialized for each device driver
371  */
372  s = (void *) hash_get (data->session_by_sa_index, sa_idx);
373 
374  if (!s)
375  {
376  session[0] = rte_cryptodev_sym_session_create (data->session_h);
377  if (!session[0])
378  {
379  data->session_h_failed += 1;
380  error = clib_error_return (0, "failed to create session header");
381  goto done;
382  }
383  hash_set (data->session_by_sa_index, sa_idx, session[0]);
384  }
385  else
386  session[0] = s[0];
387 
388  struct rte_mempool **mp;
389  mp = vec_elt_at_index (data->session_drv, res->drv_id);
390  ASSERT (mp[0] != NULL);
391 
392  i32 ret =
393  rte_cryptodev_sym_session_init (res->dev_id, session[0], xfs, mp[0]);
394  if (ret)
395  {
396  data->session_drv_failed[res->drv_id] += 1;
397  error = clib_error_return (0, "failed to init session for drv %u",
398  res->drv_id);
399  goto done;
400  }
401 
402  add_session_by_drv_and_sa_idx (session[0], data, res->drv_id, sa_idx);
403 
404 done:
406  return error;
407 }
408 
409 static void __attribute__ ((unused)) clear_and_free_obj (void *obj)
410 {
411  struct rte_mempool *mp = rte_mempool_from_obj (obj);
412 
413  clib_memset (obj, 0, mp->elt_size);
414 
415  rte_mempool_put (mp, obj);
416 }
417 
418 /* This is from rte_cryptodev_pmd.h */
419 static inline void *
420 get_session_private_data (const struct rte_cryptodev_sym_session *sess,
421  uint8_t driver_id)
422 {
423 #if RTE_VERSION < RTE_VERSION_NUM(19, 2, 0, 0)
424  return sess->sess_private_data[driver_id];
425 #else
426  if (unlikely (sess->nb_drivers <= driver_id))
427  return 0;
428 
429  return sess->sess_data[driver_id].data;
430 #endif
431 }
432 
433 /* This is from rte_cryptodev_pmd.h */
434 static inline void
435 set_session_private_data (struct rte_cryptodev_sym_session *sess,
436  uint8_t driver_id, void *private_data)
437 {
438 #if RTE_VERSION < RTE_VERSION_NUM(19, 2, 0, 0)
439  sess->sess_private_data[driver_id] = private_data;
440 #else
441  if (unlikely (sess->nb_drivers <= driver_id))
442  return;
443  sess->sess_data[driver_id].data = private_data;
444 #endif
445 }
446 
447 static clib_error_t *
449 {
452  void *drv_session;
453  u32 drv_id;
454  i32 ret;
455 
456  /* *INDENT-OFF* */
457  vec_foreach (s, v)
458  {
459  /* ordered vector by timestamp */
460  if (!(s->ts + dcm->session_timeout < ts))
461  break;
462 
463  vec_foreach_index (drv_id, dcm->drv)
464  {
465  drv_session = get_session_private_data (s->session, drv_id);
466  if (!drv_session)
467  continue;
468 
469  /*
470  * Custom clear to avoid finding a dev_id for drv_id:
471  * ret = rte_cryptodev_sym_session_clear (dev_id, drv_session);
472  * ASSERT (!ret);
473  */
474  clear_and_free_obj (drv_session);
475 
476  set_session_private_data (s->session, drv_id, NULL);
477  }
478 
479  if (rte_mempool_from_obj(s->session))
480  {
481  ret = rte_cryptodev_sym_session_free (s->session);
482  ASSERT (!ret);
483  }
484  }
485  /* *INDENT-ON* */
486 
487  if (s < vec_end (v))
488  vec_delete (v, s - v, 0);
489  else
490  vec_reset_length (v);
491 
492  return 0;
493 }
494 
495 static clib_error_t *
496 add_del_sa_session (u32 sa_index, u8 is_add)
497 {
500  struct rte_cryptodev_sym_session *s;
501  uword *val;
502  u32 drv_id;
503 
504  if (is_add)
505  return 0;
506 
507  /* *INDENT-OFF* */
508  vec_foreach (data, dcm->data)
509  {
511  val = hash_get (data->session_by_sa_index, sa_index);
512  if (val)
513  {
514  s = (struct rte_cryptodev_sym_session *) val[0];
515  vec_foreach_index (drv_id, dcm->drv)
516  {
517  val = (uword*) get_session_by_drv_and_sa_idx (data, drv_id, sa_index);
518  if (val)
519  add_session_by_drv_and_sa_idx(NULL, data, drv_id, sa_index);
520  }
521 
522  hash_unset (data->session_by_sa_index, sa_index);
523 
524  u64 ts = unix_time_now_nsec ();
526 
528  sd.ts = ts;
529  sd.session = s;
530 
531  vec_add1 (data->session_disposal, sd);
532  }
534  }
535  /* *INDENT-ON* */
536 
537  return 0;
538 }
539 
540 static clib_error_t *
542 {
544 
545  if (sa->integ_alg == IPSEC_INTEG_ALG_NONE)
546  switch (sa->crypto_alg)
547  {
548  case IPSEC_CRYPTO_ALG_NONE:
549  case IPSEC_CRYPTO_ALG_AES_GCM_128:
550  case IPSEC_CRYPTO_ALG_AES_GCM_192:
551  case IPSEC_CRYPTO_ALG_AES_GCM_256:
552  break;
553  default:
554  return clib_error_return (0, "unsupported integ-alg %U crypto-alg %U",
557  }
558 
559  /* XXX do we need the NONE check? */
560  if (sa->crypto_alg != IPSEC_CRYPTO_ALG_NONE &&
561  dcm->cipher_algs[sa->crypto_alg].disabled)
562  return clib_error_return (0, "disabled crypto-alg %U",
564 
565  /* XXX do we need the NONE check? */
566  if (sa->integ_alg != IPSEC_INTEG_ALG_NONE &&
567  dcm->auth_algs[sa->integ_alg].disabled)
568  return clib_error_return (0, "disabled integ-alg %U",
570  return NULL;
571 }
572 
573 static void
575  const struct rte_cryptodev_capabilities *cap,
576  u32 n_mains)
577 {
579  crypto_alg_t *alg;
580  u8 len, inc;
581 
582  for (; cap->op != RTE_CRYPTO_OP_TYPE_UNDEFINED; cap++)
583  {
584  /* A single capability maps to multiple cipher/auth algorithms */
585  switch (cap->sym.xform_type)
586  {
587  case RTE_CRYPTO_SYM_XFORM_AEAD:
588  case RTE_CRYPTO_SYM_XFORM_CIPHER:
589  inc = cap->sym.cipher.key_size.increment;
590  inc = inc ? inc : 1;
591  for (len = cap->sym.cipher.key_size.min;
592  len <= cap->sym.cipher.key_size.max; len += inc)
593  {
594  alg = cipher_cap_to_alg (cap, len);
595  if (!alg)
596  continue;
597  dev->cipher_support[cipher_alg_index (alg)] = 1;
598  alg->resources += vec_len (dev->free_resources);
599  /* At least enough resources to support one algo */
600  dcm->enabled |= (alg->resources >= n_mains);
601  }
602  break;
603  case RTE_CRYPTO_SYM_XFORM_AUTH:
604  inc = cap->sym.auth.digest_size.increment;
605  inc = inc ? inc : 1;
606  for (len = cap->sym.auth.digest_size.min;
607  len <= cap->sym.auth.digest_size.max; len += inc)
608  {
609  alg = auth_cap_to_alg (cap, len);
610  if (!alg)
611  continue;
612  dev->auth_support[auth_alg_index (alg)] = 1;
613  alg->resources += vec_len (dev->free_resources);
614  /* At least enough resources to support one algo */
615  dcm->enabled |= (alg->resources >= n_mains);
616  }
617  break;
618  default:
619  ;
620  }
621  }
622 }
623 
624 static clib_error_t *
625 crypto_dev_conf (u8 dev, u16 n_qp, u8 numa)
626 {
627  struct rte_cryptodev_config dev_conf = { 0 };
628  struct rte_cryptodev_qp_conf qp_conf = { 0 };
629  i32 ret;
630  u16 qp;
631  char *error_str;
632 
633  dev_conf.socket_id = numa;
634  dev_conf.nb_queue_pairs = n_qp;
635 
636  error_str = "failed to configure crypto device %u";
637  ret = rte_cryptodev_configure (dev, &dev_conf);
638  if (ret < 0)
639  return clib_error_return (0, error_str, dev);
640 
641  error_str = "failed to setup crypto device %u queue pair %u";
642  qp_conf.nb_descriptors = DPDK_CRYPTO_N_QUEUE_DESC;
643  for (qp = 0; qp < n_qp; qp++)
644  {
645 #if RTE_VERSION < RTE_VERSION_NUM(19, 2, 0, 0)
646  ret = rte_cryptodev_queue_pair_setup (dev, qp, &qp_conf, numa, NULL);
647 #else
648  ret = rte_cryptodev_queue_pair_setup (dev, qp, &qp_conf, numa);
649 #endif
650  if (ret < 0)
651  return clib_error_return (0, error_str, dev, qp);
652  }
653 
654  error_str = "failed to start crypto device %u";
655  if (rte_cryptodev_start (dev))
656  return clib_error_return (0, error_str, dev);
657 
658  return 0;
659 }
660 
661 static void
663 {
665  struct rte_cryptodev *cryptodev;
666  struct rte_cryptodev_info info = { 0 };
667  crypto_dev_t *dev;
668  crypto_resource_t *res;
670  u32 i;
671  u16 max_res_idx, res_idx, j;
672  u8 drv_id;
673 
674  vec_validate_init_empty (dcm->dev, rte_cryptodev_count () - 1,
676 
677  for (i = 0; i < rte_cryptodev_count (); i++)
678  {
679  dev = vec_elt_at_index (dcm->dev, i);
680 
681  cryptodev = &rte_cryptodevs[i];
682  rte_cryptodev_info_get (i, &info);
683 
684  dev->id = i;
685  dev->name = cryptodev->data->name;
686  dev->numa = rte_cryptodev_socket_id (i);
687  dev->features = info.feature_flags;
688  dev->max_qp = info.max_nb_queue_pairs;
689  drv_id = info.driver_id;
690  if (drv_id >= vec_len (dcm->drv))
691  vec_validate_init_empty (dcm->drv, drv_id,
692  (crypto_drv_t) EMPTY_STRUCT);
693  vec_elt_at_index (dcm->drv, drv_id)->name = info.driver_name;
694  dev->drv_id = drv_id;
695  vec_add1 (vec_elt_at_index (dcm->drv, drv_id)->devs, i);
696 
697  if (!(info.feature_flags & RTE_CRYPTODEV_FF_SYM_OPERATION_CHAINING))
698  continue;
699 
700  if ((error = crypto_dev_conf (i, dev->max_qp, dev->numa)))
701  {
702  clib_error_report (error);
703  continue;
704  }
705 
706  max_res_idx = dev->max_qp - 1;
707 
708  vec_validate (dev->free_resources, max_res_idx);
709 
710  res_idx = vec_len (dcm->resource);
711  vec_validate_init_empty_aligned (dcm->resource, res_idx + max_res_idx,
712  (crypto_resource_t) EMPTY_STRUCT,
714 
715  for (j = 0; j <= max_res_idx; j++)
716  {
717  vec_elt (dev->free_resources, max_res_idx - j) = res_idx + j;
718  res = &dcm->resource[res_idx + j];
719  res->dev_id = i;
720  res->drv_id = drv_id;
721  res->qp_id = j;
722  res->numa = dev->numa;
723  res->thread_idx = (u16) ~ 0;
724  }
725 
726  crypto_parse_capabilities (dev, info.capabilities, n_mains);
727  }
728 }
729 
730 void
732 {
734  crypto_resource_t *res;
736  crypto_dev_t *dev;
737  u32 thread_idx, skip_master;
738  u16 res_idx, *idx;
739  u8 used;
740  u16 i;
741 
742  skip_master = vlib_num_workers () > 0;
743 
744  /* *INDENT-OFF* */
745  vec_foreach (dev, dcm->dev)
746  {
747  vec_foreach_index (thread_idx, dcm->workers_main)
748  {
749  if (vec_len (dev->free_resources) == 0)
750  break;
751 
752  if (thread_idx < skip_master)
753  continue;
754 
755  /* Check thread is not already using the device */
756  vec_foreach (idx, dev->used_resources)
757  if (dcm->resource[idx[0]].thread_idx == thread_idx)
758  continue;
759 
760  cwm = vec_elt_at_index (dcm->workers_main, thread_idx);
761 
762  used = 0;
763  res_idx = vec_pop (dev->free_resources);
764 
765  /* Set device only for supported algos */
766  for (i = 0; i < IPSEC_CRYPTO_N_ALG; i++)
767  if (dev->cipher_support[i] &&
768  cwm->cipher_resource_idx[i] == (u16) ~0)
769  {
770  dcm->cipher_algs[i].disabled--;
771  cwm->cipher_resource_idx[i] = res_idx;
772  used = 1;
773  }
774 
775  for (i = 0; i < IPSEC_INTEG_N_ALG; i++)
776  if (dev->auth_support[i] &&
777  cwm->auth_resource_idx[i] == (u16) ~0)
778  {
779  dcm->auth_algs[i].disabled--;
780  cwm->auth_resource_idx[i] = res_idx;
781  used = 1;
782  }
783 
784  if (!used)
785  {
786  vec_add1 (dev->free_resources, res_idx);
787  continue;
788  }
789 
790  vec_add1 (dev->used_resources, res_idx);
791 
792  res = vec_elt_at_index (dcm->resource, res_idx);
793 
794  ASSERT (res->thread_idx == (u16) ~0);
795  res->thread_idx = thread_idx;
796 
797  /* Add device to vector of polling resources */
798  vec_add1 (cwm->resource_idx, res_idx);
799  }
800  }
801  /* *INDENT-ON* */
802 }
803 
804 static void
805 crypto_op_init (struct rte_mempool *mempool,
806  void *_arg __attribute__ ((unused)),
807  void *_obj, unsigned i __attribute__ ((unused)))
808 {
809  struct rte_crypto_op *op = _obj;
810 
811  op->sess_type = RTE_CRYPTO_OP_WITH_SESSION;
812  op->type = RTE_CRYPTO_OP_TYPE_SYMMETRIC;
813  op->status = RTE_CRYPTO_OP_STATUS_NOT_PROCESSED;
814  op->phys_addr = rte_mempool_virt2iova (_obj);
815  op->mempool = mempool;
816 }
817 
818 static clib_error_t *
820 {
824  u8 *pool_name;
825  u32 pool_priv_size = sizeof (struct rte_crypto_op_pool_private);
826  struct rte_crypto_op_pool_private *priv;
827  struct rte_mempool *mp;
828 
829  data = vec_elt_at_index (dcm->data, numa);
830 
831  /* Already allocated */
832  if (data->crypto_op)
833  return NULL;
834 
835  pool_name = format (0, "crypto_pool_numa%u%c", numa, 0);
836 
837  if (conf->num_crypto_mbufs == 0)
839 
840  mp = rte_mempool_create ((char *) pool_name, conf->num_crypto_mbufs,
841  crypto_op_len (), 512, pool_priv_size, NULL, NULL,
842  crypto_op_init, NULL, numa, 0);
843 
844  vec_free (pool_name);
845 
846  if (!mp)
847  return clib_error_return (0, "failed to create crypto op mempool");
848 
849  /* Initialize mempool private data */
850  priv = rte_mempool_get_priv (mp);
851  priv->priv_size = pool_priv_size;
852  priv->type = RTE_CRYPTO_OP_TYPE_SYMMETRIC;
853 
854  data->crypto_op = mp;
855 
856  return NULL;
857 }
858 
859 static clib_error_t *
861 {
864  u8 *pool_name;
865  struct rte_mempool *mp;
866  u32 elt_size;
867 
868  data = vec_elt_at_index (dcm->data, numa);
869 
870  if (data->session_h)
871  return NULL;
872 
873  pool_name = format (0, "session_h_pool_numa%u%c", numa, 0);
874 
875 
876  elt_size = rte_cryptodev_sym_get_header_session_size ();
877 
878 #if RTE_VERSION < RTE_VERSION_NUM(19, 2, 0, 0)
879  mp = rte_mempool_create ((char *) pool_name, DPDK_CRYPTO_NB_SESS_OBJS,
880  elt_size, 512, 0, NULL, NULL, NULL, NULL, numa, 0);
881 #else
882  /* XXX Experimental tag in DPDK 19.02 */
883  mp = rte_cryptodev_sym_session_pool_create ((char *) pool_name,
885  elt_size, 512, 0, numa);
886 #endif
887  vec_free (pool_name);
888 
889  if (!mp)
890  return clib_error_return (0, "failed to create crypto session mempool");
891 
892  data->session_h = mp;
893 
894  return NULL;
895 }
896 
897 static clib_error_t *
899 {
902  u8 *pool_name;
903  struct rte_mempool *mp;
904  u32 elt_size;
905  u8 numa = dev->numa;
906 
907  data = vec_elt_at_index (dcm->data, numa);
908 
909  vec_validate (data->session_drv, dev->drv_id);
910  vec_validate (data->session_drv_failed, dev->drv_id);
913 
914  if (data->session_drv[dev->drv_id])
915  return NULL;
916 
917  pool_name = format (0, "session_drv%u_pool_numa%u%c", dev->drv_id, numa, 0);
918 
919  elt_size = rte_cryptodev_sym_get_private_session_size (dev->id);
920  mp =
921  rte_mempool_create ((char *) pool_name, DPDK_CRYPTO_NB_SESS_OBJS,
922  elt_size, 512, 0, NULL, NULL, NULL, NULL, numa, 0);
923 
924  vec_free (pool_name);
925 
926  if (!mp)
927  return clib_error_return (0, "failed to create session drv mempool");
928 
929  data->session_drv[dev->drv_id] = mp;
930  clib_spinlock_init (&data->lockp);
931 
932  return NULL;
933 }
934 
935 static clib_error_t *
937 {
939  clib_error_t *error = NULL;
940  crypto_dev_t *dev;
941 
942  /* *INDENT-OFF* */
943  vec_foreach (dev, dcm->dev)
944  {
946 
947  error = crypto_create_crypto_op_pool (vm, dev->numa);
948  if (error)
949  return error;
950 
951  error = crypto_create_session_h_pool (vm, dev->numa);
952  if (error)
953  return error;
954 
955  error = crypto_create_session_drv_pool (vm, dev);
956  if (error)
957  return error;
958  }
959  /* *INDENT-ON* */
960 
961  return NULL;
962 }
963 
964 static void
966 {
969  u8 i;
970 
971  dcm->enabled = 0;
972 
973  /* *INDENT-OFF* */
974  vec_foreach (data, dcm->data)
975  {
976  rte_mempool_free (data->crypto_op);
977  rte_mempool_free (data->session_h);
978 
979  vec_foreach_index (i, data->session_drv)
980  rte_mempool_free (data->session_drv[i]);
981 
982  vec_free (data->session_drv);
983  clib_spinlock_free (&data->lockp);
984  }
985  /* *INDENT-ON* */
986 
987  vec_free (dcm->data);
988  vec_free (dcm->workers_main);
989  vec_free (dcm->dev);
990  vec_free (dcm->resource);
991  vec_free (dcm->cipher_algs);
992  vec_free (dcm->auth_algs);
993 }
994 
995 static clib_error_t *
997 {
1000  vlib_node_t *node = vlib_get_node_by_name (vm, (u8 *) "dpdk-crypto-input");
1001  u32 skip_master = vlib_num_workers () > 0;
1002  u32 n_mains = tm->n_vlib_mains;
1003  u32 i;
1004 
1005  ASSERT (node);
1006  for (i = skip_master; i < n_mains; i++)
1007  vlib_node_set_state (vlib_mains[i], node->index, is_enable != 0 ?
1008  VLIB_NODE_STATE_POLLING : VLIB_NODE_STATE_DISABLED);
1009 
1010  return 0;
1011 }
1012 
1013 static clib_error_t *
1015 {
1016  ipsec_main_t *im = &ipsec_main;
1019  crypto_worker_main_t *cwm;
1020  clib_error_t *error = NULL;
1021  u32 skip_master, n_mains;
1022 
1023  n_mains = tm->n_vlib_mains;
1024  skip_master = vlib_num_workers () > 0;
1025 
1026  algos_init (n_mains - skip_master);
1027 
1028  crypto_scan_devs (n_mains - skip_master);
1029 
1030  if (!(dcm->enabled))
1031  {
1033  "not enough DPDK crypto resources");
1034  crypto_disable ();
1035  return 0;
1036  }
1037 
1038  dcm->session_timeout = 10e9;
1039 
1040  vec_validate_init_empty_aligned (dcm->workers_main, n_mains - 1,
1043 
1044  /* *INDENT-OFF* */
1045  vec_foreach (cwm, dcm->workers_main)
1046  {
1049  clib_memset (cwm->cipher_resource_idx, ~0,
1050  IPSEC_CRYPTO_N_ALG * sizeof(*cwm->cipher_resource_idx));
1051  clib_memset (cwm->auth_resource_idx, ~0,
1052  IPSEC_INTEG_N_ALG * sizeof(*cwm->auth_resource_idx));
1053  }
1054  /* *INDENT-ON* */
1055 
1057 
1058  error = crypto_create_pools (vm);
1059  if (error)
1060  {
1061  clib_error_report (error);
1062  crypto_disable ();
1063  return 0;
1064  }
1065 
1066 
1067  u32 idx = ipsec_register_esp_backend (vm, im, "dpdk backend",
1068  "dpdk-esp4-encrypt",
1069  "dpdk-esp4-encrypt-tun",
1070  "dpdk-esp4-decrypt",
1071  "dpdk-esp4-decrypt",
1072  "dpdk-esp6-encrypt",
1073  "dpdk-esp6-encrypt-tun",
1074  "dpdk-esp6-decrypt",
1075  "dpdk-esp6-decrypt",
1079  int rv;
1080  if (im->esp_current_backend == ~0)
1081  {
1082  rv = ipsec_select_esp_backend (im, idx);
1083  ASSERT (rv == 0);
1084  }
1085  return 0;
1086 }
1087 
1089 
1090 /*
1091  * fd.io coding-style-patch-verification: ON
1092  *
1093  * Local Variables:
1094  * eval: (c-set-style "gnu")
1095  * End:
1096  */
#define vec_validate(V, I)
Make sure vector is long enough for given index (no header, unspecified alignment) ...
Definition: vec.h:509
u32 alg
Definition: ipsec.h:87
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 vlib_log_warn(...)
Definition: log.h:133
#define hash_unset(h, key)
Definition: hash.h:261
a
Definition: bitmap.h:544
dpdk_main_t dpdk_main
Definition: init.c:47
#define VLIB_MAIN_LOOP_ENTER_FUNCTION(x)
Definition: init.h:176
static u8 cipher_alg_index(const crypto_alg_t *alg)
Definition: ipsec.c:178
unsigned long u64
Definition: types.h:89
clib_memset(h->entries, 0, sizeof(h->entries[0]) *entries)
u32 index
Definition: node.h:280
u64 session_h_failed
Definition: ipsec.h:153
#define foreach_ipsec_crypto_alg
Definition: ipsec_sa.h:24
ipsec_key_t crypto_key
Definition: ipsec_sa.h:217
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:214
#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:592
static clib_error_t * crypto_create_session_drv_pool(vlib_main_t *vm, crypto_dev_t *dev)
Definition: ipsec.c:898
#define EMPTY_STRUCT
Definition: ipsec.c:28
static_always_inline u32 crypto_op_get_priv_offset(void)
Definition: ipsec.h:196
u16 key_len
Definition: ikev2_types.api:95
#define foreach_ipsec_integ_alg
Definition: ipsec_sa.h:51
#define DPDK_CRYPTO_NB_SESS_OBJS
Definition: ipsec.h:34
struct rte_cryptodev_sym_session * session
Definition: ipsec.h:135
vlib_main_t * vm
Definition: in2out_ed.c:1580
u8 disabled
Definition: ipsec.h:92
#define vec_validate_aligned(V, I, A)
Make sure vector is long enough for given index (no header, specified alignment)
Definition: vec.h:520
u32 esp_current_backend
Definition: ipsec.h:177
static void crypto_set_cipher_xform(struct rte_crypto_sym_xform *xform, ipsec_sa_t *sa, u8 is_outbound)
Definition: ipsec.c:272
vlib_main_t ** vlib_mains
Definition: buffer.c:332
static clib_error_t * crypto_create_session_h_pool(vlib_main_t *vm, u8 numa)
Definition: ipsec.c:860
unsigned char u8
Definition: types.h:56
#define vec_pop(V)
Returns last element of a vector and decrements its length.
Definition: vec.h:685
u8 data[128]
Definition: ipsec_types.api:90
static crypto_alg_t * cipher_cap_to_alg(const struct rte_cryptodev_capabilities *cap, u8 key_len)
Definition: ipsec.c:194
#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
static clib_error_t * add_del_sa_session(u32 sa_index, u8 is_add)
Definition: ipsec.c:496
u16 * resource_idx
Definition: ipsec.h:75
#define AES_GCM_TYPE
#define DPDK_CRYPTO_N_QUEUE_DESC
Definition: ipsec.h:33
bool is_outbound
Definition: ipsec.api:96
u16 cipher_resource_idx[IPSEC_CRYPTO_N_ALG]
Definition: ipsec.h:77
static void algos_init(u32 n_mains)
Definition: ipsec.c:32
dpdk_crypto_main_t dpdk_crypto_main
Definition: ipsec.c:26
dpdk_config_main_t dpdk_config_main
Definition: init.c:48
ipsec_main_t ipsec_main
Definition: ipsec.c:28
u8 resources
Definition: ipsec.h:93
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, 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:211
description fragment has unexpected format
Definition: map.api:433
int ipsec_select_esp_backend(ipsec_main_t *im, u32 backend_idx)
Definition: ipsec.c:293
#define NUM_CRYPTO_MBUFS
Definition: ipsec.c:29
static clib_error_t * dpdk_ipsec_enable_disable(int is_enable)
Definition: ipsec.c:996
crypto_drv_t * drv
Definition: ipsec.h:169
#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:102
#define clib_error_return(e, args...)
Definition: error.h:99
static void crypto_parse_capabilities(crypto_dev_t *dev, const struct rte_cryptodev_capabilities *cap, u32 n_mains)
Definition: ipsec.c:574
u16 * free_resources
Definition: ipsec.h:98
u8 * format_ipsec_crypto_alg(u8 *s, va_list *args)
Definition: ipsec_format.c:79
unsigned int u32
Definition: types.h:88
#define vec_end(v)
End (last data address) of vector.
crypto_alg_t * auth_algs
Definition: ipsec.h:167
#define VLIB_FRAME_SIZE
Definition: node.h:378
static clib_error_t * crypto_dev_conf(u8 dev, u16 n_qp, u8 numa)
Definition: ipsec.c:625
u8 trunc_size
Definition: ipsec.h:90
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:215
static void crypto_disable(void)
Definition: ipsec.c:965
static void clib_spinlock_init(clib_spinlock_t *p)
Definition: lock.h:65
clib_spinlock_t lockp
Definition: ipsec.h:156
static void * get_session_private_data(const struct rte_cryptodev_sym_session *sess, uint8_t driver_id)
Definition: ipsec.c:420
Definition: cJSON.c:84
u16 * used_resources
Definition: ipsec.h:99
#define hash_get(h, key)
Definition: hash.h:249
#define pool_elt_at_index(p, i)
Returns pointer to element at given index.
Definition: pool.h:546
vlib_node_t * vlib_get_node_by_name(vlib_main_t *vm, u8 *name)
Definition: node.c:45
crypto_alg_t * cipher_algs
Definition: ipsec.h:166
unsigned short u16
Definition: types.h:57
u64 features
Definition: ipsec.h:107
u64 session_timeout
Definition: ipsec.h:170
static_always_inline u32 crypto_op_len(void)
Definition: ipsec.h:186
#define AES_GCM_ALG
static clib_error_t * crypto_create_crypto_op_pool(vlib_main_t *vm, u8 numa)
Definition: ipsec.c:819
static u8 auth_alg_index(const crypto_alg_t *alg)
Definition: ipsec.c:186
struct rte_mempool ** session_drv
Definition: ipsec.h:149
u8 len
Definition: ip_types.api:103
vlib node functions
static clib_error_t * dpdk_ipsec_main_init(vlib_main_t *vm)
Definition: ipsec.c:1014
crypto_session_by_drv_t * session_by_drv_id_and_sa_index
Definition: ipsec.h:155
u32 num_crypto_mbufs
Definition: dpdk.h:293
svmdb_client_t * c
sll srl srl sll sra u16x4 i
Definition: vector_sse42.h:317
#define vec_free(V)
Free vector&#39;s memory (no header).
Definition: vec.h:380
static u64 unix_time_now_nsec(void)
Definition: time.h:270
crypto_session_disposal_t * session_disposal
Definition: ipsec.h:150
static void crypto_set_aead_xform(struct rte_crypto_sym_xform *xform, ipsec_sa_t *sa, u8 is_outbound)
Definition: ipsec.c:244
u16 id
Definition: ipsec.h:104
static void set_session_private_data(struct rte_cryptodev_sym_session *sess, uint8_t driver_id, void *private_data)
Definition: ipsec.c:435
vlib_main_t vlib_node_runtime_t * node
Definition: in2out_ed.c:1580
u8 iv_len
Definition: ipsec.h:89
signed int i32
Definition: types.h:77
u8 data[IPSEC_KEY_MAX_LEN]
Definition: ipsec_sa.h:78
#define ASSERT(truth)
#define vec_delete(V, N, M)
Delete N elements starting at element M.
Definition: vec.h:854
struct rte_mempool * crypto_op
Definition: ipsec.h:147
u32 max_qp
Definition: ipsec.h:106
ipsec_sa_t * sad
Definition: ipsec.h:111
vlib_log_class_t log_default
Definition: dpdk.h:355
static clib_error_t * dpdk_crypto_session_disposal(crypto_session_disposal_t *v, u64 ts)
Definition: ipsec.c:448
crypto_worker_main_t * workers_main
Definition: ipsec.h:163
#define clib_error_report(e)
Definition: error.h:113
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:174
crypto_resource_t * resource
Definition: ipsec.h:165
static vlib_main_t * vlib_get_main(void)
Definition: global_funcs.h:23
#define vec_elt(v, i)
Get vector value at index i.
static clib_error_t * crypto_create_pools(vlib_main_t *vm)
Definition: ipsec.c:936
struct rte_mempool * session_h
Definition: ipsec.h:148
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
void crypto_auto_placement(void)
Definition: ipsec.c:731
u64 * session_drv_failed
Definition: ipsec.h:154
u64 uword
Definition: types.h:112
uword * session_by_sa_index
Definition: ipsec.h:151
static void crypto_scan_devs(u32 n_mains)
Definition: ipsec.c:662
const char * name
Definition: ipsec.h:105
static void crypto_op_init(struct rte_mempool *mempool, void *_arg, void *_obj, unsigned i)
Definition: ipsec.c:805
struct rte_crypto_op ** ops
Definition: ipsec.h:76
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
crypto_dev_t * dev
Definition: ipsec.h:164
enum rte_crypto_sym_xform_type type
Definition: ipsec.h:86
crypto_data_t * data
Definition: ipsec.h:168
ipsec_crypto_alg_t crypto_alg
Definition: ipsec_sa.h:213
static vlib_thread_main_t * vlib_get_thread_main()
Definition: global_funcs.h:32
static u32 vlib_num_workers()
Definition: threads.h:377
u16 auth_resource_idx[IPSEC_INTEG_N_ALG]
Definition: ipsec.h:78
u8 auth_support[IPSEC_INTEG_N_ALG]
Definition: ipsec.h:101
#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:568
#define vec_foreach(var, vec)
Vector iterator.
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:227
u8 key_len
Definition: ipsec.h:88
#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:556
#define CLIB_CACHE_LINE_BYTES
Definition: cache.h:59
ipsec_key_t integ_key
Definition: ipsec_sa.h:216
static_always_inline void clib_spinlock_lock_if_init(clib_spinlock_t *p)
Definition: lock.h:106
static void crypto_set_auth_xform(struct rte_crypto_sym_xform *xform, ipsec_sa_t *sa, u8 is_outbound)
Definition: ipsec.c:298
static clib_error_t * dpdk_ipsec_check_support(ipsec_sa_t *sa)
Definition: ipsec.c:541
u8 cipher_support[IPSEC_CRYPTO_N_ALG]
Definition: ipsec.h:100
static void clear_and_free_obj(void *obj)
Definition: ipsec.c:409
static crypto_alg_t * auth_cap_to_alg(const struct rte_cryptodev_capabilities *cap, u8 trunc_size)
Definition: ipsec.c:222