FD.io VPP  v17.04-9-g99c0734
Vector Packet Processing
crypto_node.c
Go to the documentation of this file.
1 /*
2  *------------------------------------------------------------------
3  * crypto_node.c - DPDK Cryptodev input node
4  *
5  * Copyright (c) 2016 Intel and/or its affiliates.
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at:
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *------------------------------------------------------------------
18  */
19 
20 #include <vlib/vlib.h>
21 #include <vnet/ip/ip.h>
22 #include <vnet/ethernet/ethernet.h>
23 #include <vnet/ipsec/ipsec.h>
24 
25 #include <dpdk/device/dpdk.h>
26 #include <dpdk/device/dpdk_priv.h>
27 #include <dpdk/ipsec/ipsec.h>
28 
29 #define foreach_dpdk_crypto_input_next \
30  _(DROP, "error-drop") \
31  _(ENCRYPT_POST, "dpdk-esp-encrypt-post") \
32  _(DECRYPT_POST, "dpdk-esp-decrypt-post")
33 
34 typedef enum
35 {
36 #define _(f,s) DPDK_CRYPTO_INPUT_NEXT_##f,
38 #undef _
41 
42 #define foreach_dpdk_crypto_input_error \
43  _(DQ_COPS, "Crypto ops dequeued") \
44  _(COP_FAILED, "Crypto op failed")
45 
46 typedef enum
47 {
48 #define _(f,s) DPDK_CRYPTO_INPUT_ERROR_##f,
50 #undef _
53 
55 #define _(n, s) s,
57 #undef _
58 };
59 
61 
62 typedef struct
63 {
70 
71 static u8 *
72 format_dpdk_crypto_input_trace (u8 * s, va_list * args)
73 {
74  CLIB_UNUSED (vlib_main_t * vm) = va_arg (*args, vlib_main_t *);
75  CLIB_UNUSED (vlib_node_t * node) = va_arg (*args, vlib_node_t *);
77 
78  s = format (s, "dpdk_crypto: cryptodev-id %u queue-pair %u next-index %d",
79  t->cdev, t->qp, t->next_index);
80 
81  s = format (s, " status %u sa-idx %u\n", t->status, t->sa_idx);
82 
83  return s;
84 }
85 
88  crypto_qp_data_t * qpd)
89 {
90  u32 n_deq, *to_next = 0, next_index, n_cops, def_next_index;
91  struct rte_crypto_op **cops = qpd->cops;
92 
93  if (qpd->inflights == 0)
94  return 0;
95 
96  if (qpd->is_outbound)
97  def_next_index = DPDK_CRYPTO_INPUT_NEXT_ENCRYPT_POST;
98  else
99  def_next_index = DPDK_CRYPTO_INPUT_NEXT_DECRYPT_POST;
100 
101  n_cops = rte_cryptodev_dequeue_burst (qpd->dev_id, qpd->qp_id,
102  cops, VLIB_FRAME_SIZE);
103  n_deq = n_cops;
104  next_index = def_next_index;
105 
106  qpd->inflights -= n_cops;
107  ASSERT (qpd->inflights >= 0);
108 
109  while (n_cops > 0)
110  {
111  u32 n_left_to_next;
112 
113  vlib_get_next_frame (vm, node, next_index, to_next, n_left_to_next);
114 
115  while (n_cops > 0 && n_left_to_next > 0)
116  {
117  u32 bi0, next0;
118  vlib_buffer_t *b0 = 0;
119  struct rte_crypto_op *cop;
120  struct rte_crypto_sym_op *sym_cop;
121 
122  cop = cops[0];
123  cops += 1;
124  n_cops -= 1;
125  n_left_to_next -= 1;
126 
127  next0 = def_next_index;
128 
129  if (PREDICT_FALSE (cop->status != RTE_CRYPTO_OP_STATUS_SUCCESS))
130  {
131  next0 = DPDK_CRYPTO_INPUT_NEXT_DROP;
133  DPDK_CRYPTO_INPUT_ERROR_COP_FAILED,
134  1);
135  }
136  cop->status = RTE_CRYPTO_OP_STATUS_NOT_PROCESSED;
137 
138  sym_cop = (struct rte_crypto_sym_op *) (cop + 1);
139  b0 = vlib_buffer_from_rte_mbuf (sym_cop->m_src);
140  bi0 = vlib_get_buffer_index (vm, b0);
141 
142  to_next[0] = bi0;
143  to_next += 1;
144 
146  {
147  vlib_trace_next_frame (vm, node, next0);
149  vlib_add_trace (vm, node, b0, sizeof (*tr));
150  tr->cdev = qpd->dev_id;
151  tr->qp = qpd->qp_id;
152  tr->status = cop->status;
153  tr->next_index = next0;
154  tr->sa_idx = vnet_buffer (b0)->ipsec.sad_index;
155  }
156 
157  vlib_validate_buffer_enqueue_x1 (vm, node, next_index, to_next,
158  n_left_to_next, bi0, next0);
159  }
160  vlib_put_next_frame (vm, node, next_index, n_left_to_next);
161  }
162 
163  crypto_free_cop (qpd, qpd->cops, n_deq);
164 
166  DPDK_CRYPTO_INPUT_ERROR_DQ_COPS, n_deq);
167  return n_deq;
168 }
169 
170 static uword
172  vlib_frame_t * frame)
173 {
174  u32 cpu_index = os_get_cpu_number ();
176  crypto_worker_main_t *cwm = &dcm->workers_main[cpu_index];
177  crypto_qp_data_t *qpd;
178  u32 n_deq = 0;
179 
180  /* *INDENT-OFF* */
181  vec_foreach (qpd, cwm->qp_data)
182  n_deq += dpdk_crypto_dequeue(vm, node, qpd);
183  /* *INDENT-ON* */
184 
185  return n_deq;
186 }
187 
188 /* *INDENT-OFF* */
190 {
191  .function = dpdk_crypto_input_fn,
192  .name = "dpdk-crypto-input",
193  .format_trace = format_dpdk_crypto_input_trace,
194  .type = VLIB_NODE_TYPE_INPUT,
195  .state = VLIB_NODE_STATE_DISABLED,
196  .n_errors = DPDK_CRYPTO_INPUT_N_ERROR,
197  .error_strings = dpdk_crypto_input_error_strings,
198  .n_next_nodes = DPDK_CRYPTO_INPUT_N_NEXT,
199  .next_nodes =
200  {
201 #define _(s,n) [DPDK_CRYPTO_INPUT_NEXT_##s] = n,
203 #undef _
204  },
205 };
206 /* *INDENT-ON* */
207 
209 /*
210  * fd.io coding-style-patch-verification: ON
211  *
212  * Local Variables:
213  * eval: (c-set-style "gnu")
214  * End:
215  */
dpdk_crypto_input_error_t
Definition: crypto_node.c:46
#define vlib_buffer_from_rte_mbuf(x)
Definition: dpdk_priv.h:17
static_always_inline u32 dpdk_crypto_dequeue(vlib_main_t *vm, vlib_node_runtime_t *node, crypto_qp_data_t *qpd)
Definition: crypto_node.c:87
#define CLIB_UNUSED(x)
Definition: clib.h:79
u16 is_outbound
Definition: ipsec.h:62
void vlib_put_next_frame(vlib_main_t *vm, vlib_node_runtime_t *r, u32 next_index, u32 n_vectors_left)
Release pointer to next frame vector data.
Definition: main.c:459
struct _vlib_node_registration vlib_node_registration_t
u8 * format(u8 *s, const char *fmt,...)
Definition: format.c:418
vlib_node_registration_t dpdk_crypto_input_node
(constructor) VLIB_REGISTER_NODE (dpdk_crypto_input_node)
Definition: crypto_node.c:60
static_always_inline void crypto_free_cop(crypto_qp_data_t *qpd, struct rte_crypto_op **cops, u32 n)
Definition: ipsec.h:127
dpdk_crypto_main_t dpdk_crypto_main
Definition: ipsec.h:88
#define static_always_inline
Definition: clib.h:85
static void vlib_trace_next_frame(vlib_main_t *vm, vlib_node_runtime_t *r, u32 next_index)
Definition: trace_funcs.h:92
i16 inflights
Definition: ipsec.h:63
static u32 vlib_get_buffer_index(vlib_main_t *vm, void *p)
Translate buffer pointer into buffer index.
Definition: buffer_funcs.h:70
#define foreach_dpdk_crypto_input_error
Definition: crypto_node.c:42
dpdk_crypto_input_next_t
Definition: crypto_node.c:34
#define foreach_dpdk_crypto_input_next
Definition: crypto_node.c:29
uword os_get_cpu_number(void)
Definition: unix-misc.c:224
#define PREDICT_FALSE(x)
Definition: clib.h:97
static uword dpdk_crypto_input_fn(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame)
Definition: crypto_node.c:171
#define VLIB_FRAME_SIZE
Definition: node.h:328
struct rte_crypto_op * cops[VLIB_FRAME_SIZE]
Definition: ipsec.h:65
#define vlib_validate_buffer_enqueue_x1(vm, node, next_index, to_next, n_left_to_next, bi0, next0)
Finish enqueueing one buffer forward in the graph.
Definition: buffer_node.h:216
#define vlib_get_next_frame(vm, node, next_index, vectors, n_vectors_left)
Get pointer to next frame vector data by (vlib_node_runtime_t, next_index).
Definition: node_funcs.h:350
static void vlib_node_increment_counter(vlib_main_t *vm, u32 node_index, u32 counter_index, u64 increment)
Definition: node_funcs.h:1112
vlib_main_t * vm
Definition: buffer.c:276
#define VLIB_BUFFER_IS_TRACED
Definition: buffer.h:85
static char * dpdk_crypto_input_error_strings[]
Definition: crypto_node.c:54
#define ASSERT(truth)
unsigned int u32
Definition: types.h:88
crypto_worker_main_t * workers_main
Definition: ipsec.h:85
crypto_qp_data_t * qp_data
Definition: ipsec.h:78
u64 uword
Definition: types.h:112
static void * vlib_add_trace(vlib_main_t *vm, vlib_node_runtime_t *r, vlib_buffer_t *b, u32 n_data_bytes)
Definition: trace_funcs.h:55
static u8 * format_dpdk_crypto_input_trace(u8 *s, va_list *args)
Definition: crypto_node.c:72
unsigned char u8
Definition: types.h:56
#define vnet_buffer(b)
Definition: buffer.h:294
#define VLIB_NODE_FUNCTION_MULTIARCH(node, fn)
Definition: node.h:158
#define VLIB_REGISTER_NODE(x,...)
Definition: node.h:143
#define vec_foreach(var, vec)
Vector iterator.
u32 flags
buffer flags: VLIB_BUFFER_IS_TRACED: trace this buffer.
Definition: buffer.h:74