DPDK patches and discussions
 help / color / mirror / Atom feed
* [dpdk-dev] [PATCH] pipeline: add symmetric crypto to table action
@ 2018-08-28  8:19 Zhang, Roy Fan
  2018-09-28 12:26 ` [dpdk-dev] [PATCH v2 0/7] pipeline: add symmetric crypto to action Fan Zhang
  0 siblings, 1 reply; 10+ messages in thread
From: Zhang, Roy Fan @ 2018-08-28  8:19 UTC (permalink / raw)
  To: dev; +Cc: cristian.dumitrescu

This patch adds the symmetric crypto action support to pipeline
library. The symmetric crypto action works as the shim layer
between pipeline and DPDK cryptodev and is able to interact with
cryptodev with the control path requests such as session
creation/deletion and data path work to assemble the crypto
operations for received packets.

Change-Id: Id0b547bb10f9e8814b08f5df2343337daca0ae92
Signed-off-by: Zhang, Roy Fan <roy.fan.zhang@intel.com>
---
 lib/librte_pipeline/Makefile           |   2 +-
 lib/librte_pipeline/meson.build        |   2 +-
 lib/librte_pipeline/rte_table_action.c | 466 +++++++++++++++++++++++++++++++++
 lib/librte_pipeline/rte_table_action.h |  70 +++++
 4 files changed, 538 insertions(+), 2 deletions(-)

diff --git a/lib/librte_pipeline/Makefile b/lib/librte_pipeline/Makefile
index 84afe98cb..cf265503f 100644
--- a/lib/librte_pipeline/Makefile
+++ b/lib/librte_pipeline/Makefile
@@ -12,7 +12,7 @@ CFLAGS += -DALLOW_EXPERIMENTAL_API
 CFLAGS += -O3
 CFLAGS += $(WERROR_FLAGS)
 LDLIBS += -lrte_eal -lrte_mempool -lrte_mbuf -lrte_table
-LDLIBS += -lrte_port -lrte_meter -lrte_sched
+LDLIBS += -lrte_port -lrte_meter -lrte_sched -lrte_cryptodev
 
 EXPORT_MAP := rte_pipeline_version.map
 
diff --git a/lib/librte_pipeline/meson.build b/lib/librte_pipeline/meson.build
index dc16ab42f..04e5f5179 100644
--- a/lib/librte_pipeline/meson.build
+++ b/lib/librte_pipeline/meson.build
@@ -5,4 +5,4 @@ version = 3
 allow_experimental_apis = true
 sources = files('rte_pipeline.c', 'rte_port_in_action.c', 'rte_table_action.c')
 headers = files('rte_pipeline.h', 'rte_port_in_action.h', 'rte_table_action.h')
-deps += ['port', 'table', 'meter', 'sched']
+deps += ['port', 'table', 'meter', 'sched', 'cryptodev']
diff --git a/lib/librte_pipeline/rte_table_action.c b/lib/librte_pipeline/rte_table_action.c
index 83ffa5ded..a958aa82a 100644
--- a/lib/librte_pipeline/rte_table_action.c
+++ b/lib/librte_pipeline/rte_table_action.c
@@ -15,6 +15,7 @@
 #include <rte_esp.h>
 #include <rte_tcp.h>
 #include <rte_udp.h>
+#include <rte_cryptodev.h>
 
 #include "rte_table_action.h"
 
@@ -1219,6 +1220,428 @@ pkt_work_time(struct time_data *data,
 	data->time = time;
 }
 
+
+/**
+ * RTE_TABLE_ACTION_CRYPTO
+ */
+
+#define CRYPTO_OP_MASK_CIPHER	0x1
+#define CRYPTO_OP_MASK_AUTH	0x2
+#define CRYPTO_OP_MASK_AEAD	0x4
+#define CRYPTO_IV_OFFSET						\
+	sizeof(struct rte_crypto_op) + sizeof(struct rte_crypto_sym_op)
+
+struct crypto_op_sym_iv_aad {
+	struct rte_crypto_op op;
+	struct rte_crypto_sym_op sym_op;
+	union {
+		struct {
+			uint8_t cipher_iv[
+				RTE_TABLE_ACTION_SYM_CRYPTO_IV_SIZE_MAX];
+			uint8_t auth_iv[
+				RTE_TABLE_ACTION_SYM_CRYPTO_IV_SIZE_MAX];
+		} cipher_auth;
+
+		struct {
+			uint8_t iv[RTE_TABLE_ACTION_SYM_CRYPTO_IV_SIZE_MAX];
+			uint8_t aad[RTE_TABLE_ACTION_SYM_CRYPTO_AAD_SIZE_MAX];
+		} aead_iv_aad;
+
+	} iv_aad;
+};
+
+struct sym_crypto_data {
+
+	union {
+		struct {
+
+			/** Length of cipher iv. */
+			uint16_t cipher_iv_len;
+
+			/** Offset from start of IP header to the cipher iv. */
+			uint16_t cipher_iv_data_offset;
+
+			/** Length of cipher iv to be updated in the mbuf. */
+			uint16_t cipher_iv_update_len;
+
+			/** Offset from start of IP header to the auth iv. */
+			uint16_t auth_iv_data_offset;
+
+			/** Length of auth iv in the mbuf. */
+			uint16_t auth_iv_len;
+
+			/** Length of auth iv to be updated in the mbuf. */
+			uint16_t auth_iv_update_len;
+
+		} cipher_auth;
+		struct {
+
+			/** Length of iv. */
+			uint16_t iv_len;
+
+			/** Offset from start of IP header to the aead iv. */
+			uint16_t iv_data_offset;
+
+			/** Length of iv to be updated in the mbuf. */
+			uint16_t iv_update_len;
+
+			/** Length of aad */
+			uint16_t aad_len;
+
+			/** Offset from start of IP header to the aad. */
+			uint16_t aad_data_offset;
+
+			/** Length of aad to updated in the mbuf. */
+			uint16_t aad_update_len;
+
+		} aead;
+	};
+
+	/** Offset from start of IP header to the data. */
+	uint16_t data_offset;
+
+	/** Digest length. */
+	uint16_t digest_len;
+
+	/** block size */
+	uint16_t block_size;
+
+	/** Mask of crypto operation */
+	uint16_t op_mask;
+
+	/** Session pointer. */
+	struct rte_cryptodev_sym_session *session;
+
+	/** Private data size to store cipher iv / aad. */
+	uint8_t iv_aad_data[0];
+
+	/** Direction of crypto, encrypt or decrypt */
+	uint16_t direction;
+
+} __attribute__((__packed__));
+
+static int
+sym_crypto_cfg_check(struct rte_table_action_sym_crypto_config *cfg)
+{
+	if (cfg->mempool_session_create == NULL ||
+			cfg->mempool_session_init == NULL)
+		return -EINVAL;
+
+	if (cfg->cryptodev_id >= rte_cryptodev_count())
+		return -EINVAL;
+
+	return 0;
+}
+
+static int
+get_block_size(const struct rte_crypto_sym_xform *xform, uint8_t cdev_id)
+{
+	unsigned int i = 0;
+	struct rte_cryptodev_info dev_info;
+	const struct rte_cryptodev_capabilities *cap;
+
+	rte_cryptodev_info_get(cdev_id, &dev_info);
+	cap = &dev_info.capabilities[0];
+
+	while (cap->op != RTE_CRYPTO_OP_TYPE_UNDEFINED) {
+		if (cap->sym.xform_type != xform->type)
+			continue;
+
+
+		if ((xform->type == RTE_CRYPTO_SYM_XFORM_CIPHER) &&
+				(cap->sym.cipher.algo == xform->cipher.algo))
+			return cap->sym.cipher.block_size;
+
+		if ((xform->type == RTE_CRYPTO_SYM_XFORM_AEAD) &&
+				(cap->sym.aead.algo == xform->aead.algo))
+			return cap->sym.aead.block_size;
+
+		cap = &dev_info.capabilities[++i];
+	}
+
+	return -1;
+}
+
+static int
+sym_crypto_apply(struct sym_crypto_data *data,
+	struct rte_table_action_sym_crypto_config *cfg,
+	struct rte_table_action_sym_crypto_params *p)
+{
+	struct rte_cryptodev_sym_session *sess;
+	struct rte_crypto_sym_xform *xform = p->xform;
+	struct rte_crypto_cipher_xform *cipher_xform = NULL;
+	struct rte_crypto_auth_xform *auth_xform = NULL;
+	struct rte_crypto_aead_xform *aead_xform = NULL;
+	int ret;
+
+	memset(data, 0, sizeof(*data));
+
+	while (xform) {
+		if (xform->type == RTE_CRYPTO_SYM_XFORM_CIPHER) {
+			cipher_xform = &xform->cipher;
+
+			if (cipher_xform->iv.length >
+				RTE_TABLE_ACTION_SYM_CRYPTO_IV_SIZE_MAX)
+			return -ENOMEM;
+
+			ret = get_block_size(xform, cfg->cryptodev_id);
+			if (ret < 0)
+				return -1;
+			data->block_size = (uint16_t)ret;
+			data->op_mask |= CRYPTO_OP_MASK_CIPHER;
+
+			data->cipher_auth.cipher_iv_data_offset = (uint16_t)
+					p->cipher_auth.cipher_iv.offset;
+			data->cipher_auth.cipher_iv_len =
+					cipher_xform->iv.length;
+			data->cipher_auth.cipher_iv_update_len = (uint16_t)
+					p->cipher_auth.cipher_iv.length;
+
+			rte_memcpy(data->iv_aad_data,
+					p->cipher_auth.cipher_iv.val,
+					p->cipher_auth.cipher_iv.length);
+
+			data->direction = cipher_xform->op;
+
+			cipher_xform->iv.offset = CRYPTO_IV_OFFSET;
+
+		} else if (xform->type == RTE_CRYPTO_SYM_XFORM_AUTH) {
+			auth_xform = &xform->auth;
+			if (auth_xform->iv.length >
+				RTE_TABLE_ACTION_SYM_CRYPTO_IV_SIZE_MAX)
+				return -ENOMEM;
+			data->op_mask |= CRYPTO_OP_MASK_AUTH;
+
+			data->cipher_auth.auth_iv_data_offset =
+					(uint16_t)p->cipher_auth.auth_iv.offset;
+			data->cipher_auth.auth_iv_len = auth_xform->iv.length;
+			data->cipher_auth.auth_iv_update_len = (uint16_t)
+					p->cipher_auth.auth_iv.length;
+			data->digest_len = auth_xform->digest_length;
+
+			if (auth_xform->iv.length)
+				auth_xform->iv.offset = CRYPTO_IV_OFFSET +
+				RTE_TABLE_ACTION_SYM_CRYPTO_IV_SIZE_MAX;
+
+			data->direction = (auth_xform->op ==
+					RTE_CRYPTO_AUTH_OP_GENERATE) ?
+					RTE_CRYPTO_CIPHER_OP_ENCRYPT :
+					RTE_CRYPTO_CIPHER_OP_DECRYPT;
+
+		} else if (xform->type == RTE_CRYPTO_SYM_XFORM_AEAD) {
+			aead_xform = &xform->aead;
+
+			if ((aead_xform->iv.length >
+				RTE_TABLE_ACTION_SYM_CRYPTO_IV_SIZE_MAX) || (
+				aead_xform->aad_length >
+				RTE_TABLE_ACTION_SYM_CRYPTO_AAD_SIZE_MAX))
+				return -EINVAL;
+
+			ret = get_block_size(xform, cfg->cryptodev_id);
+			if (ret < 0)
+				return -1;
+			data->block_size = (uint16_t)ret;
+			data->op_mask |= CRYPTO_OP_MASK_AEAD;
+			data->digest_len = aead_xform->digest_length;
+
+			data->aead.iv_data_offset = (uint16_t)p->aead.iv.offset;
+			data->aead.iv_len = aead_xform->iv.length;
+			data->aead.iv_update_len = (uint16_t)p->aead.iv.length;
+
+			data->aead.aad_data_offset = (uint16_t)
+					p->aead.aad.offset;
+			data->aead.aad_len = aead_xform->aad_length;
+			data->aead.aad_update_len =
+					(uint16_t)p->aead.aad.length;
+
+			if (aead_xform->iv.length)
+				aead_xform->iv.offset = CRYPTO_IV_OFFSET;
+
+			rte_memcpy(data->iv_aad_data,
+					p->aead.iv.val,
+					p->aead.iv.length);
+
+			rte_memcpy(data->iv_aad_data + p->aead.iv.length,
+					p->aead.aad.val,
+					p->aead.aad.length);
+
+			data->direction = (aead_xform->op ==
+					RTE_CRYPTO_AEAD_OP_ENCRYPT) ?
+					RTE_CRYPTO_CIPHER_OP_ENCRYPT :
+					RTE_CRYPTO_CIPHER_OP_DECRYPT;
+		} else
+			return -EINVAL;
+
+		xform = xform->next;
+	}
+
+	data->data_offset = (uint16_t)p->data_offset;
+
+	sess = rte_cryptodev_sym_session_create(cfg->mempool_session_create);
+	if (!sess) {
+		memset(data, 0, sizeof(*data));
+		return -ENOMEM;
+	}
+
+	ret = rte_cryptodev_sym_session_init(cfg->cryptodev_id, sess, xform,
+			cfg->mempool_session_init);
+	if (ret < 0) {
+		memset(data, 0, sizeof(*data));
+		return ret;
+	}
+
+	data->session = sess;
+
+	return 0;
+}
+
+static __rte_always_inline uint64_t
+pkt_work_sym_crypto(struct rte_mbuf *mbuf, struct sym_crypto_data *data,
+		struct rte_table_action_sym_crypto_config *cfg,
+		uint16_t ip_offset)
+{
+	struct crypto_op_sym_iv_aad *crypto_op = (struct crypto_op_sym_iv_aad *)
+			RTE_MBUF_METADATA_UINT8_PTR(mbuf, cfg->op_offset);
+	struct rte_crypto_op *op = &crypto_op->op;
+	uint16_t rel_ip_offset = ip_offset - mbuf->data_off;
+	uint16_t payload_len = 0;
+
+	op->sym->m_src = mbuf;
+	op->sym->m_dst = NULL;
+	op->type = RTE_CRYPTO_OP_TYPE_SYMMETRIC;
+	op->sess_type = RTE_CRYPTO_OP_WITH_SESSION;
+	op->phys_addr = rte_pktmbuf_iova_offset(mbuf, cfg->op_offset);
+	op->status = RTE_CRYPTO_OP_STATUS_NOT_PROCESSED;
+	op->sym->session = data->session;
+
+	/** pad the packet */
+	if (data->direction == RTE_CRYPTO_CIPHER_OP_ENCRYPT) {
+		payload_len = RTE_ALIGN_CEIL(rte_pktmbuf_pkt_len(mbuf) -
+				(data->data_offset + rel_ip_offset),
+				data->block_size) - rte_pktmbuf_pkt_len(mbuf);
+
+		if (unlikely(rte_pktmbuf_append(mbuf, payload_len +
+				data->digest_len) == NULL))
+			return 1;
+	}
+
+	payload_len = rte_pktmbuf_pkt_len(mbuf);
+
+	if (data->op_mask & CRYPTO_OP_MASK_CIPHER) {
+		/** prepare cipher op */
+		uint8_t *iv = crypto_op->iv_aad.cipher_auth.cipher_iv;
+
+		op->sym->cipher.data.length = payload_len;
+		op->sym->cipher.data.offset = data->data_offset + rel_ip_offset;
+
+		if (data->cipher_auth.cipher_iv_update_len) {
+			uint8_t *pkt_iv = RTE_MBUF_METADATA_UINT8_PTR(mbuf,
+				data->cipher_auth.cipher_iv_data_offset
+				+ ip_offset);
+
+			/** For encryption, update the pkt iv field, otherwise
+			 *  update the iv_aad_field
+			 **/
+			if (data->direction == RTE_CRYPTO_CIPHER_OP_ENCRYPT)
+				rte_memcpy(pkt_iv, data->iv_aad_data,
+					data->cipher_auth.cipher_iv_update_len);
+			else
+				rte_memcpy(data->iv_aad_data, pkt_iv,
+					data->cipher_auth.cipher_iv_update_len);
+		}
+
+		/** write iv */
+		rte_memcpy(iv, data->iv_aad_data,
+				data->cipher_auth.cipher_iv_len);
+	}
+
+	if (data->op_mask & CRYPTO_OP_MASK_AUTH) {
+		op->sym->auth.data.offset = rel_ip_offset;
+		op->sym->auth.data.length = payload_len;
+		op->sym->auth.digest.data = rte_pktmbuf_mtod_offset(mbuf,
+				uint8_t *, rte_pktmbuf_pkt_len(mbuf) -
+				data->digest_len);
+		op->sym->auth.digest.phys_addr = rte_pktmbuf_iova_offset(mbuf,
+				rte_pktmbuf_pkt_len(mbuf) - data->digest_len);
+
+		if (data->cipher_auth.auth_iv_update_len) {
+			uint8_t *pkt_iv = RTE_MBUF_METADATA_UINT8_PTR(mbuf,
+					data->cipher_auth.auth_iv_data_offset
+					+ ip_offset);
+			uint8_t *data_iv = data->iv_aad_data +
+					data->cipher_auth.cipher_iv_len;
+
+			if (data->direction == RTE_CRYPTO_CIPHER_OP_ENCRYPT)
+				rte_memcpy(pkt_iv, data_iv,
+					data->cipher_auth.auth_iv_update_len);
+			else
+				rte_memcpy(data_iv, pkt_iv,
+					data->cipher_auth.auth_iv_update_len);
+		}
+
+		if (data->cipher_auth.auth_iv_len) {
+			/** prepare cipher op */
+			uint8_t *iv = crypto_op->iv_aad.cipher_auth.auth_iv;
+
+			rte_memcpy(iv, data->iv_aad_data +
+					data->cipher_auth.cipher_iv_len,
+					data->cipher_auth.auth_iv_len);
+		}
+	}
+
+	if (data->op_mask & CRYPTO_OP_MASK_AEAD) {
+		uint8_t *iv = crypto_op->iv_aad.aead_iv_aad.iv;
+		uint8_t *aad = crypto_op->iv_aad.aead_iv_aad.aad;
+
+		op->sym->aead.aad.data = aad;
+		op->sym->aead.aad.phys_addr = op->phys_addr +
+				CRYPTO_IV_OFFSET +
+				RTE_TABLE_ACTION_SYM_CRYPTO_IV_SIZE_MAX;
+		op->sym->aead.digest.data = rte_pktmbuf_mtod_offset(mbuf,
+				uint8_t *, rte_pktmbuf_pkt_len(mbuf) -
+				data->digest_len);
+		op->sym->aead.digest.phys_addr = rte_pktmbuf_iova_offset(mbuf,
+				rte_pktmbuf_pkt_len(mbuf) - data->digest_len);
+		op->sym->aead.data.offset = data->data_offset + rel_ip_offset;
+		op->sym->aead.data.length = payload_len;
+
+		if (data->aead.iv_update_len) {
+			uint8_t *pkt_iv = RTE_MBUF_METADATA_UINT8_PTR(mbuf,
+					data->aead.iv_data_offset + ip_offset);
+			uint8_t *data_iv = data->iv_aad_data;
+
+			if (data->direction == RTE_CRYPTO_CIPHER_OP_ENCRYPT)
+				rte_memcpy(pkt_iv, data_iv,
+						data->aead.iv_update_len);
+			else
+				rte_memcpy(data_iv, pkt_iv,
+					data->aead.iv_update_len);
+		}
+
+		rte_memcpy(iv, data->iv_aad_data, data->aead.iv_len);
+
+
+		if (data->aead.aad_update_len) {
+			uint8_t *pkt_aad = RTE_MBUF_METADATA_UINT8_PTR(mbuf,
+					data->aead.aad_data_offset + ip_offset);
+			uint8_t *data_aad = data->iv_aad_data +
+					data->aead.iv_len;
+
+			if (data->direction == RTE_CRYPTO_CIPHER_OP_ENCRYPT)
+				rte_memcpy(pkt_aad, data_aad,
+						data->aead.iv_update_len);
+			else
+				rte_memcpy(data_aad, pkt_aad,
+					data->aead.iv_update_len);
+		}
+
+		rte_memcpy(aad, data->iv_aad_data + data->aead.iv_len,
+					data->aead.aad_len);
+	}
+
+	return 0;
+}
+
 /**
  * Action profile
  */
@@ -1235,6 +1658,7 @@ action_valid(enum rte_table_action_type action)
 	case RTE_TABLE_ACTION_TTL:
 	case RTE_TABLE_ACTION_STATS:
 	case RTE_TABLE_ACTION_TIME:
+	case RTE_TABLE_ACTION_SYM_CRYPTO:
 		return 1;
 	default:
 		return 0;
@@ -1254,6 +1678,7 @@ struct ap_config {
 	struct rte_table_action_nat_config nat;
 	struct rte_table_action_ttl_config ttl;
 	struct rte_table_action_stats_config stats;
+	struct rte_table_action_sym_crypto_config crypto;
 };
 
 static size_t
@@ -1274,6 +1699,8 @@ action_cfg_size(enum rte_table_action_type action)
 		return sizeof(struct rte_table_action_ttl_config);
 	case RTE_TABLE_ACTION_STATS:
 		return sizeof(struct rte_table_action_stats_config);
+	case RTE_TABLE_ACTION_SYM_CRYPTO:
+		return sizeof(struct rte_table_action_sym_crypto_config);
 	default:
 		return 0;
 	}
@@ -1305,6 +1732,8 @@ action_cfg_get(struct ap_config *ap_config,
 	case RTE_TABLE_ACTION_STATS:
 		return &ap_config->stats;
 
+	case RTE_TABLE_ACTION_SYM_CRYPTO:
+		return &ap_config->crypto;
 	default:
 		return NULL;
 	}
@@ -1460,6 +1889,10 @@ rte_table_action_profile_action_register(struct rte_table_action_profile *profil
 		status = stats_cfg_check(action_config);
 		break;
 
+	case RTE_TABLE_ACTION_SYM_CRYPTO:
+		status = sym_crypto_cfg_check(action_config);
+		break;
+
 	default:
 		status = 0;
 		break;
@@ -1609,6 +2042,11 @@ rte_table_action_apply(struct rte_table_action *action,
 		return time_apply(action_data,
 			action_params);
 
+	case RTE_TABLE_ACTION_SYM_CRYPTO:
+		return sym_crypto_apply(action_data,
+				&action->cfg.crypto,
+				action_params);
+
 	default:
 		return -EINVAL;
 	}
@@ -1966,6 +2404,14 @@ pkt_work(struct rte_mbuf *mbuf,
 		pkt_work_time(data, time);
 	}
 
+	if (cfg->action_mask & (1LLU << RTE_TABLE_ACTION_SYM_CRYPTO)) {
+		void *data = action_data_get(table_entry, action,
+				RTE_TABLE_ACTION_SYM_CRYPTO);
+
+		drop_mask |= pkt_work_sym_crypto(mbuf, data, &cfg->crypto,
+				ip_offset);
+	}
+
 	return drop_mask;
 }
 
@@ -2254,6 +2700,26 @@ pkt4_work(struct rte_mbuf **mbufs,
 		pkt_work_time(data3, time);
 	}
 
+	if (cfg->action_mask & (1LLU << RTE_TABLE_ACTION_SYM_CRYPTO)) {
+		void *data0 = action_data_get(table_entry0, action,
+				RTE_TABLE_ACTION_SYM_CRYPTO);
+		void *data1 = action_data_get(table_entry1, action,
+				RTE_TABLE_ACTION_SYM_CRYPTO);
+		void *data2 = action_data_get(table_entry2, action,
+				RTE_TABLE_ACTION_SYM_CRYPTO);
+		void *data3 = action_data_get(table_entry3, action,
+				RTE_TABLE_ACTION_SYM_CRYPTO);
+
+		drop_mask0 |= pkt_work_sym_crypto(mbuf0, data0, &cfg->crypto,
+				ip_offset);
+		drop_mask1 |= pkt_work_sym_crypto(mbuf1, data1, &cfg->crypto,
+				ip_offset);
+		drop_mask2 |= pkt_work_sym_crypto(mbuf2, data2, &cfg->crypto,
+				ip_offset);
+		drop_mask3 |= pkt_work_sym_crypto(mbuf3, data3, &cfg->crypto,
+				ip_offset);
+	}
+
 	return drop_mask0 |
 		(drop_mask1 << 1) |
 		(drop_mask2 << 2) |
diff --git a/lib/librte_pipeline/rte_table_action.h b/lib/librte_pipeline/rte_table_action.h
index c7f751aae..897f42308 100644
--- a/lib/librte_pipeline/rte_table_action.h
+++ b/lib/librte_pipeline/rte_table_action.h
@@ -93,6 +93,9 @@ enum rte_table_action_type {
 
 	/** Timestamp. */
 	RTE_TABLE_ACTION_TIME,
+
+	/** Crypto. */
+	RTE_TABLE_ACTION_SYM_CRYPTO,
 };
 
 /** Common action configuration (per table action profile). */
@@ -898,6 +901,73 @@ rte_table_action_time_read(struct rte_table_action *action,
 	void *data,
 	uint64_t *timestamp);
 
+
+/**
+ * RTE_TABLE_ACTION_CRYPTO
+ */
+/** Symmetric crypto action configuration (per table action profile). */
+struct rte_table_action_sym_crypto_config {
+	/** Target Cryptodev ID. */
+	uint8_t cryptodev_id;
+
+	/** Crypto Session mempool. */
+	struct rte_mempool *mempool_session_create;
+
+	/** Crypto session init mempool, used for init cryptodev session. */
+	struct rte_mempool *mempool_session_init;
+
+	/** The offset to fetch rte_crypto_op. */
+	uint32_t op_offset;
+};
+
+#ifndef RTE_TABLE_ACTION_SYM_CRYPTO_IV_SIZE_MAX
+#define RTE_TABLE_ACTION_SYM_CRYPTO_IV_SIZE_MAX		(16)
+#endif
+
+#ifndef RTE_TABLE_ACTION_SYM_CRYPTO_AAD_SIZE_MAX
+#define RTE_TABLE_ACTION_SYM_CRYPTO_AAD_SIZE_MAX	(16)
+#endif
+
+/** Common action structure to store the data's value, length, and offset */
+struct rte_table_action_vlo {
+	uint8_t *val;
+	uint32_t length;
+	uint32_t offset;
+};
+
+/** Symmetric Crypto action parameters (per table rule). */
+struct rte_table_action_sym_crypto_params {
+
+	/** Xform pointer contains all relevant information */
+	struct rte_crypto_sym_xform *xform;
+
+	/**
+	 * Offset from start of IP packet to the first packet byte to be
+	 * processed by the crypto unit.
+	 **/
+	uint32_t data_offset;
+
+	union {
+		struct {
+			/** Cipher iv data, offset from start of ip header */
+			struct rte_table_action_vlo cipher_iv;
+
+			/** Auth iv data, offset from start of ip header */
+			struct rte_table_action_vlo auth_iv;
+
+		} cipher_auth;
+
+		struct {
+			/** AEAD AAD data, offset from start of ip header */
+			struct rte_table_action_vlo aad;
+
+			/** AEAD iv data, offset from start of ip header */
+			struct rte_table_action_vlo iv;
+
+		} aead;
+	};
+};
+
 #ifdef __cplusplus
 }
 #endif
-- 
2.13.6

^ permalink raw reply	[flat|nested] 10+ messages in thread

* [dpdk-dev] [PATCH v2 0/7] pipeline: add symmetric crypto to action
  2018-08-28  8:19 [dpdk-dev] [PATCH] pipeline: add symmetric crypto to table action Zhang, Roy Fan
@ 2018-09-28 12:26 ` Fan Zhang
  2018-09-28 12:26   ` [dpdk-dev] [PATCH v2 1/7] " Fan Zhang
                     ` (7 more replies)
  0 siblings, 8 replies; 10+ messages in thread
From: Fan Zhang @ 2018-09-28 12:26 UTC (permalink / raw)
  To: dev; +Cc: cristian.dumitrescu

This patchset creates an abstraction layer of DPDK Cryptodev to the pipeline
library to enable its symmetric cryptographic capability. The ip_pipeline
sample application is updated accordingly.

v2:
- Fixed bugs.
- Updated data structure.
- Updated IP-pipeline sample application.

Zhang, Roy Fan (7):
  pipeline: add symmetric crypto to action
  examples/ip_pipeline: add cryptodev
  examples/ip_pipeline: configure crypto port
  examples/ip_pipeline: add symmetric crypto action
  examples/ip_pipeline: update cli parsing
  examples/ip_pipeline: add script
  doc: update action documentation

 doc/guides/prog_guide/packet_framework.rst    |  11 +-
 doc/guides/sample_app_ug/ip_pipeline.rst      |  23 +
 examples/ip_pipeline/Makefile                 |   1 +
 examples/ip_pipeline/action.c                 |  11 +
 examples/ip_pipeline/action.h                 |   1 +
 examples/ip_pipeline/cli.c                    | 577 +++++++++++++++++++++++++-
 examples/ip_pipeline/cryptodev.c              | 117 ++++++
 examples/ip_pipeline/cryptodev.h              |  43 ++
 examples/ip_pipeline/examples/flow_crypto.cli |  58 +++
 examples/ip_pipeline/main.c                   |   9 +
 examples/ip_pipeline/meson.build              |   3 +-
 examples/ip_pipeline/pipeline.c               |  60 +++
 examples/ip_pipeline/pipeline.h               |  14 +
 examples/ip_pipeline/thread.c                 |  10 +
 lib/librte_pipeline/Makefile                  |   2 +-
 lib/librte_pipeline/meson.build               |   2 +-
 lib/librte_pipeline/rte_pipeline_version.map  |   1 +
 lib/librte_pipeline/rte_table_action.c        | 503 +++++++++++++++++++++-
 lib/librte_pipeline/rte_table_action.h        | 104 +++++
 19 files changed, 1543 insertions(+), 7 deletions(-)
 create mode 100644 examples/ip_pipeline/cryptodev.c
 create mode 100644 examples/ip_pipeline/cryptodev.h
 create mode 100644 examples/ip_pipeline/examples/flow_crypto.cli

-- 
2.13.6

^ permalink raw reply	[flat|nested] 10+ messages in thread

* [dpdk-dev] [PATCH v2 1/7] pipeline: add symmetric crypto to action
  2018-09-28 12:26 ` [dpdk-dev] [PATCH v2 0/7] pipeline: add symmetric crypto to action Fan Zhang
@ 2018-09-28 12:26   ` Fan Zhang
  2018-09-28 12:26   ` [dpdk-dev] [PATCH v2 2/7] examples/ip_pipeline: add cryptodev Fan Zhang
                     ` (6 subsequent siblings)
  7 siblings, 0 replies; 10+ messages in thread
From: Fan Zhang @ 2018-09-28 12:26 UTC (permalink / raw)
  To: dev; +Cc: cristian.dumitrescu, Zhang, Roy Fan, Zhang

From: "Zhang, Roy Fan" <roy.fan.zhang@intel.com>

This patch adds the symmetric crypto action support to pipeline
library. The symmetric crypto action works as the shim layer
between pipeline and DPDK cryptodev and is able to interact with
cryptodev with the control path requests such as session
creation/deletion and data path work to assemble the crypto
operations for received packets.

Signed-off-by: Zhang, Roy Fan <roy.fan.zhang@intel.com>
Acked-by: Dumitrescu, Cristian <cristian.dumitrescu@intel.com>
---
 lib/librte_pipeline/Makefile                 |   2 +-
 lib/librte_pipeline/meson.build              |   2 +-
 lib/librte_pipeline/rte_pipeline_version.map |   1 +
 lib/librte_pipeline/rte_table_action.c       | 503 ++++++++++++++++++++++++++-
 lib/librte_pipeline/rte_table_action.h       | 104 ++++++
 5 files changed, 609 insertions(+), 3 deletions(-)

diff --git a/lib/librte_pipeline/Makefile b/lib/librte_pipeline/Makefile
index 84afe98cb..cf265503f 100644
--- a/lib/librte_pipeline/Makefile
+++ b/lib/librte_pipeline/Makefile
@@ -12,7 +12,7 @@ CFLAGS += -DALLOW_EXPERIMENTAL_API
 CFLAGS += -O3
 CFLAGS += $(WERROR_FLAGS)
 LDLIBS += -lrte_eal -lrte_mempool -lrte_mbuf -lrte_table
-LDLIBS += -lrte_port -lrte_meter -lrte_sched
+LDLIBS += -lrte_port -lrte_meter -lrte_sched -lrte_cryptodev
 
 EXPORT_MAP := rte_pipeline_version.map
 
diff --git a/lib/librte_pipeline/meson.build b/lib/librte_pipeline/meson.build
index dc16ab42f..04e5f5179 100644
--- a/lib/librte_pipeline/meson.build
+++ b/lib/librte_pipeline/meson.build
@@ -5,4 +5,4 @@ version = 3
 allow_experimental_apis = true
 sources = files('rte_pipeline.c', 'rte_port_in_action.c', 'rte_table_action.c')
 headers = files('rte_pipeline.h', 'rte_port_in_action.h', 'rte_table_action.h')
-deps += ['port', 'table', 'meter', 'sched']
+deps += ['port', 'table', 'meter', 'sched', 'cryptodev']
diff --git a/lib/librte_pipeline/rte_pipeline_version.map b/lib/librte_pipeline/rte_pipeline_version.map
index d820b22f6..420f065d6 100644
--- a/lib/librte_pipeline/rte_pipeline_version.map
+++ b/lib/librte_pipeline/rte_pipeline_version.map
@@ -72,4 +72,5 @@ EXPERIMENTAL {
 	rte_table_action_stats_read;
 	rte_table_action_time_read;
 	rte_table_action_ttl_read;
+	rte_table_action_crypto_sym_session_get;
 };
diff --git a/lib/librte_pipeline/rte_table_action.c b/lib/librte_pipeline/rte_table_action.c
index 338dcfeee..edb334021 100644
--- a/lib/librte_pipeline/rte_table_action.c
+++ b/lib/librte_pipeline/rte_table_action.c
@@ -1,7 +1,6 @@
 /* SPDX-License-Identifier: BSD-3-Clause
  * Copyright(c) 2010-2018 Intel Corporation
  */
-
 #include <stdlib.h>
 #include <string.h>
 
@@ -15,6 +14,8 @@
 #include <rte_esp.h>
 #include <rte_tcp.h>
 #include <rte_udp.h>
+#include <rte_cryptodev.h>
+#include <rte_cryptodev_pmd.h>
 
 #include "rte_table_action.h"
 
@@ -1575,6 +1576,441 @@ pkt_work_time(struct time_data *data,
 	data->time = time;
 }
 
+
+/**
+ * RTE_TABLE_ACTION_CRYPTO
+ */
+
+#define CRYPTO_OP_MASK_CIPHER	0x1
+#define CRYPTO_OP_MASK_AUTH	0x2
+#define CRYPTO_OP_MASK_AEAD	0x4
+
+struct crypto_op_sym_iv_aad {
+	struct rte_crypto_op op;
+	struct rte_crypto_sym_op sym_op;
+	union {
+		struct {
+			uint8_t cipher_iv[
+				RTE_TABLE_ACTION_SYM_CRYPTO_IV_SIZE_MAX];
+			uint8_t auth_iv[
+				RTE_TABLE_ACTION_SYM_CRYPTO_IV_SIZE_MAX];
+		} cipher_auth;
+
+		struct {
+			uint8_t iv[RTE_TABLE_ACTION_SYM_CRYPTO_IV_SIZE_MAX];
+			uint8_t aad[RTE_TABLE_ACTION_SYM_CRYPTO_AAD_SIZE_MAX];
+		} aead_iv_aad;
+
+	} iv_aad;
+};
+
+struct sym_crypto_data {
+
+	union {
+		struct {
+
+			/** Length of cipher iv. */
+			uint16_t cipher_iv_len;
+
+			/** Offset from start of IP header to the cipher iv. */
+			uint16_t cipher_iv_data_offset;
+
+			/** Length of cipher iv to be updated in the mbuf. */
+			uint16_t cipher_iv_update_len;
+
+			/** Offset from start of IP header to the auth iv. */
+			uint16_t auth_iv_data_offset;
+
+			/** Length of auth iv in the mbuf. */
+			uint16_t auth_iv_len;
+
+			/** Length of auth iv to be updated in the mbuf. */
+			uint16_t auth_iv_update_len;
+
+		} cipher_auth;
+		struct {
+
+			/** Length of iv. */
+			uint16_t iv_len;
+
+			/** Offset from start of IP header to the aead iv. */
+			uint16_t iv_data_offset;
+
+			/** Length of iv to be updated in the mbuf. */
+			uint16_t iv_update_len;
+
+			/** Length of aad */
+			uint16_t aad_len;
+
+			/** Offset from start of IP header to the aad. */
+			uint16_t aad_data_offset;
+
+			/** Length of aad to updated in the mbuf. */
+			uint16_t aad_update_len;
+
+		} aead;
+	};
+
+	/** Offset from start of IP header to the data. */
+	uint16_t data_offset;
+
+	/** Digest length. */
+	uint16_t digest_len;
+
+	/** block size */
+	uint16_t block_size;
+
+	/** Mask of crypto operation */
+	uint16_t op_mask;
+
+	/** Session pointer. */
+	struct rte_cryptodev_sym_session *session;
+
+	/** Direction of crypto, encrypt or decrypt */
+	uint16_t direction;
+
+	/** Private data size to store cipher iv / aad. */
+	uint8_t iv_aad_data[32];
+
+} __attribute__((__packed__));
+
+static int
+sym_crypto_cfg_check(struct rte_table_action_sym_crypto_config *cfg)
+{
+	if (!rte_cryptodev_pmd_is_valid_dev(cfg->cryptodev_id))
+		return -EINVAL;
+	if (cfg->mp_create == NULL || cfg->mp_init == NULL)
+		return -EINVAL;
+
+	return 0;
+}
+
+static int
+get_block_size(const struct rte_crypto_sym_xform *xform, uint8_t cdev_id)
+{
+	struct rte_cryptodev_info dev_info;
+	const struct rte_cryptodev_capabilities *cap;
+	uint32_t i;
+
+	rte_cryptodev_info_get(cdev_id, &dev_info);
+
+	for (i = 0;; i++) {
+		cap = &dev_info.capabilities[i];
+		if (!cap)
+			break;
+
+		if (cap->sym.xform_type != xform->type)
+			continue;
+
+		if ((xform->type == RTE_CRYPTO_SYM_XFORM_CIPHER) &&
+				(cap->sym.cipher.algo == xform->cipher.algo))
+			return cap->sym.cipher.block_size;
+
+		if ((xform->type == RTE_CRYPTO_SYM_XFORM_AEAD) &&
+				(cap->sym.aead.algo == xform->aead.algo))
+			return cap->sym.aead.block_size;
+
+		if (xform->type == RTE_CRYPTO_SYM_XFORM_NOT_SPECIFIED)
+			break;
+	}
+
+	return -1;
+}
+
+static int
+sym_crypto_apply(struct sym_crypto_data *data,
+	struct rte_table_action_sym_crypto_config *cfg,
+	struct rte_table_action_sym_crypto_params *p)
+{
+	const struct rte_crypto_cipher_xform *cipher_xform = NULL;
+	const struct rte_crypto_auth_xform *auth_xform = NULL;
+	const struct rte_crypto_aead_xform *aead_xform = NULL;
+	struct rte_crypto_sym_xform *xform = p->xform;
+	struct rte_cryptodev_sym_session *session;
+	int ret;
+
+	memset(data, 0, sizeof(*data));
+
+	while (xform) {
+		if (xform->type == RTE_CRYPTO_SYM_XFORM_CIPHER) {
+			cipher_xform = &xform->cipher;
+
+			if (cipher_xform->iv.length >
+				RTE_TABLE_ACTION_SYM_CRYPTO_IV_SIZE_MAX)
+				return -ENOMEM;
+			if (cipher_xform->iv.offset !=
+					RTE_TABLE_ACTION_SYM_CRYPTO_IV_OFFSET)
+				return -EINVAL;
+
+			ret = get_block_size(xform, cfg->cryptodev_id);
+			if (ret < 0)
+				return -1;
+			data->block_size = (uint16_t)ret;
+			data->op_mask |= CRYPTO_OP_MASK_CIPHER;
+
+			data->cipher_auth.cipher_iv_len =
+					cipher_xform->iv.length;
+			data->cipher_auth.cipher_iv_data_offset = (uint16_t)
+					p->cipher_auth.cipher_iv_update.offset;
+			data->cipher_auth.cipher_iv_update_len = (uint16_t)
+					p->cipher_auth.cipher_iv_update.length;
+
+			rte_memcpy(data->iv_aad_data,
+					p->cipher_auth.cipher_iv.val,
+					p->cipher_auth.cipher_iv.length);
+
+			data->direction = cipher_xform->op;
+
+		} else if (xform->type == RTE_CRYPTO_SYM_XFORM_AUTH) {
+			auth_xform = &xform->auth;
+			if (auth_xform->iv.length >
+				RTE_TABLE_ACTION_SYM_CRYPTO_IV_SIZE_MAX)
+				return -ENOMEM;
+			data->op_mask |= CRYPTO_OP_MASK_AUTH;
+
+			data->cipher_auth.auth_iv_len = auth_xform->iv.length;
+			data->cipher_auth.auth_iv_data_offset = (uint16_t)
+					p->cipher_auth.auth_iv_update.offset;
+			data->cipher_auth.auth_iv_update_len = (uint16_t)
+					p->cipher_auth.auth_iv_update.length;
+			data->digest_len = auth_xform->digest_length;
+
+			data->direction = (auth_xform->op ==
+					RTE_CRYPTO_AUTH_OP_GENERATE) ?
+					RTE_CRYPTO_CIPHER_OP_ENCRYPT :
+					RTE_CRYPTO_CIPHER_OP_DECRYPT;
+
+		} else if (xform->type == RTE_CRYPTO_SYM_XFORM_AEAD) {
+			aead_xform = &xform->aead;
+
+			if ((aead_xform->iv.length >
+				RTE_TABLE_ACTION_SYM_CRYPTO_IV_SIZE_MAX) || (
+				aead_xform->aad_length >
+				RTE_TABLE_ACTION_SYM_CRYPTO_AAD_SIZE_MAX))
+				return -EINVAL;
+			if (aead_xform->iv.offset !=
+					RTE_TABLE_ACTION_SYM_CRYPTO_IV_OFFSET)
+				return -EINVAL;
+
+			ret = get_block_size(xform, cfg->cryptodev_id);
+			if (ret < 0)
+				return -1;
+			data->block_size = (uint16_t)ret;
+			data->op_mask |= CRYPTO_OP_MASK_AEAD;
+
+			data->digest_len = aead_xform->digest_length;
+			data->aead.iv_len = aead_xform->iv.length;
+			data->aead.aad_len = aead_xform->aad_length;
+
+			data->aead.iv_data_offset = (uint16_t)
+					p->aead.iv_update.offset;
+			data->aead.iv_update_len = (uint16_t)
+					p->aead.iv_update.length;
+			data->aead.aad_data_offset = (uint16_t)
+					p->aead.aad_update.offset;
+			data->aead.aad_update_len = (uint16_t)
+					p->aead.aad_update.length;
+
+			rte_memcpy(data->iv_aad_data,
+					p->aead.iv.val,
+					p->aead.iv.length);
+
+			rte_memcpy(data->iv_aad_data + p->aead.iv.length,
+					p->aead.aad.val,
+					p->aead.aad.length);
+
+			data->direction = (aead_xform->op ==
+					RTE_CRYPTO_AEAD_OP_ENCRYPT) ?
+					RTE_CRYPTO_CIPHER_OP_ENCRYPT :
+					RTE_CRYPTO_CIPHER_OP_DECRYPT;
+		} else
+			return -EINVAL;
+
+		xform = xform->next;
+	}
+
+	if (auth_xform && auth_xform->iv.length) {
+		if (cipher_xform) {
+			if (auth_xform->iv.offset !=
+					RTE_TABLE_ACTION_SYM_CRYPTO_IV_OFFSET +
+					cipher_xform->iv.length)
+				return -EINVAL;
+
+			rte_memcpy(data->iv_aad_data + cipher_xform->iv.length,
+					p->cipher_auth.auth_iv.val,
+					p->cipher_auth.auth_iv.length);
+		} else {
+			rte_memcpy(data->iv_aad_data,
+					p->cipher_auth.auth_iv.val,
+					p->cipher_auth.auth_iv.length);
+		}
+	}
+
+	session = rte_cryptodev_sym_session_create(cfg->mp_create);
+	if (!session)
+		return -ENOMEM;
+
+	ret = rte_cryptodev_sym_session_init(cfg->cryptodev_id, session,
+			p->xform, cfg->mp_init);
+	if (ret < 0) {
+		rte_cryptodev_sym_session_free(session);
+		return ret;
+	}
+
+	data->data_offset = (uint16_t)p->data_offset;
+	data->session = session;
+
+	return 0;
+}
+
+static __rte_always_inline uint64_t
+pkt_work_sym_crypto(struct rte_mbuf *mbuf, struct sym_crypto_data *data,
+		struct rte_table_action_sym_crypto_config *cfg,
+		uint16_t ip_offset)
+{
+	struct crypto_op_sym_iv_aad *crypto_op = (struct crypto_op_sym_iv_aad *)
+			RTE_MBUF_METADATA_UINT8_PTR(mbuf, cfg->op_offset);
+	struct rte_crypto_op *op = &crypto_op->op;
+	struct rte_crypto_sym_op *sym = op->sym;
+	uint32_t pkt_offset = sizeof(*mbuf) + mbuf->data_off;
+	uint32_t payload_len = pkt_offset + mbuf->data_len - data->data_offset;
+
+	op->type = RTE_CRYPTO_OP_TYPE_SYMMETRIC;
+	op->sess_type = RTE_CRYPTO_OP_WITH_SESSION;
+	op->phys_addr = mbuf->buf_iova + cfg->op_offset - sizeof(*mbuf);
+	op->status = RTE_CRYPTO_OP_STATUS_NOT_PROCESSED;
+	sym->m_src = mbuf;
+	sym->m_dst = NULL;
+	sym->session = data->session;
+
+	/** pad the packet */
+	if (data->direction == RTE_CRYPTO_CIPHER_OP_ENCRYPT) {
+		uint32_t append_len = RTE_ALIGN_CEIL(payload_len,
+				data->block_size) - payload_len;
+
+		if (unlikely(rte_pktmbuf_append(mbuf, append_len +
+				data->digest_len) == NULL))
+			return 1;
+
+		payload_len += append_len;
+	} else
+		payload_len -= data->digest_len;
+
+	if (data->op_mask & CRYPTO_OP_MASK_CIPHER) {
+		/** prepare cipher op */
+		uint8_t *iv = crypto_op->iv_aad.cipher_auth.cipher_iv;
+
+		sym->cipher.data.length = payload_len;
+		sym->cipher.data.offset = data->data_offset - pkt_offset;
+
+		if (data->cipher_auth.cipher_iv_update_len) {
+			uint8_t *pkt_iv = RTE_MBUF_METADATA_UINT8_PTR(mbuf,
+				data->cipher_auth.cipher_iv_data_offset
+				+ ip_offset);
+
+			/** For encryption, update the pkt iv field, otherwise
+			 *  update the iv_aad_field
+			 **/
+			if (data->direction == RTE_CRYPTO_CIPHER_OP_ENCRYPT)
+				rte_memcpy(pkt_iv, data->iv_aad_data,
+					data->cipher_auth.cipher_iv_update_len);
+			else
+				rte_memcpy(data->iv_aad_data, pkt_iv,
+					data->cipher_auth.cipher_iv_update_len);
+		}
+
+		/** write iv */
+		rte_memcpy(iv, data->iv_aad_data,
+				data->cipher_auth.cipher_iv_len);
+	}
+
+	if (data->op_mask & CRYPTO_OP_MASK_AUTH) {
+		/** authentication always start from IP header. */
+		sym->auth.data.offset = ip_offset - pkt_offset;
+		sym->auth.data.length = mbuf->data_len - sym->auth.data.offset -
+				data->digest_len;
+		sym->auth.digest.data = rte_pktmbuf_mtod_offset(mbuf,
+				uint8_t *, rte_pktmbuf_pkt_len(mbuf) -
+				data->digest_len);
+		sym->auth.digest.phys_addr = rte_pktmbuf_iova_offset(mbuf,
+				rte_pktmbuf_pkt_len(mbuf) - data->digest_len);
+
+		if (data->cipher_auth.auth_iv_update_len) {
+			uint8_t *pkt_iv = RTE_MBUF_METADATA_UINT8_PTR(mbuf,
+					data->cipher_auth.auth_iv_data_offset
+					+ ip_offset);
+			uint8_t *data_iv = data->iv_aad_data +
+					data->cipher_auth.cipher_iv_len;
+
+			if (data->direction == RTE_CRYPTO_CIPHER_OP_ENCRYPT)
+				rte_memcpy(pkt_iv, data_iv,
+					data->cipher_auth.auth_iv_update_len);
+			else
+				rte_memcpy(data_iv, pkt_iv,
+					data->cipher_auth.auth_iv_update_len);
+		}
+
+		if (data->cipher_auth.auth_iv_len) {
+			/** prepare cipher op */
+			uint8_t *iv = crypto_op->iv_aad.cipher_auth.auth_iv;
+
+			rte_memcpy(iv, data->iv_aad_data +
+					data->cipher_auth.cipher_iv_len,
+					data->cipher_auth.auth_iv_len);
+		}
+	}
+
+	if (data->op_mask & CRYPTO_OP_MASK_AEAD) {
+		uint8_t *iv = crypto_op->iv_aad.aead_iv_aad.iv;
+		uint8_t *aad = crypto_op->iv_aad.aead_iv_aad.aad;
+
+		sym->aead.aad.data = aad;
+		sym->aead.aad.phys_addr = rte_pktmbuf_iova_offset(mbuf,
+				aad - rte_pktmbuf_mtod(mbuf, uint8_t *));
+		sym->aead.digest.data = rte_pktmbuf_mtod_offset(mbuf,
+				uint8_t *, rte_pktmbuf_pkt_len(mbuf) -
+				data->digest_len);
+		sym->aead.digest.phys_addr = rte_pktmbuf_iova_offset(mbuf,
+				rte_pktmbuf_pkt_len(mbuf) - data->digest_len);
+		sym->aead.data.offset = data->data_offset - pkt_offset;
+		sym->aead.data.length = payload_len;
+
+		if (data->aead.iv_update_len) {
+			uint8_t *pkt_iv = RTE_MBUF_METADATA_UINT8_PTR(mbuf,
+					data->aead.iv_data_offset + ip_offset);
+			uint8_t *data_iv = data->iv_aad_data;
+
+			if (data->direction == RTE_CRYPTO_CIPHER_OP_ENCRYPT)
+				rte_memcpy(pkt_iv, data_iv,
+						data->aead.iv_update_len);
+			else
+				rte_memcpy(data_iv, pkt_iv,
+					data->aead.iv_update_len);
+		}
+
+		rte_memcpy(iv, data->iv_aad_data, data->aead.iv_len);
+
+		if (data->aead.aad_update_len) {
+			uint8_t *pkt_aad = RTE_MBUF_METADATA_UINT8_PTR(mbuf,
+					data->aead.aad_data_offset + ip_offset);
+			uint8_t *data_aad = data->iv_aad_data +
+					data->aead.iv_len;
+
+			if (data->direction == RTE_CRYPTO_CIPHER_OP_ENCRYPT)
+				rte_memcpy(pkt_aad, data_aad,
+						data->aead.iv_update_len);
+			else
+				rte_memcpy(data_aad, pkt_aad,
+					data->aead.iv_update_len);
+		}
+
+		rte_memcpy(aad, data->iv_aad_data + data->aead.iv_len,
+					data->aead.aad_len);
+	}
+
+	return 0;
+}
+
 /**
  * Action profile
  */
@@ -1591,6 +2027,7 @@ action_valid(enum rte_table_action_type action)
 	case RTE_TABLE_ACTION_TTL:
 	case RTE_TABLE_ACTION_STATS:
 	case RTE_TABLE_ACTION_TIME:
+	case RTE_TABLE_ACTION_SYM_CRYPTO:
 		return 1;
 	default:
 		return 0;
@@ -1610,6 +2047,7 @@ struct ap_config {
 	struct rte_table_action_nat_config nat;
 	struct rte_table_action_ttl_config ttl;
 	struct rte_table_action_stats_config stats;
+	struct rte_table_action_sym_crypto_config sym_crypto;
 };
 
 static size_t
@@ -1630,6 +2068,8 @@ action_cfg_size(enum rte_table_action_type action)
 		return sizeof(struct rte_table_action_ttl_config);
 	case RTE_TABLE_ACTION_STATS:
 		return sizeof(struct rte_table_action_stats_config);
+	case RTE_TABLE_ACTION_SYM_CRYPTO:
+		return sizeof(struct rte_table_action_sym_crypto_config);
 	default:
 		return 0;
 	}
@@ -1661,6 +2101,8 @@ action_cfg_get(struct ap_config *ap_config,
 	case RTE_TABLE_ACTION_STATS:
 		return &ap_config->stats;
 
+	case RTE_TABLE_ACTION_SYM_CRYPTO:
+		return &ap_config->sym_crypto;
 	default:
 		return NULL;
 	}
@@ -1717,6 +2159,9 @@ action_data_size(enum rte_table_action_type action,
 	case RTE_TABLE_ACTION_TIME:
 		return sizeof(struct time_data);
 
+	case RTE_TABLE_ACTION_SYM_CRYPTO:
+		return (sizeof(struct sym_crypto_data));
+
 	default:
 		return 0;
 	}
@@ -1816,6 +2261,10 @@ rte_table_action_profile_action_register(struct rte_table_action_profile *profil
 		status = stats_cfg_check(action_config);
 		break;
 
+	case RTE_TABLE_ACTION_SYM_CRYPTO:
+		status = sym_crypto_cfg_check(action_config);
+		break;
+
 	default:
 		status = 0;
 		break;
@@ -1965,6 +2414,11 @@ rte_table_action_apply(struct rte_table_action *action,
 		return time_apply(action_data,
 			action_params);
 
+	case RTE_TABLE_ACTION_SYM_CRYPTO:
+		return sym_crypto_apply(action_data,
+				&action->cfg.sym_crypto,
+				action_params);
+
 	default:
 		return -EINVAL;
 	}
@@ -2217,6 +2671,25 @@ rte_table_action_time_read(struct rte_table_action *action,
 	return 0;
 }
 
+struct rte_cryptodev_sym_session *
+rte_table_action_crypto_sym_session_get(struct rte_table_action *action,
+	void *data)
+{
+	struct sym_crypto_data *sym_crypto_data;
+
+	/* Check input arguments */
+	if ((action == NULL) ||
+		((action->cfg.action_mask &
+		(1LLU << RTE_TABLE_ACTION_SYM_CRYPTO)) == 0) ||
+		(data == NULL))
+		return NULL;
+
+	sym_crypto_data = action_data_get(data, action,
+			RTE_TABLE_ACTION_SYM_CRYPTO);
+
+	return sym_crypto_data->session;
+}
+
 static __rte_always_inline uint64_t
 pkt_work(struct rte_mbuf *mbuf,
 	struct rte_pipeline_table_entry *table_entry,
@@ -2322,6 +2795,14 @@ pkt_work(struct rte_mbuf *mbuf,
 		pkt_work_time(data, time);
 	}
 
+	if (cfg->action_mask & (1LLU << RTE_TABLE_ACTION_SYM_CRYPTO)) {
+		void *data = action_data_get(table_entry, action,
+				RTE_TABLE_ACTION_SYM_CRYPTO);
+
+		drop_mask |= pkt_work_sym_crypto(mbuf, data, &cfg->sym_crypto,
+				ip_offset);
+	}
+
 	return drop_mask;
 }
 
@@ -2610,6 +3091,26 @@ pkt4_work(struct rte_mbuf **mbufs,
 		pkt_work_time(data3, time);
 	}
 
+	if (cfg->action_mask & (1LLU << RTE_TABLE_ACTION_SYM_CRYPTO)) {
+		void *data0 = action_data_get(table_entry0, action,
+				RTE_TABLE_ACTION_SYM_CRYPTO);
+		void *data1 = action_data_get(table_entry1, action,
+				RTE_TABLE_ACTION_SYM_CRYPTO);
+		void *data2 = action_data_get(table_entry2, action,
+				RTE_TABLE_ACTION_SYM_CRYPTO);
+		void *data3 = action_data_get(table_entry3, action,
+				RTE_TABLE_ACTION_SYM_CRYPTO);
+
+		drop_mask0 |= pkt_work_sym_crypto(mbuf0, data0, &cfg->sym_crypto,
+				ip_offset);
+		drop_mask1 |= pkt_work_sym_crypto(mbuf1, data1, &cfg->sym_crypto,
+				ip_offset);
+		drop_mask2 |= pkt_work_sym_crypto(mbuf2, data2, &cfg->sym_crypto,
+				ip_offset);
+		drop_mask3 |= pkt_work_sym_crypto(mbuf3, data3, &cfg->sym_crypto,
+				ip_offset);
+	}
+
 	return drop_mask0 |
 		(drop_mask1 << 1) |
 		(drop_mask2 << 2) |
diff --git a/lib/librte_pipeline/rte_table_action.h b/lib/librte_pipeline/rte_table_action.h
index 73b564c14..e8a7b66f8 100644
--- a/lib/librte_pipeline/rte_table_action.h
+++ b/lib/librte_pipeline/rte_table_action.h
@@ -93,6 +93,9 @@ enum rte_table_action_type {
 
 	/** Timestamp. */
 	RTE_TABLE_ACTION_TIME,
+
+	/** Crypto. */
+	RTE_TABLE_ACTION_SYM_CRYPTO,
 };
 
 /** Common action configuration (per table action profile). */
@@ -681,6 +684,93 @@ struct rte_table_action_time_params {
 };
 
 /**
+ * RTE_TABLE_ACTION_CRYPTO
+ */
+#ifndef RTE_TABLE_ACTION_SYM_CRYPTO_IV_SIZE_MAX
+#define RTE_TABLE_ACTION_SYM_CRYPTO_IV_SIZE_MAX		(16)
+#endif
+
+#ifndef RTE_TABLE_ACTION_SYM_CRYPTO_AAD_SIZE_MAX
+#define RTE_TABLE_ACTION_SYM_CRYPTO_AAD_SIZE_MAX	(16)
+#endif
+
+#ifndef RTE_TABLE_ACTION_SYM_CRYPTO_IV_OFFSET
+#define RTE_TABLE_ACTION_SYM_CRYPTO_IV_OFFSET				\
+	(sizeof(struct rte_crypto_op) + sizeof(struct rte_crypto_sym_op))
+#endif
+
+/** Common action structure to store the data's value, length, and offset */
+struct rte_table_action_vlo {
+	uint8_t *val;
+	uint32_t length;
+	uint32_t offset;
+};
+
+/** Symmetric crypto action configuration (per table action profile). */
+struct rte_table_action_sym_crypto_config {
+	/** Target Cryptodev ID. */
+	uint8_t cryptodev_id;
+
+	/**
+	 * Offset to rte_crypto_op structure within the input packet buffer.
+	 * Offset 0 points to the first byte of the MBUF structure.
+	 */
+	uint32_t op_offset;
+
+	/** The mempool for creating cryptodev sessions. */
+	struct rte_mempool *mp_create;
+
+	/** The mempool for initializing cryptodev sessions. */
+	struct rte_mempool *mp_init;
+};
+
+/** Symmetric Crypto action parameters (per table rule). */
+struct rte_table_action_sym_crypto_params {
+
+	/** Xform pointer contains all relevant information */
+	struct rte_crypto_sym_xform *xform;
+
+	/**
+	 * Offset within the input packet buffer to the first byte of data
+	 * to be processed by the crypto unit. Offset 0 points to the first
+	 * byte of the MBUF structure.
+	 */
+	uint32_t data_offset;
+
+	union {
+		struct {
+			/** Cipher iv data. */
+			struct rte_table_action_vlo cipher_iv;
+
+			/** Cipher iv data. */
+			struct rte_table_action_vlo cipher_iv_update;
+
+			/** Auth iv data. */
+			struct rte_table_action_vlo auth_iv;
+
+			/** Auth iv data. */
+			struct rte_table_action_vlo auth_iv_update;
+
+		} cipher_auth;
+
+		struct {
+			/** AEAD AAD data. */
+			struct rte_table_action_vlo aad;
+
+			/** AEAD iv data. */
+			struct rte_table_action_vlo iv;
+
+			/** AEAD AAD data. */
+			struct rte_table_action_vlo aad_update;
+
+			/** AEAD iv data. */
+			struct rte_table_action_vlo iv_update;
+
+		} aead;
+	};
+};
+
+/**
  * Table action profile.
  */
 struct rte_table_action_profile;
@@ -973,6 +1063,20 @@ rte_table_action_time_read(struct rte_table_action *action,
 	void *data,
 	uint64_t *timestamp);
 
+/**
+ * Table action cryptodev symmetric session get.
+ *
+ * @param[in] action
+ *   Handle to table action object (needs to be valid).
+ * @param[in] data
+ *   Data byte array (typically table rule data) with sym crypto action.
+ * @return
+ *   The pointer to the session on success, NULL otherwise.
+ */
+struct rte_cryptodev_sym_session *__rte_experimental
+rte_table_action_crypto_sym_session_get(struct rte_table_action *action,
+	void *data);
+
 #ifdef __cplusplus
 }
 #endif
-- 
2.13.6

^ permalink raw reply	[flat|nested] 10+ messages in thread

* [dpdk-dev] [PATCH v2 2/7] examples/ip_pipeline: add cryptodev
  2018-09-28 12:26 ` [dpdk-dev] [PATCH v2 0/7] pipeline: add symmetric crypto to action Fan Zhang
  2018-09-28 12:26   ` [dpdk-dev] [PATCH v2 1/7] " Fan Zhang
@ 2018-09-28 12:26   ` Fan Zhang
  2018-09-28 12:26   ` [dpdk-dev] [PATCH v2 3/7] examples/ip_pipeline: configure crypto port Fan Zhang
                     ` (5 subsequent siblings)
  7 siblings, 0 replies; 10+ messages in thread
From: Fan Zhang @ 2018-09-28 12:26 UTC (permalink / raw)
  To: dev; +Cc: cristian.dumitrescu, Zhang, Roy Fan, Zhang

From: "Zhang, Roy Fan" <roy.fan.zhang@intel.com>

This patch adds symmetric crypto device abstraction to ip_pipeline
sameple application.

Signed-off-by: Zhang, Roy Fan <roy.fan.zhang@intel.com>
Acked-by: Dumitrescu, Cristian <cristian.dumitrescu@intel.com>
---
 examples/ip_pipeline/Makefile    |   1 +
 examples/ip_pipeline/cryptodev.c | 117 +++++++++++++++++++++++++++++++++++++++
 examples/ip_pipeline/cryptodev.h |  43 ++++++++++++++
 examples/ip_pipeline/main.c      |   9 +++
 examples/ip_pipeline/meson.build |   3 +-
 5 files changed, 172 insertions(+), 1 deletion(-)
 create mode 100644 examples/ip_pipeline/cryptodev.c
 create mode 100644 examples/ip_pipeline/cryptodev.h

diff --git a/examples/ip_pipeline/Makefile b/examples/ip_pipeline/Makefile
index 3fb98ce3e..41ba7df2c 100644
--- a/examples/ip_pipeline/Makefile
+++ b/examples/ip_pipeline/Makefile
@@ -18,6 +18,7 @@ SRCS-y += swq.c
 SRCS-y += tap.c
 SRCS-y += thread.c
 SRCS-y += tmgr.c
+SRCS-y += cryptodev.c
 
 # Build using pkg-config variables if possible
 $(shell pkg-config --exists libdpdk)
diff --git a/examples/ip_pipeline/cryptodev.c b/examples/ip_pipeline/cryptodev.c
new file mode 100644
index 000000000..c4ba72bec
--- /dev/null
+++ b/examples/ip_pipeline/cryptodev.c
@@ -0,0 +1,117 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2018 Intel Corporation
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+
+#include <rte_cryptodev.h>
+#include <rte_cryptodev_pmd.h>
+#include <rte_string_fns.h>
+
+#include "cryptodev.h"
+
+static struct cryptodev_list cryptodev_list;
+
+int
+cryptodev_init(void)
+{
+	TAILQ_INIT(&cryptodev_list);
+
+	return 0;
+}
+
+struct cryptodev *
+cryptodev_find(const char *name)
+{
+	struct cryptodev *cryptodev;
+
+	if (name == NULL)
+		return NULL;
+
+	TAILQ_FOREACH(cryptodev, &cryptodev_list, node)
+		if (strcmp(cryptodev->name, name) == 0)
+			return cryptodev;
+
+	return NULL;
+}
+
+struct cryptodev *
+cryptodev_next(struct cryptodev *cryptodev)
+{
+	return (cryptodev == NULL) ?
+			TAILQ_FIRST(&cryptodev_list) :
+			TAILQ_NEXT(cryptodev, node);
+}
+
+struct cryptodev *
+cryptodev_create(const char *name, struct cryptodev_params *params)
+{
+	struct rte_cryptodev_info dev_info;
+	struct rte_cryptodev_config dev_conf;
+	struct rte_cryptodev_qp_conf queue_conf;
+	struct cryptodev *cryptodev;
+	uint32_t dev_id, i;
+	uint32_t socket_id;
+	int status;
+
+	/* Check input params */
+	if ((name == NULL) ||
+		cryptodev_find(name) ||
+		(params->n_queues == 0) ||
+		(params->queue_size == 0))
+		return NULL;
+
+	if (params->dev_name) {
+		status = rte_cryptodev_get_dev_id(params->dev_name);
+		if (status == -1)
+			return NULL;
+
+		dev_id = (uint32_t)status;
+	} else {
+		if (rte_cryptodev_pmd_is_valid_dev(params->dev_id) == 0)
+			return NULL;
+
+		dev_id = params->dev_id;
+	}
+
+	socket_id = rte_cryptodev_socket_id(dev_id);
+	rte_cryptodev_info_get(dev_id, &dev_info);
+
+	if (dev_info.max_nb_queue_pairs < params->n_queues)
+		return NULL;
+	if (dev_info.feature_flags & RTE_CRYPTODEV_FF_HW_ACCELERATED)
+		return NULL;
+
+	dev_conf.socket_id = socket_id;
+	dev_conf.nb_queue_pairs = params->n_queues;
+
+	status = rte_cryptodev_configure(dev_id, &dev_conf);
+	if (status < 0)
+		return NULL;
+
+	queue_conf.nb_descriptors = params->queue_size;
+	for (i = 0; i < params->n_queues; i++) {
+		status = rte_cryptodev_queue_pair_setup(dev_id, i,
+				&queue_conf, socket_id, NULL);
+		if (status < 0)
+			return NULL;
+	}
+
+	if (rte_cryptodev_start(dev_id) < 0)
+		return NULL;
+
+	cryptodev = calloc(1, sizeof(struct cryptodev));
+	if (cryptodev == NULL) {
+		rte_cryptodev_stop(dev_id);
+		return NULL;
+	}
+
+	strlcpy(cryptodev->name, name, sizeof(cryptodev->name));
+	cryptodev->dev_id = dev_id;
+	cryptodev->n_queues = params->n_queues;
+
+	TAILQ_INSERT_TAIL(&cryptodev_list, cryptodev, node);
+
+	return cryptodev;
+}
diff --git a/examples/ip_pipeline/cryptodev.h b/examples/ip_pipeline/cryptodev.h
new file mode 100644
index 000000000..d06b3f2f1
--- /dev/null
+++ b/examples/ip_pipeline/cryptodev.h
@@ -0,0 +1,43 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2018 Intel Corporation
+ */
+
+#ifndef _INCLUDE_SYM_C_H_
+#define _INCLUDE_SYM_C_H_
+
+#include <stdint.h>
+#include <sys/queue.h>
+
+#include <rte_cryptodev.h>
+
+#include "common.h"
+
+struct cryptodev {
+	TAILQ_ENTRY(cryptodev) node;
+	char name[NAME_SIZE];
+	uint16_t dev_id;
+	uint32_t n_queues;
+};
+
+TAILQ_HEAD(cryptodev_list, cryptodev);
+
+int
+cryptodev_init(void);
+
+struct cryptodev *
+cryptodev_find(const char *name);
+
+struct cryptodev *
+cryptodev_next(struct cryptodev *cryptodev);
+
+struct cryptodev_params {
+	const char *dev_name;
+	uint32_t dev_id; /**< Valid only when *dev_name* is NULL. */
+	uint32_t n_queues;
+	uint32_t queue_size;
+};
+
+struct cryptodev *
+cryptodev_create(const char *name, struct cryptodev_params *params);
+
+#endif
diff --git a/examples/ip_pipeline/main.c b/examples/ip_pipeline/main.c
index a69faceef..97d1e91c2 100644
--- a/examples/ip_pipeline/main.c
+++ b/examples/ip_pipeline/main.c
@@ -14,6 +14,7 @@
 #include "cli.h"
 #include "conn.h"
 #include "kni.h"
+#include "cryptodev.h"
 #include "link.h"
 #include "mempool.h"
 #include "pipeline.h"
@@ -210,6 +211,14 @@ main(int argc, char **argv)
 		return status;
 	}
 
+	/* Sym Crypto */
+	status = cryptodev_init();
+	if (status) {
+		printf("Error: Cryptodev initialization failed (%d)\n",
+				status);
+		return status;
+	}
+
 	/* Action */
 	status = port_in_action_profile_init();
 	if (status) {
diff --git a/examples/ip_pipeline/meson.build b/examples/ip_pipeline/meson.build
index a9f2ea447..5e5fe6479 100644
--- a/examples/ip_pipeline/meson.build
+++ b/examples/ip_pipeline/meson.build
@@ -21,5 +21,6 @@ sources = files(
 	'swq.c',
 	'tap.c',
 	'thread.c',
-	'tmgr.c'
+	'tmgr.c',
+	'cryptodev.c'
 )
-- 
2.13.6

^ permalink raw reply	[flat|nested] 10+ messages in thread

* [dpdk-dev] [PATCH v2 3/7] examples/ip_pipeline: configure crypto port
  2018-09-28 12:26 ` [dpdk-dev] [PATCH v2 0/7] pipeline: add symmetric crypto to action Fan Zhang
  2018-09-28 12:26   ` [dpdk-dev] [PATCH v2 1/7] " Fan Zhang
  2018-09-28 12:26   ` [dpdk-dev] [PATCH v2 2/7] examples/ip_pipeline: add cryptodev Fan Zhang
@ 2018-09-28 12:26   ` Fan Zhang
  2018-09-28 12:26   ` [dpdk-dev] [PATCH v2 4/7] examples/ip_pipeline: add symmetric crypto action Fan Zhang
                     ` (4 subsequent siblings)
  7 siblings, 0 replies; 10+ messages in thread
From: Fan Zhang @ 2018-09-28 12:26 UTC (permalink / raw)
  To: dev; +Cc: cristian.dumitrescu, Zhang, Roy Fan, Zhang

From: "Zhang, Roy Fan" <roy.fan.zhang@intel.com>

This patch adds symmetric crypto port configuration to ip_pipeline
sample application.

Signed-off-by: Zhang, Roy Fan <roy.fan.zhang@intel.com>
Acked-by: Dumitrescu, Cristian <cristian.dumitrescu@intel.com>
---
 examples/ip_pipeline/pipeline.c | 60 +++++++++++++++++++++++++++++++++++++++++
 examples/ip_pipeline/pipeline.h | 13 +++++++++
 2 files changed, 73 insertions(+)

diff --git a/examples/ip_pipeline/pipeline.c b/examples/ip_pipeline/pipeline.c
index b2fd215b1..b23d6c09a 100644
--- a/examples/ip_pipeline/pipeline.c
+++ b/examples/ip_pipeline/pipeline.c
@@ -18,6 +18,7 @@
 #include <rte_port_source_sink.h>
 #include <rte_port_fd.h>
 #include <rte_port_sched.h>
+#include <rte_port_sym_crypto.h>
 
 #include <rte_table_acl.h>
 #include <rte_table_array.h>
@@ -36,6 +37,7 @@
 #include "tap.h"
 #include "tmgr.h"
 #include "swq.h"
+#include "cryptodev.h"
 
 #ifndef PIPELINE_MSGQ_SIZE
 #define PIPELINE_MSGQ_SIZE                                 64
@@ -162,6 +164,7 @@ pipeline_port_in_create(const char *pipeline_name,
 		struct rte_port_kni_reader_params kni;
 #endif
 		struct rte_port_source_params source;
+		struct rte_port_sym_crypto_reader_params sym_crypto;
 	} pp;
 
 	struct pipeline *pipeline;
@@ -295,6 +298,27 @@ pipeline_port_in_create(const char *pipeline_name,
 		break;
 	}
 
+	case PORT_IN_CRYPTODEV:
+	{
+		struct cryptodev *cryptodev;
+
+		cryptodev = cryptodev_find(params->dev_name);
+		if (cryptodev == NULL)
+			return -1;
+
+		if (params->rxq.queue_id > cryptodev->n_queues - 1)
+			return -1;
+
+		pp.sym_crypto.cryptodev_id = cryptodev->dev_id;
+		pp.sym_crypto.queue_id = params->cryptodev.queue_id;
+		pp.sym_crypto.f_callback = params->cryptodev.f_callback;
+		pp.sym_crypto.arg_callback = params->cryptodev.arg_callback;
+		p.ops = &rte_port_sym_crypto_reader_ops;
+		p.arg_create = &pp.sym_crypto;
+
+		break;
+	}
+
 	default:
 		return -1;
 	}
@@ -384,6 +408,7 @@ pipeline_port_out_create(const char *pipeline_name,
 		struct rte_port_kni_writer_params kni;
 #endif
 		struct rte_port_sink_params sink;
+		struct rte_port_sym_crypto_writer_params sym_crypto;
 	} pp;
 
 	union {
@@ -393,6 +418,7 @@ pipeline_port_out_create(const char *pipeline_name,
 #ifdef RTE_LIBRTE_KNI
 		struct rte_port_kni_writer_nodrop_params kni;
 #endif
+		struct rte_port_sym_crypto_writer_nodrop_params sym_crypto;
 	} pp_nodrop;
 
 	struct pipeline *pipeline;
@@ -548,6 +574,40 @@ pipeline_port_out_create(const char *pipeline_name,
 		break;
 	}
 
+	case PORT_OUT_CRYPTODEV:
+	{
+		struct cryptodev *cryptodev;
+
+		cryptodev = cryptodev_find(params->dev_name);
+		if (cryptodev == NULL)
+			return -1;
+
+		if (params->cryptodev.queue_id >= cryptodev->n_queues)
+			return -1;
+
+		pp.sym_crypto.cryptodev_id = cryptodev->dev_id;
+		pp.sym_crypto.queue_id = params->cryptodev.queue_id;
+		pp.sym_crypto.tx_burst_sz = params->burst_size;
+		pp.sym_crypto.crypto_op_offset = params->cryptodev.op_offset;
+
+		pp_nodrop.sym_crypto.cryptodev_id = cryptodev->dev_id;
+		pp_nodrop.sym_crypto.queue_id = params->cryptodev.queue_id;
+		pp_nodrop.sym_crypto.tx_burst_sz = params->burst_size;
+		pp_nodrop.sym_crypto.n_retries = params->retry;
+		pp_nodrop.sym_crypto.crypto_op_offset =
+				params->cryptodev.op_offset;
+
+		if (params->retry == 0) {
+			p.ops = &rte_port_sym_crypto_writer_ops;
+			p.arg_create = &pp.sym_crypto;
+		} else {
+			p.ops = &rte_port_sym_crypto_writer_nodrop_ops;
+			p.arg_create = &pp_nodrop.sym_crypto;
+		}
+
+		break;
+	}
+
 	default:
 		return -1;
 	}
diff --git a/examples/ip_pipeline/pipeline.h b/examples/ip_pipeline/pipeline.h
index a953a29fa..fb283e558 100644
--- a/examples/ip_pipeline/pipeline.h
+++ b/examples/ip_pipeline/pipeline.h
@@ -27,6 +27,7 @@ enum port_in_type {
 	PORT_IN_TAP,
 	PORT_IN_KNI,
 	PORT_IN_SOURCE,
+	PORT_IN_CRYPTODEV,
 };
 
 struct port_in_params {
@@ -48,6 +49,12 @@ struct port_in_params {
 			const char *file_name;
 			uint32_t n_bytes_per_pkt;
 		} source;
+
+		struct {
+			uint16_t queue_id;
+			void *f_callback;
+			void *arg_callback;
+		} cryptodev;
 	};
 	uint32_t burst_size;
 
@@ -62,6 +69,7 @@ enum port_out_type {
 	PORT_OUT_TAP,
 	PORT_OUT_KNI,
 	PORT_OUT_SINK,
+	PORT_OUT_CRYPTODEV,
 };
 
 struct port_out_params {
@@ -76,6 +84,11 @@ struct port_out_params {
 			const char *file_name;
 			uint32_t max_n_pkts;
 		} sink;
+
+		struct {
+			uint16_t queue_id;
+			uint32_t op_offset;
+		} cryptodev;
 	};
 	uint32_t burst_size;
 	int retry;
-- 
2.13.6

^ permalink raw reply	[flat|nested] 10+ messages in thread

* [dpdk-dev] [PATCH v2 4/7] examples/ip_pipeline: add symmetric crypto action
  2018-09-28 12:26 ` [dpdk-dev] [PATCH v2 0/7] pipeline: add symmetric crypto to action Fan Zhang
                     ` (2 preceding siblings ...)
  2018-09-28 12:26   ` [dpdk-dev] [PATCH v2 3/7] examples/ip_pipeline: configure crypto port Fan Zhang
@ 2018-09-28 12:26   ` Fan Zhang
  2018-09-28 12:26   ` [dpdk-dev] [PATCH v2 5/7] examples/ip_pipeline: update cli parsing Fan Zhang
                     ` (3 subsequent siblings)
  7 siblings, 0 replies; 10+ messages in thread
From: Fan Zhang @ 2018-09-28 12:26 UTC (permalink / raw)
  To: dev; +Cc: cristian.dumitrescu, Zhang, Roy Fan, Zhang

From: "Zhang, Roy Fan" <roy.fan.zhang@intel.com>

This patch adds symmetric crypto action support to ip_pipeline
application.

Signed-off-by: Zhang, Roy Fan <roy.fan.zhang@intel.com>
Acked-by: Dumitrescu, Cristian <cristian.dumitrescu@intel.com>
---
 examples/ip_pipeline/action.c   | 11 +++++++++++
 examples/ip_pipeline/action.h   |  1 +
 examples/ip_pipeline/pipeline.h |  1 +
 examples/ip_pipeline/thread.c   | 10 ++++++++++
 4 files changed, 23 insertions(+)

diff --git a/examples/ip_pipeline/action.c b/examples/ip_pipeline/action.c
index 20497c3c7..a0f97bee7 100644
--- a/examples/ip_pipeline/action.c
+++ b/examples/ip_pipeline/action.c
@@ -333,6 +333,17 @@ table_action_profile_create(const char *name,
 		}
 	}
 
+	if (params->action_mask & (1LLU << RTE_TABLE_ACTION_SYM_CRYPTO)) {
+		status = rte_table_action_profile_action_register(ap,
+			RTE_TABLE_ACTION_SYM_CRYPTO,
+			&params->sym_crypto);
+
+		if (status) {
+			rte_table_action_profile_free(ap);
+			return NULL;
+		}
+	}
+
 	status = rte_table_action_profile_freeze(ap);
 	if (status) {
 		rte_table_action_profile_free(ap);
diff --git a/examples/ip_pipeline/action.h b/examples/ip_pipeline/action.h
index 417200e86..cde17e69a 100644
--- a/examples/ip_pipeline/action.h
+++ b/examples/ip_pipeline/action.h
@@ -53,6 +53,7 @@ struct table_action_profile_params {
 	struct rte_table_action_nat_config nat;
 	struct rte_table_action_ttl_config ttl;
 	struct rte_table_action_stats_config stats;
+	struct rte_table_action_sym_crypto_config sym_crypto;
 };
 
 struct table_action_profile {
diff --git a/examples/ip_pipeline/pipeline.h b/examples/ip_pipeline/pipeline.h
index fb283e558..b6b9dc06f 100644
--- a/examples/ip_pipeline/pipeline.h
+++ b/examples/ip_pipeline/pipeline.h
@@ -281,6 +281,7 @@ struct table_rule_action {
 	struct rte_table_action_ttl_params ttl;
 	struct rte_table_action_stats_params stats;
 	struct rte_table_action_time_params time;
+	struct rte_table_action_sym_crypto_params sym_crypto;
 };
 
 int
diff --git a/examples/ip_pipeline/thread.c b/examples/ip_pipeline/thread.c
index 7fc03332e..ca741952a 100644
--- a/examples/ip_pipeline/thread.c
+++ b/examples/ip_pipeline/thread.c
@@ -2476,6 +2476,16 @@ action_convert(struct rte_table_action *a,
 			return status;
 	}
 
+	if (action->action_mask & (1LLU << RTE_TABLE_ACTION_SYM_CRYPTO)) {
+		status = rte_table_action_apply(a,
+			data,
+			RTE_TABLE_ACTION_SYM_CRYPTO,
+			&action->sym_crypto);
+
+		if (status)
+			return status;
+	}
+
 	return 0;
 }
 
-- 
2.13.6

^ permalink raw reply	[flat|nested] 10+ messages in thread

* [dpdk-dev] [PATCH v2 5/7] examples/ip_pipeline: update cli parsing
  2018-09-28 12:26 ` [dpdk-dev] [PATCH v2 0/7] pipeline: add symmetric crypto to action Fan Zhang
                     ` (3 preceding siblings ...)
  2018-09-28 12:26   ` [dpdk-dev] [PATCH v2 4/7] examples/ip_pipeline: add symmetric crypto action Fan Zhang
@ 2018-09-28 12:26   ` Fan Zhang
  2018-09-28 12:26   ` [dpdk-dev] [PATCH v2 6/7] examples/ip_pipeline: add script Fan Zhang
                     ` (2 subsequent siblings)
  7 siblings, 0 replies; 10+ messages in thread
From: Fan Zhang @ 2018-09-28 12:26 UTC (permalink / raw)
  To: dev; +Cc: cristian.dumitrescu, Zhang, Roy Fan, Zhang

From: "Zhang, Roy Fan" <roy.fan.zhang@intel.com>

This patch updates the cli parsing of ip_pipeline application
with extra symmetric crypto, port, session, and action support.

Signed-off-by: Zhang, Roy Fan <roy.fan.zhang@intel.com>
Acked-by: Dumitrescu, Cristian <cristian.dumitrescu@intel.com>
---
 examples/ip_pipeline/cli.c | 577 ++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 575 insertions(+), 2 deletions(-)

diff --git a/examples/ip_pipeline/cli.c b/examples/ip_pipeline/cli.c
index 01c37691f..3ff7caaca 100644
--- a/examples/ip_pipeline/cli.c
+++ b/examples/ip_pipeline/cli.c
@@ -12,6 +12,8 @@
 #include <rte_ethdev.h>
 
 #include "cli.h"
+
+#include "cryptodev.h"
 #include "kni.h"
 #include "link.h"
 #include "mempool.h"
@@ -785,6 +787,65 @@ cmd_kni(char **tokens,
 	}
 }
 
+static const char cmd_cryptodev_help[] =
+"cryptodev <cryptodev_name>\n"
+"   dev <device_name> | dev_id <device_id>\n"
+"   queue <n_queues> <queue_size>\n";
+
+static void
+cmd_cryptodev(char **tokens,
+	uint32_t n_tokens,
+	char *out,
+	size_t out_size)
+{
+	struct cryptodev_params params;
+	char *name;
+
+	memset(&params, 0, sizeof(params));
+	if (n_tokens != 7) {
+		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
+		return;
+	}
+
+	name = tokens[1];
+
+	if (strcmp(tokens[2], "dev") == 0)
+		params.dev_name = tokens[3];
+	else if (strcmp(tokens[2], "dev_id") == 0) {
+		if (parser_read_uint32(&params.dev_id, tokens[3]) < 0) {
+			snprintf(out, out_size,	MSG_ARG_INVALID,
+				"dev_id");
+			return;
+		}
+	} else {
+		snprintf(out, out_size,	MSG_ARG_INVALID,
+			"cryptodev");
+		return;
+	}
+
+	if (strcmp(tokens[4], "queue")) {
+		snprintf(out, out_size,	MSG_ARG_NOT_FOUND,
+			"4");
+		return;
+	}
+
+	if (parser_read_uint32(&params.n_queues, tokens[5]) < 0) {
+		snprintf(out, out_size,	MSG_ARG_INVALID,
+			"q");
+		return;
+	}
+
+	if (parser_read_uint32(&params.queue_size, tokens[6]) < 0) {
+		snprintf(out, out_size,	MSG_ARG_INVALID,
+			"queue_size");
+		return;
+	}
+
+	if (cryptodev_create(name, &params) == NULL) {
+		snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
+		return;
+	}
+}
 
 static const char cmd_port_in_action_profile_help[] =
 "port in action profile <profile_name>\n"
@@ -968,7 +1029,10 @@ static const char cmd_table_action_profile_help[] =
 "   [ttl drop | fwd\n"
 "       stats none | pkts]\n"
 "   [stats pkts | bytes | both]\n"
-"   [time]\n";
+"   [time]\n"
+"   [sym_crypto dev <CRYPTODEV_NAME> offset <op_offset> "
+"       mempool_create <mempool_name>\n"
+"       mempool_init <mempool_name>]\n";
 
 static void
 cmd_table_action_profile(char **tokens,
@@ -1336,6 +1400,57 @@ cmd_table_action_profile(char **tokens,
 		t0 += 1;
 	} /* time */
 
+	if ((t0 < n_tokens) && (strcmp(tokens[t0], "sym_crypto") == 0)) {
+		struct cryptodev *cryptodev;
+		struct mempool *mempool;
+
+		if (n_tokens < t0 + 9 ||
+				strcmp(tokens[t0 + 1], "dev") ||
+				strcmp(tokens[t0 + 3], "offset") ||
+				strcmp(tokens[t0 + 5], "mempool_create") ||
+				strcmp(tokens[t0 + 7], "mempool_init")) {
+			snprintf(out, out_size, MSG_ARG_MISMATCH,
+				"table action profile sym_crypto");
+			return;
+		}
+
+		cryptodev = cryptodev_find(tokens[t0 + 2]);
+		if (cryptodev == NULL) {
+			snprintf(out, out_size, MSG_ARG_INVALID,
+				"table action profile sym_crypto");
+			return;
+		}
+
+		p.sym_crypto.cryptodev_id = cryptodev->dev_id;
+
+		if (parser_read_uint32(&p.sym_crypto.op_offset,
+				tokens[t0 + 4]) != 0) {
+			snprintf(out, out_size, MSG_ARG_INVALID,
+					"table action profile sym_crypto");
+			return;
+		}
+
+		mempool = mempool_find(tokens[t0 + 6]);
+		if (mempool == NULL) {
+			snprintf(out, out_size, MSG_ARG_INVALID,
+				"table action profile sym_crypto");
+			return;
+		}
+		p.sym_crypto.mp_create = mempool->m;
+
+		mempool = mempool_find(tokens[t0 + 8]);
+		if (mempool == NULL) {
+			snprintf(out, out_size, MSG_ARG_INVALID,
+				"table action profile sym_crypto");
+			return;
+		}
+		p.sym_crypto.mp_init = mempool->m;
+
+		p.action_mask |= 1LLU << RTE_TABLE_ACTION_SYM_CRYPTO;
+
+		t0 += 9;
+	} /* sym_crypto */
+
 	if (t0 < n_tokens) {
 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
 		return;
@@ -1417,6 +1532,7 @@ static const char cmd_pipeline_port_in_help[] =
 "   | tap <tap_name> mempool <mempool_name> mtu <mtu>\n"
 "   | kni <kni_name>\n"
 "   | source mempool <mempool_name> file <file_name> bpp <n_bytes_per_pkt>\n"
+"   | cryptodev <cryptodev_name> rxq <queue_id>\n"
 "   [action <port_in_action_profile_name>]\n"
 "   [disabled]\n";
 
@@ -1589,6 +1705,26 @@ cmd_pipeline_port_in(char **tokens,
 		}
 
 		t0 += 7;
+	} else if (strcmp(tokens[t0], "cryptodev") == 0) {
+		if (n_tokens < t0 + 3) {
+			snprintf(out, out_size, MSG_ARG_MISMATCH,
+				"pipeline port in cryptodev");
+			return;
+		}
+
+		p.type = PORT_IN_CRYPTODEV;
+
+		p.dev_name = tokens[t0 + 1];
+		if (parser_read_uint16(&p.rxq.queue_id, tokens[t0 + 3]) != 0) {
+			snprintf(out, out_size, MSG_ARG_INVALID,
+				"rxq");
+			return;
+		}
+
+		p.cryptodev.arg_callback = NULL;
+		p.cryptodev.f_callback = NULL;
+
+		t0 += 4;
 	} else {
 		snprintf(out, out_size, MSG_ARG_INVALID, tokens[0]);
 		return;
@@ -1635,7 +1771,8 @@ static const char cmd_pipeline_port_out_help[] =
 "   | tmgr <tmgr_name>\n"
 "   | tap <tap_name>\n"
 "   | kni <kni_name>\n"
-"   | sink [file <file_name> pkts <max_n_pkts>]\n";
+"   | sink [file <file_name> pkts <max_n_pkts>]\n"
+"   | cryptodev <cryptodev_name> txq <txq_id> offset <crypto_op_offset>\n";
 
 static void
 cmd_pipeline_port_out(char **tokens,
@@ -1769,6 +1906,41 @@ cmd_pipeline_port_out(char **tokens,
 				return;
 			}
 		}
+
+	} else if (strcmp(tokens[6], "cryptodev") == 0) {
+		if (n_tokens != 12) {
+			snprintf(out, out_size, MSG_ARG_MISMATCH,
+				"pipeline port out cryptodev");
+			return;
+		}
+
+		p.type = PORT_OUT_CRYPTODEV;
+
+		p.dev_name = tokens[7];
+
+		if (strcmp(tokens[8], "txq")) {
+			snprintf(out, out_size, MSG_ARG_MISMATCH,
+				"pipeline port out cryptodev");
+			return;
+		}
+
+		if (parser_read_uint16(&p.cryptodev.queue_id, tokens[9])
+				!= 0) {
+			snprintf(out, out_size, MSG_ARG_INVALID, "queue_id");
+			return;
+		}
+
+		if (strcmp(tokens[10], "offset")) {
+			snprintf(out, out_size, MSG_ARG_MISMATCH,
+				"pipeline port out cryptodev");
+			return;
+		}
+
+		if (parser_read_uint32(&p.cryptodev.op_offset, tokens[11])
+				!= 0) {
+			snprintf(out, out_size, MSG_ARG_INVALID, "queue_id");
+			return;
+		}
 	} else {
 		snprintf(out, out_size, MSG_ARG_INVALID, tokens[0]);
 		return;
@@ -2923,6 +3095,18 @@ parse_match(char **tokens,
  *    [ttl dec | keep]
  *    [stats]
  *    [time]
+ *    [sym_crypto
+ *       encrypt | decrypt
+ *       type
+ *       | cipher
+ *          cipher_algo <algo> cipher_key <key> cipher_iv <iv>
+ *       | cipher_auth
+ *          cipher_algo <algo> cipher_key <key> cipher_iv <iv>
+ *          auth_algo <algo> auth_key <key> digest_size <size>
+ *       | aead
+ *          aead_algo <algo> aead_key <key> aead_iv <iv> aead_aad <aad>
+ *          digest_size <size>
+ *       data_offset <data_offset>]
  *
  * where:
  *    <pa> ::= g | y | r | drop
@@ -3521,6 +3705,368 @@ parse_table_action_time(char **tokens,
 	return 1;
 }
 
+static void
+parse_free_sym_crypto_param_data(struct rte_table_action_sym_crypto_params *p)
+{
+	struct rte_crypto_sym_xform *xform[2] = {NULL};
+	uint32_t i;
+
+	xform[0] = p->xform;
+	if (xform[0])
+		xform[1] = xform[0]->next;
+
+	for (i = 0; i < 2; i++) {
+		if (xform[i] == NULL)
+			continue;
+
+		switch (xform[i]->type) {
+		case RTE_CRYPTO_SYM_XFORM_CIPHER:
+			if (xform[i]->cipher.key.data)
+				free(xform[i]->cipher.key.data);
+			if (p->cipher_auth.cipher_iv.val)
+				free(p->cipher_auth.cipher_iv.val);
+			if (p->cipher_auth.cipher_iv_update.val)
+				free(p->cipher_auth.cipher_iv_update.val);
+			break;
+		case RTE_CRYPTO_SYM_XFORM_AUTH:
+			if (xform[i]->auth.key.data)
+				free(xform[i]->cipher.key.data);
+			if (p->cipher_auth.auth_iv.val)
+				free(p->cipher_auth.cipher_iv.val);
+			if (p->cipher_auth.auth_iv_update.val)
+				free(p->cipher_auth.cipher_iv_update.val);
+			break;
+		case RTE_CRYPTO_SYM_XFORM_AEAD:
+			if (xform[i]->aead.key.data)
+				free(xform[i]->cipher.key.data);
+			if (p->aead.iv.val)
+				free(p->aead.iv.val);
+			if (p->aead.aad.val)
+				free(p->aead.aad.val);
+			break;
+		default:
+			continue;
+		}
+	}
+
+}
+
+static struct rte_crypto_sym_xform *
+parse_table_action_cipher(struct rte_table_action_sym_crypto_params *p,
+		char **tokens, uint32_t n_tokens, uint32_t encrypt,
+		uint32_t *used_n_tokens)
+{
+	struct rte_crypto_sym_xform *xform_cipher;
+	int status;
+	size_t len;
+
+	if (n_tokens < 7 || strcmp(tokens[1], "cipher_algo") ||
+			strcmp(tokens[3], "cipher_key") ||
+			strcmp(tokens[5], "cipher_iv"))
+		return NULL;
+
+	xform_cipher = calloc(1, sizeof(*xform_cipher));
+	if (xform_cipher == NULL)
+		return NULL;
+
+	xform_cipher->type = RTE_CRYPTO_SYM_XFORM_CIPHER;
+	xform_cipher->cipher.op = encrypt ? RTE_CRYPTO_CIPHER_OP_ENCRYPT :
+			RTE_CRYPTO_CIPHER_OP_DECRYPT;
+
+	/* cipher_algo */
+	status = rte_cryptodev_get_cipher_algo_enum(
+			&xform_cipher->cipher.algo, tokens[2]);
+	if (status < 0)
+		goto error_exit;
+
+	/* cipher_key */
+	len = strlen(tokens[4]);
+	xform_cipher->cipher.key.data = calloc(1, len / 2 + 1);
+	if (xform_cipher->cipher.key.data == NULL)
+		goto error_exit;
+
+	status = parse_hex_string(tokens[4],
+			xform_cipher->cipher.key.data,
+			(uint32_t *)&len);
+	if (status < 0)
+		goto error_exit;
+
+	xform_cipher->cipher.key.length = (uint16_t)len;
+
+	/* cipher_iv */
+	len = strlen(tokens[6]);
+
+	p->cipher_auth.cipher_iv.val = calloc(1, len / 2 + 1);
+	if (p->cipher_auth.cipher_iv.val == NULL)
+		goto error_exit;
+
+	status = parse_hex_string(tokens[6],
+			p->cipher_auth.cipher_iv.val,
+			(uint32_t *)&len);
+	if (status < 0)
+		goto error_exit;
+
+	xform_cipher->cipher.iv.length = (uint16_t)len;
+	xform_cipher->cipher.iv.offset = RTE_TABLE_ACTION_SYM_CRYPTO_IV_OFFSET;
+	p->cipher_auth.cipher_iv.length = (uint32_t)len;
+	*used_n_tokens = 7;
+
+	return xform_cipher;
+
+error_exit:
+	if (xform_cipher->cipher.key.data)
+		free(xform_cipher->cipher.key.data);
+
+	if (p->cipher_auth.cipher_iv.val) {
+		free(p->cipher_auth.cipher_iv.val);
+		p->cipher_auth.cipher_iv.val = NULL;
+	}
+
+	free(xform_cipher);
+
+	return NULL;
+}
+
+static struct rte_crypto_sym_xform *
+parse_table_action_cipher_auth(struct rte_table_action_sym_crypto_params *p,
+		char **tokens, uint32_t n_tokens, uint32_t encrypt,
+		uint32_t *used_n_tokens)
+{
+	struct rte_crypto_sym_xform *xform_cipher;
+	struct rte_crypto_sym_xform *xform_auth;
+	int status;
+	size_t len;
+
+	if (n_tokens < 13 ||
+			strcmp(tokens[7], "auth_algo") ||
+			strcmp(tokens[9], "auth_key") ||
+			strcmp(tokens[11], "digest_size"))
+		return NULL;
+
+	xform_auth = calloc(1, sizeof(*xform_auth));
+	if (xform_auth == NULL)
+		return NULL;
+
+	xform_auth->type = RTE_CRYPTO_SYM_XFORM_AUTH;
+	xform_auth->auth.op = encrypt ? RTE_CRYPTO_AUTH_OP_GENERATE :
+			RTE_CRYPTO_AUTH_OP_VERIFY;
+
+	/* auth_algo */
+	status = rte_cryptodev_get_auth_algo_enum(&xform_auth->auth.algo,
+			tokens[8]);
+	if (status < 0)
+		goto error_exit;
+
+	/* auth_key */
+	len = strlen(tokens[10]);
+	xform_auth->auth.key.data = calloc(1, len / 2 + 1);
+	if (xform_auth->auth.key.data == NULL)
+		goto error_exit;
+
+	status = parse_hex_string(tokens[10],
+			xform_auth->auth.key.data, (uint32_t *)&len);
+	if (status < 0)
+		goto error_exit;
+
+	xform_auth->auth.key.length = (uint16_t)len;
+
+	if (strcmp(tokens[11], "digest_size"))
+		goto error_exit;
+
+	status = parser_read_uint16(&xform_auth->auth.digest_length,
+			tokens[12]);
+	if (status < 0)
+		goto error_exit;
+
+	xform_cipher = parse_table_action_cipher(p, tokens, 7, encrypt,
+			used_n_tokens);
+	if (xform_cipher == NULL)
+		goto error_exit;
+
+	*used_n_tokens += 6;
+
+	if (encrypt) {
+		xform_cipher->next = xform_auth;
+		return xform_cipher;
+	} else {
+		xform_auth->next = xform_cipher;
+		return xform_auth;
+	}
+
+error_exit:
+	if (xform_auth->auth.key.data)
+		free(xform_auth->auth.key.data);
+	if (p->cipher_auth.auth_iv.val) {
+		free(p->cipher_auth.auth_iv.val);
+		p->cipher_auth.auth_iv.val = 0;
+	}
+
+	free(xform_auth);
+
+	return NULL;
+}
+
+static struct rte_crypto_sym_xform *
+parse_table_action_aead(struct rte_table_action_sym_crypto_params *p,
+		char **tokens, uint32_t n_tokens, uint32_t encrypt,
+		uint32_t *used_n_tokens)
+{
+	struct rte_crypto_sym_xform *xform_aead;
+	int status;
+	size_t len;
+
+	if (n_tokens < 11 || strcmp(tokens[1], "aead_algo") ||
+			strcmp(tokens[3], "aead_key") ||
+			strcmp(tokens[5], "aead_iv") ||
+			strcmp(tokens[7], "aead_aad") ||
+			strcmp(tokens[9], "digest_size"))
+		return NULL;
+
+	xform_aead = calloc(1, sizeof(*xform_aead));
+	if (xform_aead == NULL)
+		return NULL;
+
+	xform_aead->type = RTE_CRYPTO_SYM_XFORM_AEAD;
+	xform_aead->aead.op = encrypt ? RTE_CRYPTO_AEAD_OP_ENCRYPT :
+			RTE_CRYPTO_AEAD_OP_DECRYPT;
+
+	/* aead_algo */
+	status = rte_cryptodev_get_aead_algo_enum(&xform_aead->aead.algo,
+			tokens[2]);
+	if (status < 0)
+		goto error_exit;
+
+	/* aead_key */
+	len = strlen(tokens[4]);
+	xform_aead->aead.key.data = calloc(1, len / 2 + 1);
+	if (xform_aead->aead.key.data == NULL)
+		goto error_exit;
+
+	status = parse_hex_string(tokens[4], xform_aead->aead.key.data,
+			(uint32_t *)&len);
+	if (status < 0)
+		goto error_exit;
+
+	xform_aead->aead.key.length = (uint16_t)len;
+
+	/* aead_iv */
+	len = strlen(tokens[6]);
+	p->aead.iv.val = calloc(1, len / 2 + 1);
+	if (p->aead.iv.val == NULL)
+		goto error_exit;
+
+	status = parse_hex_string(tokens[6], p->aead.iv.val,
+			(uint32_t *)&len);
+	if (status < 0)
+		goto error_exit;
+
+	xform_aead->aead.iv.length = (uint16_t)len;
+	xform_aead->aead.iv.offset = RTE_TABLE_ACTION_SYM_CRYPTO_IV_OFFSET;
+	p->aead.iv.length = (uint32_t)len;
+
+	/* aead_aad */
+	len = strlen(tokens[8]);
+	p->aead.aad.val = calloc(1, len / 2 + 1);
+	if (p->aead.aad.val == NULL)
+		goto error_exit;
+
+	status = parse_hex_string(tokens[8], p->aead.aad.val, (uint32_t *)&len);
+	if (status < 0)
+		goto error_exit;
+
+	xform_aead->aead.aad_length = (uint16_t)len;
+	p->aead.aad.length = (uint32_t)len;
+
+	/* digest_size */
+	status = parser_read_uint16(&xform_aead->aead.digest_length,
+			tokens[10]);
+	if (status < 0)
+		goto error_exit;
+
+	*used_n_tokens = 11;
+
+	return xform_aead;
+
+error_exit:
+	if (xform_aead->aead.key.data)
+		free(xform_aead->aead.key.data);
+	if (p->aead.iv.val) {
+		free(p->aead.iv.val);
+		p->aead.iv.val = NULL;
+	}
+	if (p->aead.aad.val) {
+		free(p->aead.aad.val);
+		p->aead.aad.val = NULL;
+	}
+
+	free(xform_aead);
+
+	return NULL;
+}
+
+
+static uint32_t
+parse_table_action_sym_crypto(char **tokens,
+	uint32_t n_tokens,
+	struct table_rule_action *a)
+{
+	struct rte_table_action_sym_crypto_params *p = &a->sym_crypto;
+	struct rte_crypto_sym_xform *xform = NULL;
+	uint32_t used_n_tokens;
+	uint32_t encrypt;
+	int status;
+
+	if ((n_tokens < 12) ||
+		strcmp(tokens[0], "sym_crypto") ||
+		strcmp(tokens[2], "type"))
+		return 0;
+
+	memset(p, 0, sizeof(*p));
+
+	if (strcmp(tokens[1], "encrypt") == 0)
+		encrypt = 1;
+	else
+		encrypt = 0;
+
+	status = parser_read_uint32(&p->data_offset, tokens[n_tokens - 1]);
+	if (status < 0)
+		return 0;
+
+	if (strcmp(tokens[3], "cipher") == 0) {
+		tokens += 3;
+		n_tokens -= 3;
+
+		xform = parse_table_action_cipher(p, tokens, n_tokens, encrypt,
+				&used_n_tokens);
+	} else if (strcmp(tokens[3], "cipher_auth") == 0) {
+		tokens += 3;
+		n_tokens -= 3;
+
+		xform = parse_table_action_cipher_auth(p, tokens, n_tokens,
+				encrypt, &used_n_tokens);
+	} else if (strcmp(tokens[3], "aead") == 0) {
+		tokens += 3;
+		n_tokens -= 3;
+
+		xform = parse_table_action_aead(p, tokens, n_tokens, encrypt,
+				&used_n_tokens);
+	}
+
+	if (xform == NULL)
+		return 0;
+
+	p->xform = xform;
+
+	if (strcmp(tokens[used_n_tokens], "data_offset")) {
+		parse_free_sym_crypto_param_data(p);
+		return 0;
+	}
+
+	a->action_mask |= 1 << RTE_TABLE_ACTION_SYM_CRYPTO;
+
+	return used_n_tokens + 5;
+}
+
 static uint32_t
 parse_table_action(char **tokens,
 	uint32_t n_tokens,
@@ -3665,6 +4211,20 @@ parse_table_action(char **tokens,
 		n_tokens -= n;
 	}
 
+	if (n_tokens && (strcmp(tokens[0], "sym_crypto") == 0)) {
+		uint32_t n;
+
+		n = parse_table_action_sym_crypto(tokens, n_tokens, a);
+		if (n == 0) {
+			snprintf(out, out_size, MSG_ARG_INVALID,
+				"action sym_crypto");
+			return 0;
+		}
+
+		tokens += n;
+		n_tokens -= n;
+	}
+
 	if (n_tokens0 - n_tokens == 1) {
 		snprintf(out, out_size, MSG_ARG_INVALID, "action");
 		return 0;
@@ -3752,6 +4312,9 @@ cmd_pipeline_table_rule_add(char **tokens,
 		snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
 		return;
 	}
+
+	if (a.action_mask & 1 << RTE_TABLE_ACTION_SYM_CRYPTO)
+		parse_free_sym_crypto_param_data(&a.sym_crypto);
 }
 
 
@@ -4743,6 +5306,11 @@ cmd_help(char **tokens, uint32_t n_tokens, char *out, size_t out_size)
 		return;
 	}
 
+	if (strcmp(tokens[0], "cryptodev") == 0) {
+		snprintf(out, out_size, "\n%s\n", cmd_cryptodev_help);
+		return;
+	}
+
 	if ((n_tokens == 4) &&
 		(strcmp(tokens[0], "port") == 0) &&
 		(strcmp(tokens[1], "in") == 0) &&
@@ -5033,6 +5601,11 @@ cli_process(char *in, char *out, size_t out_size)
 		return;
 	}
 
+	if (strcmp(tokens[0], "cryptodev") == 0) {
+		cmd_cryptodev(tokens, n_tokens, out, out_size);
+		return;
+	}
+
 	if (strcmp(tokens[0], "port") == 0) {
 		cmd_port_in_action_profile(tokens, n_tokens, out, out_size);
 		return;
-- 
2.13.6

^ permalink raw reply	[flat|nested] 10+ messages in thread

* [dpdk-dev] [PATCH v2 6/7] examples/ip_pipeline: add script
  2018-09-28 12:26 ` [dpdk-dev] [PATCH v2 0/7] pipeline: add symmetric crypto to action Fan Zhang
                     ` (4 preceding siblings ...)
  2018-09-28 12:26   ` [dpdk-dev] [PATCH v2 5/7] examples/ip_pipeline: update cli parsing Fan Zhang
@ 2018-09-28 12:26   ` Fan Zhang
  2018-09-28 12:26   ` [dpdk-dev] [PATCH v2 7/7] doc: update action documentation Fan Zhang
  2018-10-01 17:26   ` [dpdk-dev] [PATCH v2 0/7] pipeline: add symmetric crypto to action Dumitrescu, Cristian
  7 siblings, 0 replies; 10+ messages in thread
From: Fan Zhang @ 2018-09-28 12:26 UTC (permalink / raw)
  To: dev; +Cc: cristian.dumitrescu, Zhang, Roy Fan, Zhang

From: "Zhang, Roy Fan" <roy.fan.zhang@intel.com>

Signed-off-by: Zhang, Roy Fan <roy.fan.zhang@intel.com>
Acked-by: Dumitrescu, Cristian <cristian.dumitrescu@intel.com>
---
 examples/ip_pipeline/examples/flow_crypto.cli | 58 +++++++++++++++++++++++++++
 1 file changed, 58 insertions(+)
 create mode 100644 examples/ip_pipeline/examples/flow_crypto.cli

diff --git a/examples/ip_pipeline/examples/flow_crypto.cli b/examples/ip_pipeline/examples/flow_crypto.cli
new file mode 100644
index 000000000..9b639deb7
--- /dev/null
+++ b/examples/ip_pipeline/examples/flow_crypto.cli
@@ -0,0 +1,58 @@
+; SPDX-License-Identifier: BSD-3-Clause
+; Copyright(c) 2018 Intel Corporation
+
+;                 ________________
+; LINK0 RXQ0 --->|                |---> CRYPTO0 TXQ0
+;                |      Flow      |
+; CRYPTO0 RXQ0-->| Classification |---> LINK0 TXQ0
+;                |________________|
+;                        |
+;                        +-----------> SINK0 (flow lookup miss)
+;
+; Input packet: Ethernet/IPv4
+;
+; Packet buffer layout:
+; #   Field Name       Offset (Bytes)   Size (Bytes)
+; 0   Mbuf             0                128
+; 1   Headroom         128              128
+; 2   Ethernet header  256              14
+; 3   IPv4 header      280              20
+; 4   Packet           256              1536
+; 5   Crypto Operation 1792             160
+
+mempool MEMPOOL0 buffer 2304 pool 32K cache 256 cpu 1
+mempool MEMPOOL_SESSION0 buffer 1024 pool 1024 cache 128 cpu 1
+
+link LINK0 dev 0000:81:00.0 rxq 1 128 MEMPOOL0 txq 1 512 promiscuous on
+
+#Cryptodev
+cryptodev CRYPTO0 dev crypto_aesni_gcm0 queue 1 1024
+
+table action profile AP0 ipv4 offset 270 fwd sym_crypto dev CRYPTO0 offset 1792 mempool_create MEMPOOL_SESSION0 mempool_init MEMPOOL_SESSION0
+table action profile AP1 ipv4 offset 270 fwd
+
+pipeline PIPELINE0 period 10 offset_port_id 0 cpu 1
+
+pipeline PIPELINE0 port in bsz 32 link LINK0 rxq 0
+pipeline PIPELINE0 port in bsz 32 cryptodev CRYPTO0 rxq 0
+
+pipeline PIPELINE0 port out bsz 32 cryptodev CRYPTO0 txq 0 offset 1792
+pipeline PIPELINE0 port out bsz 32 link LINK0 txq 0
+pipeline PIPELINE0 port out bsz 32 sink
+
+pipeline PIPELINE0 table match hash ext key 8 mask FFFFFFFF00000000 offset 282 buckets 1K size 4K action AP0
+pipeline PIPELINE0 table match stub action AP1
+
+pipeline PIPELINE0 port in 0 table 0
+pipeline PIPELINE0 port in 1 table 1
+
+thread 24 pipeline PIPELINE0 enable
+
+pipeline PIPELINE0 table 0 rule add match default action fwd port 2
+
+#AES-GCM encrypt
+pipeline PIPELINE0 table 0 rule add match hash ipv4_addr 100.0.0.10 action fwd port 0 sym_crypto encrypt type aead aead_algo aes-gcm aead_key 000102030405060708090a0b0c0d0e0f aead_iv 000102030405060708090a0b aead_aad 000102030405060708090a0b0c0d0e0f digest_size 8 data_offset 290
+#AES-GCM decrypt
+#pipeline PIPELINE0 table 0 rule add match hash ipv4_addr 100.0.0.10 action fwd port 0 sym_crypto decrypt type aead aead_algo aes-gcm aead_key 000102030405060708090a0b0c0d0e0f aead_iv 000102030405060708090a0b aead_aad 000102030405060708090a0b0c0d0e0f digest_size 8 data_offset 290
+
+pipeline PIPELINE0 table 1 rule add match default action fwd port 1
-- 
2.13.6

^ permalink raw reply	[flat|nested] 10+ messages in thread

* [dpdk-dev] [PATCH v2 7/7] doc: update action documentation
  2018-09-28 12:26 ` [dpdk-dev] [PATCH v2 0/7] pipeline: add symmetric crypto to action Fan Zhang
                     ` (5 preceding siblings ...)
  2018-09-28 12:26   ` [dpdk-dev] [PATCH v2 6/7] examples/ip_pipeline: add script Fan Zhang
@ 2018-09-28 12:26   ` Fan Zhang
  2018-10-01 17:26   ` [dpdk-dev] [PATCH v2 0/7] pipeline: add symmetric crypto to action Dumitrescu, Cristian
  7 siblings, 0 replies; 10+ messages in thread
From: Fan Zhang @ 2018-09-28 12:26 UTC (permalink / raw)
  To: dev; +Cc: cristian.dumitrescu, Zhang, Roy Fan, Zhang

From: "Zhang, Roy Fan" <roy.fan.zhang@intel.com>

Signed-off-by: Zhang, Roy Fan <roy.fan.zhang@intel.com>
Acked-by: Dumitrescu, Cristian <cristian.dumitrescu@intel.com>
---
 doc/guides/prog_guide/packet_framework.rst | 11 ++++++++++-
 doc/guides/sample_app_ug/ip_pipeline.rst   | 23 +++++++++++++++++++++++
 2 files changed, 33 insertions(+), 1 deletion(-)

diff --git a/doc/guides/prog_guide/packet_framework.rst b/doc/guides/prog_guide/packet_framework.rst
index f0b485669..48d257501 100644
--- a/doc/guides/prog_guide/packet_framework.rst
+++ b/doc/guides/prog_guide/packet_framework.rst
@@ -98,6 +98,10 @@ Port Types
    |   |                  | character device.                                                                     |
    |   |                  |                                                                                       |
    +---+------------------+---------------------------------------------------------------------------------------+
+   | 9 | Sym_crypto       | Output port used to extract DPDK Cryptodev operations from a fixed offset of the      |
+   |   |                  | packet and then enqueue to the Cryptodev PMD. Input port used to dequeue the          |
+   |   |                  | Cryptodev operations from the Cryptodev PMD and then retrieve the packets from them.  |
+   +---+------------------+---------------------------------------------------------------------------------------+
 
 Port Interface
 ~~~~~~~~~~~~~~
@@ -1078,6 +1082,11 @@ with each table entry having its own set of enabled user actions and its own cop
    |   |                                   | checksum.                                                           |
    |   |                                   |                                                                     |
    +---+-----------------------------------+---------------------------------------------------------------------+
+   | 7 | Sym Crypto                        | Generate Cryptodev session based on the user-specified algorithm    |
+   |   |                                   | and key(s), and assemble the cryptodev operation based on the       |
+   |   |                                   | predefined offsets.                                                 |
+   |   |                                   |                                                                     |
+   +---+-----------------------------------+---------------------------------------------------------------------+
 
 Multicore Scaling
 -----------------
@@ -1133,7 +1142,7 @@ Typical devices with acceleration capabilities are:
 
 *   Inline accelerators: NICs, switches, FPGAs, etc;
 
-*   Look-aside accelerators: chipsets, FPGAs, etc.
+*   Look-aside accelerators: chipsets, FPGAs, Intel QuickAssist, etc.
 
 Usually, to support a specific functional block, specific implementation of Packet Framework tables and/or ports and/or actions has to be provided for each accelerator,
 with all the implementations sharing the same API: pure SW implementation (no acceleration), implementation using accelerator A, implementation using accelerator B, etc.
diff --git a/doc/guides/sample_app_ug/ip_pipeline.rst b/doc/guides/sample_app_ug/ip_pipeline.rst
index b75509a0b..447a544d5 100644
--- a/doc/guides/sample_app_ug/ip_pipeline.rst
+++ b/doc/guides/sample_app_ug/ip_pipeline.rst
@@ -304,6 +304,15 @@ Kni
     [thread <thread_id>]
 
 
+Cryptodev
+~~~~~~~~~
+
+  Create cryptodev port ::
+
+   cryptodev <cryptodev_name>
+    dev <DPDK Cryptodev PMD name>
+    queue <n_queues> <queue_size>
+
 Action profile
 ~~~~~~~~~~~~~~
 
@@ -330,6 +339,8 @@ Action profile
    [ttl drop | fwd
        stats none | pkts]
    [stats pkts | bytes | both]
+   [sym_crypto cryptodev <cryptodev_name>
+       mempool_create <mempool_name> mempool_init <mempool_name>]
    [time]
 
 
@@ -471,6 +482,18 @@ Add rule to table for specific pipeline instance ::
      [ttl dec | keep]
      [stats]
      [time]
+     [sym_crypto
+        encrypt | decrypt
+        type
+        | cipher
+           cipher_algo <algo> cipher_key <key> cipher_iv <iv>
+        | cipher_auth
+           cipher_algo <algo> cipher_key <key> cipher_iv <iv>
+           auth_algo <algo> auth_key <key> digest_size <size>
+        | aead
+           aead_algo <algo> aead_key <key> aead_iv <iv> aead_aad <aad>
+           digest_size <size>
+        data_offset <data_offset>]
 
   where:
      <pa> ::= g | y | r | drop
-- 
2.13.6

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [dpdk-dev] [PATCH v2 0/7] pipeline: add symmetric crypto to action
  2018-09-28 12:26 ` [dpdk-dev] [PATCH v2 0/7] pipeline: add symmetric crypto to action Fan Zhang
                     ` (6 preceding siblings ...)
  2018-09-28 12:26   ` [dpdk-dev] [PATCH v2 7/7] doc: update action documentation Fan Zhang
@ 2018-10-01 17:26   ` Dumitrescu, Cristian
  7 siblings, 0 replies; 10+ messages in thread
From: Dumitrescu, Cristian @ 2018-10-01 17:26 UTC (permalink / raw)
  To: Zhang, Roy Fan, dev



> -----Original Message-----
> From: Zhang, Roy Fan
> Sent: Friday, September 28, 2018 1:26 PM
> To: dev@dpdk.org
> Cc: Dumitrescu, Cristian <cristian.dumitrescu@intel.com>
> Subject: [PATCH v2 0/7] pipeline: add symmetric crypto to action
> 
> This patchset creates an abstraction layer of DPDK Cryptodev to the pipeline
> library to enable its symmetric cryptographic capability. The ip_pipeline
> sample application is updated accordingly.
> 
> v2:
> - Fixed bugs.
> - Updated data structure.
> - Updated IP-pipeline sample application.
> 
> Zhang, Roy Fan (7):
>   pipeline: add symmetric crypto to action
>   examples/ip_pipeline: add cryptodev
>   examples/ip_pipeline: configure crypto port
>   examples/ip_pipeline: add symmetric crypto action
>   examples/ip_pipeline: update cli parsing
>   examples/ip_pipeline: add script
>   doc: update action documentation
> 
>  doc/guides/prog_guide/packet_framework.rst    |  11 +-
>  doc/guides/sample_app_ug/ip_pipeline.rst      |  23 +
>  examples/ip_pipeline/Makefile                 |   1 +
>  examples/ip_pipeline/action.c                 |  11 +
>  examples/ip_pipeline/action.h                 |   1 +
>  examples/ip_pipeline/cli.c                    | 577 +++++++++++++++++++++++++-
>  examples/ip_pipeline/cryptodev.c              | 117 ++++++
>  examples/ip_pipeline/cryptodev.h              |  43 ++
>  examples/ip_pipeline/examples/flow_crypto.cli |  58 +++
>  examples/ip_pipeline/main.c                   |   9 +
>  examples/ip_pipeline/meson.build              |   3 +-
>  examples/ip_pipeline/pipeline.c               |  60 +++
>  examples/ip_pipeline/pipeline.h               |  14 +
>  examples/ip_pipeline/thread.c                 |  10 +
>  lib/librte_pipeline/Makefile                  |   2 +-
>  lib/librte_pipeline/meson.build               |   2 +-
>  lib/librte_pipeline/rte_pipeline_version.map  |   1 +
>  lib/librte_pipeline/rte_table_action.c        | 503 +++++++++++++++++++++-
>  lib/librte_pipeline/rte_table_action.h        | 104 +++++
>  19 files changed, 1543 insertions(+), 7 deletions(-)
>  create mode 100644 examples/ip_pipeline/cryptodev.c
>  create mode 100644 examples/ip_pipeline/cryptodev.h
>  create mode 100644 examples/ip_pipeline/examples/flow_crypto.cli
> 
> --
> 2.13.6

Series applied to next-pipeline tree, thanks!

^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2018-10-01 17:29 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-08-28  8:19 [dpdk-dev] [PATCH] pipeline: add symmetric crypto to table action Zhang, Roy Fan
2018-09-28 12:26 ` [dpdk-dev] [PATCH v2 0/7] pipeline: add symmetric crypto to action Fan Zhang
2018-09-28 12:26   ` [dpdk-dev] [PATCH v2 1/7] " Fan Zhang
2018-09-28 12:26   ` [dpdk-dev] [PATCH v2 2/7] examples/ip_pipeline: add cryptodev Fan Zhang
2018-09-28 12:26   ` [dpdk-dev] [PATCH v2 3/7] examples/ip_pipeline: configure crypto port Fan Zhang
2018-09-28 12:26   ` [dpdk-dev] [PATCH v2 4/7] examples/ip_pipeline: add symmetric crypto action Fan Zhang
2018-09-28 12:26   ` [dpdk-dev] [PATCH v2 5/7] examples/ip_pipeline: update cli parsing Fan Zhang
2018-09-28 12:26   ` [dpdk-dev] [PATCH v2 6/7] examples/ip_pipeline: add script Fan Zhang
2018-09-28 12:26   ` [dpdk-dev] [PATCH v2 7/7] doc: update action documentation Fan Zhang
2018-10-01 17:26   ` [dpdk-dev] [PATCH v2 0/7] pipeline: add symmetric crypto to action Dumitrescu, Cristian

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).