aboutsummaryrefslogtreecommitdiffstats
path: root/src/plugins/odp/ipsec/crypto_input.c
diff options
context:
space:
mode:
authorSzymon Sliwa <szs@semihalf.com>2018-01-26 12:30:41 +0100
committerSzymon Sliwa <szs@semihalf.com>2018-02-06 14:48:32 +0100
commitafb5b006e4451a9dcb3270d4a5755413e65f5497 (patch)
treee5a8de9f1c1bda994b9a9248cab18d8506b052c4 /src/plugins/odp/ipsec/crypto_input.c
parent9775521a9ca1466e9a02fe4d69afafc55dcbc09c (diff)
plugins: odp: Add support for async crypto mode
By default ipsec picks asynchronuous crypto. After the operation it may turn out that the operation was performed synchronously anyways, in such case the packet is send further by the esp_* node because there will be no notification event sent about the crypto completion. To use asynchronous mode put async in the odp section of the startup.conf file, like this: odp { async } Falls back to synchronous mode. Change-Id: I5301df5f1c93a5ccd53a9c0ed2c4cacb9ca5fdd4 Signed-off-by: Szymon Sliwa <szs@semihalf.com>
Diffstat (limited to 'src/plugins/odp/ipsec/crypto_input.c')
-rw-r--r--src/plugins/odp/ipsec/crypto_input.c155
1 files changed, 155 insertions, 0 deletions
diff --git a/src/plugins/odp/ipsec/crypto_input.c b/src/plugins/odp/ipsec/crypto_input.c
new file mode 100644
index 00000000..03d2ccd8
--- /dev/null
+++ b/src/plugins/odp/ipsec/crypto_input.c
@@ -0,0 +1,155 @@
+#include <vlib/vlib.h>
+#include <vnet/ip/ip.h>
+
+#include <odp/ipsec/ipsec.h>
+#include <odp/ipsec/esp.h>
+#include <odp/odp_packet.h>
+
+#include <assert.h>
+
+#define foreach_odp_crypto_input_next \
+ _(DROP, "error-drop") \
+ _(ENCRYPT_POST, "odp-crypto-esp-encrypt-post") \
+ _(DECRYPT_POST, "odp-crypto-esp-decrypt-post")
+
+typedef enum
+{
+#define _(f, s) ODP_CRYPTO_INPUT_NEXT_##f,
+ foreach_odp_crypto_input_next
+#undef _
+ODP_CRYPTO_INPUT_N_NEXT,
+} odp_crypto_input_next_t;
+
+#define foreach_crypto_input_error \
+_(DEQUE_COP, "Dequed crypto operations")
+
+typedef enum
+{
+#define _(sym,str) CRYPTO_INPUT_ERROR_##sym,
+ foreach_crypto_input_error
+#undef _
+} crypto_input_error_t;
+
+static char *crypto_input_error_strings[] = {
+#define _(sym,string) string,
+ foreach_crypto_input_error
+#undef _
+};
+
+typedef struct
+{
+ u32 next_index;
+ odp_packet_t pkt;
+} odp_packet_crypto_trace_t;
+
+static u8 *
+format_odp_crypto_input_trace (u8 * s, va_list * args)
+{
+ CLIB_UNUSED (vlib_main_t * vm) = va_arg (*args, vlib_main_t *);
+ CLIB_UNUSED (vlib_node_t * node) = va_arg (*args, vlib_node_t *);
+
+ s = format (s, " odp-crypto-input ");
+
+ return s;
+}
+
+static uword
+odp_dequeue_cops (vlib_main_t * vm, vlib_node_runtime_t * node,
+ vlib_frame_t * frame, odp_queue_t queue, u32 next_node_index)
+{
+ u32 next_index = next_node_index, n_deq, n_cops, *to_next = 0;
+ const int MAX_EVENTS = (1<<8);
+ odp_event_t events[MAX_EVENTS];
+
+ n_deq = odp_queue_deq_multi(queue, events, MAX_EVENTS);
+
+ n_cops = n_deq;
+
+ int index = 0;
+ while(n_cops > 0) {
+ u32 n_left_to_next;
+
+ vlib_get_next_frame (vm, node, next_index, to_next, n_left_to_next);
+
+ while(n_cops > 0 && n_left_to_next > 0) {
+ odp_event_t event = events[index++];
+
+ ASSERT(ODP_EVENT_CRYPTO_COMPL == odp_event_type(event));
+
+ odp_crypto_compl_t compl;
+ odp_crypto_op_result_t result;
+ odp_packet_t pkt;
+ vlib_buffer_t *b0;
+ u32 bi0;
+
+ compl = odp_crypto_compl_from_event(event);
+ odp_crypto_compl_result(compl, &result);
+ pkt = result.pkt;
+
+ b0 = vlib_buffer_from_odp_packet(pkt);
+ bi0 = vlib_get_buffer_index (vm, b0);
+
+ to_next[0] = bi0;
+ to_next += 1;
+
+ n_cops -= 1;
+ n_left_to_next -= 1;
+
+ if (PREDICT_FALSE (b0->flags & VLIB_BUFFER_IS_TRACED))
+ {
+ odp_packet_crypto_trace_t *tr;
+ tr = vlib_add_trace (vm, node, b0, sizeof (*tR));
+ tr->next_index = next_index;
+ }
+
+ vlib_validate_buffer_enqueue_x1 (vm, node, next_index,
+ to_next, n_left_to_next, bi0, next_node_index);
+ }
+ vlib_put_next_frame (vm, node, next_index, n_left_to_next);
+ }
+ vlib_node_increment_counter (vm, odp_crypto_input_node.index,
+ CRYPTO_INPUT_ERROR_DEQUE_COP,
+ n_deq);
+
+ return n_deq;
+}
+
+static uword
+odp_crypto_input_node_fn (vlib_main_t * vm, vlib_node_runtime_t * node,
+ vlib_frame_t * frame)
+{
+ odp_crypto_main_t *ocm = &odp_crypto_main;
+ u32 thread_index = vlib_get_thread_index ();
+ odp_crypto_worker_main_t *cwm =
+ vec_elt_at_index (ocm->workers, thread_index);
+ u32 n_cops_dequeued = 0;
+ n_cops_dequeued += odp_dequeue_cops(vm, node, frame, cwm->post_encrypt, ODP_CRYPTO_INPUT_NEXT_ENCRYPT_POST);
+ n_cops_dequeued += odp_dequeue_cops(vm, node, frame, cwm->post_decrypt, ODP_CRYPTO_INPUT_NEXT_DECRYPT_POST);
+ return n_cops_dequeued;
+}
+
+
+VLIB_REGISTER_NODE (odp_crypto_input_node) =
+{
+ .function = odp_crypto_input_node_fn,
+ .name = "odp-crypto-input",
+ .format_trace = format_odp_crypto_input_trace,
+ .type = VLIB_NODE_TYPE_INPUT,
+ .state = VLIB_NODE_STATE_DISABLED,
+
+ .n_errors = ARRAY_LEN(crypto_input_error_strings),
+ .error_strings = crypto_input_error_strings,
+
+ .n_next_nodes = ODP_CRYPTO_INPUT_N_NEXT,
+ .next_nodes =
+ {
+#define _(s, n) [ODP_CRYPTO_INPUT_NEXT_##s] = n,
+ foreach_odp_crypto_input_next
+#undef _
+ },
+};
+
+VLIB_NODE_FUNCTION_MULTIARCH (odp_crypto_input_node, odp_crypto_input_node_fn);
+
+
+