From: Nelio Laranjeiro <nelio.laranjeiro@6wind.com>
To: dev@dpdk.org
Cc: Aviad Yehezkel <aviadye@mellanox.com>,
Yongseok Koh <yskoh@mellanox.com>,
Adrien Mazarguil <adrien.mazarguil@6wind.com>
Subject: [dpdk-dev] [PATCH v1 3/7] net/mlx5: add IPsec Tx/Rx offload support
Date: Thu, 23 Nov 2017 17:13:05 +0100 [thread overview]
Message-ID: <78bfa76414abebb8436c1c1000a180cb6b01e0ac.1511453340.git.nelio.laranjeiro@6wind.com> (raw)
In-Reply-To: <cover.1511453340.git.nelio.laranjeiro@6wind.com>
In-Reply-To: <cover.1511453340.git.nelio.laranjeiro@6wind.com>
From: Aviad Yehezkel <aviadye@mellanox.com>
This feature is only supported by ConnectX-4 Lx INNOVA NIC. Having such
support will automatically disable and enable crypto offload device
arguments to make the PMD IPsec capable.
Signed-off-by: Aviad Yehezkel <aviadye@mellanox.com>
Signed-off-by: Nelio Laranjeiro <nelio.laranjeiro@6wind.com>
---
drivers/net/mlx5/mlx5.c | 8 ++++
drivers/net/mlx5/mlx5.h | 1 +
drivers/net/mlx5/mlx5_ethdev.c | 4 ++
drivers/net/mlx5/mlx5_prm.h | 39 ++++++++++++++++
drivers/net/mlx5/mlx5_rxtx.c | 104 ++++++++++++++++++++++++++++++++++++++---
drivers/net/mlx5/mlx5_rxtx.h | 4 +-
drivers/net/mlx5/mlx5_txq.c | 1 +
7 files changed, 154 insertions(+), 7 deletions(-)
diff --git a/drivers/net/mlx5/mlx5.c b/drivers/net/mlx5/mlx5.c
index cd66fe162..00480cef0 100644
--- a/drivers/net/mlx5/mlx5.c
+++ b/drivers/net/mlx5/mlx5.c
@@ -106,6 +106,14 @@
#define MLX5DV_CONTEXT_FLAGS_CQE_128B_COMP (1 << 4)
#endif
+#ifdef HAVE_IBV_IPSEC_SUPPORT
+#define MLX5_IPSEC_FLAGS \
+ (MLX5DV_CONTEXT_XFRM_FLAGS_ESP_AES_GCM_TX | \
+ MLX5DV_CONTEXT_XFRM_FLAGS_ESP_AES_GCM_RX | \
+ MLX5DV_CONTEXT_XFRM_FLAGS_ESP_AES_GCM_REQ_METADATA | \
+ MLX5DV_CONTEXT_XFRM_FLAGS_ESP_AES_GCM_SPI_RSS_ONLY)
+#endif
+
struct mlx5_args {
int cqe_comp;
int txq_inline;
diff --git a/drivers/net/mlx5/mlx5.h b/drivers/net/mlx5/mlx5.h
index e6a69b823..c6a01d972 100644
--- a/drivers/net/mlx5/mlx5.h
+++ b/drivers/net/mlx5/mlx5.h
@@ -117,6 +117,7 @@ struct priv {
unsigned int isolated:1; /* Whether isolated mode is enabled. */
unsigned int tx_vec_en:1; /* Whether Tx vector is enabled. */
unsigned int rx_vec_en:1; /* Whether Rx vector is enabled. */
+ unsigned int ipsec_en:1; /* Whether IPsec is enabled. */
unsigned int counter_set_supported:1; /* Counter set is supported. */
/* Whether Tx offloads for tunneled packets are supported. */
unsigned int max_tso_payload_sz; /* Maximum TCP payload for TSO. */
diff --git a/drivers/net/mlx5/mlx5_ethdev.c b/drivers/net/mlx5/mlx5_ethdev.c
index ca9ad0fef..f0c7fba43 100644
--- a/drivers/net/mlx5/mlx5_ethdev.c
+++ b/drivers/net/mlx5/mlx5_ethdev.c
@@ -680,6 +680,10 @@ mlx5_dev_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *info)
DEV_TX_OFFLOAD_TCP_CKSUM);
if (priv->tso)
info->tx_offload_capa |= DEV_TX_OFFLOAD_TCP_TSO;
+ if (priv->ipsec_en) {
+ info->tx_offload_capa |= DEV_TX_OFFLOAD_SECURITY;
+ info->rx_offload_capa |= DEV_RX_OFFLOAD_SECURITY;
+ }
if (priv->tunnel_en)
info->tx_offload_capa |= (DEV_TX_OFFLOAD_OUTER_IPV4_CKSUM |
DEV_TX_OFFLOAD_VXLAN_TNL_TSO |
diff --git a/drivers/net/mlx5/mlx5_prm.h b/drivers/net/mlx5/mlx5_prm.h
index 2de310bcb..bd6270671 100644
--- a/drivers/net/mlx5/mlx5_prm.h
+++ b/drivers/net/mlx5/mlx5_prm.h
@@ -342,4 +342,43 @@ mlx5_flow_mark_get(uint32_t val)
#endif
}
+/* IPsec offloads elements. */
+
+/* IPsec Rx code. */
+#define MLX5_IPSEC_RX_DECRYPTED 0x11
+#define MLX5_IPSEC_RX_AUTH_FAIL 0x12
+
+/* IPsec Tx code. */
+#define MLX5_IPSEC_TX_OFFLOAD 0x8
+
+/* Metadata length . */
+#define MLX5_METADATA_LEN 8
+
+/* Packet IPsec Rx metadata. */
+struct mlx5_rx_pkt_ipsec_metadata {
+ uint8_t reserved;
+ rte_be32_t sa_handle;
+} __rte_packed;
+
+/* Tx packet Metadata. */
+struct mlx5_tx_pkt_ipsec_metadata {
+ rte_be16_t mss_inv; /** MSS fixed point, used only in LSO. */
+ rte_be16_t seq; /** LSBs of the first TCP seq, only in LSO. */
+ uint8_t esp_next_proto; /* Next protocol of ESP. */
+} __rte_packed;
+
+/* Packet Metadata. */
+struct mlx5_pkt_metadata {
+ uint8_t syndrome;
+ union {
+ uint8_t raw[5];
+ struct mlx5_rx_pkt_ipsec_metadata rx;
+ struct mlx5_tx_pkt_ipsec_metadata tx;
+ } __rte_packed;
+ rte_be16_t ethertype;
+} __rte_packed;
+
+static_assert(sizeof(struct mlx5_pkt_metadata) == MLX5_METADATA_LEN,
+ "wrong metadata size detected.");
+
#endif /* RTE_PMD_MLX5_PRM_H_ */
diff --git a/drivers/net/mlx5/mlx5_rxtx.c b/drivers/net/mlx5/mlx5_rxtx.c
index 28c0ad8ab..91ceb3c55 100644
--- a/drivers/net/mlx5/mlx5_rxtx.c
+++ b/drivers/net/mlx5/mlx5_rxtx.c
@@ -344,6 +344,7 @@ mlx5_tx_burst(void *dpdk_txq, struct rte_mbuf **pkts, uint16_t pkts_n)
unsigned int j = 0;
unsigned int k = 0;
uint16_t max_elts;
+ const unsigned int ipsec_en = txq->ipsec_en;
uint16_t max_wqe;
unsigned int comp;
volatile struct mlx5_wqe_ctrl *last_wqe = NULL;
@@ -417,14 +418,43 @@ mlx5_tx_burst(void *dpdk_txq, struct rte_mbuf **pkts, uint16_t pkts_n)
rte_pktmbuf_mtod(*(pkts + 1), volatile void *));
cs_flags = txq_ol_cksum_to_cs(txq, buf);
raw = ((uint8_t *)(uintptr_t)wqe) + 2 * MLX5_WQE_DWORD_SIZE;
- /* Replace the Ethernet type by the VLAN if necessary. */
+ addr += 2;
+ length -= 2;
+ /* Handle IPsec offload. */
+ if (ipsec_en && (buf->ol_flags & PKT_TX_SEC_OFFLOAD)) {
+ struct mlx5_pkt_metadata mdata = {
+ .syndrome = MLX5_IPSEC_TX_OFFLOAD,
+ .tx.esp_next_proto = buf->inner_esp_next_proto,
+ };
+ unsigned int len = 2 * ETHER_ADDR_LEN - 2;
+ rte_be16_t ethertype =
+ rte_cpu_to_be_16(ETHER_TYPE_MLNX);
+
+ if (buf->ol_flags & PKT_TX_TCP_CKSUM) {
+ txq->stats.oerrors++;
+ break;
+ }
+ /* Copy Destination and source mac address. */
+ memcpy((uint8_t *)raw, ((uint8_t *)addr), len);
+ raw += len;
+ addr += len;
+ length -= len;
+ /* Copy Metadata. */
+ memcpy((uint8_t *)raw, ðertype, 2);
+ memcpy((uint8_t *)raw + 2, &mdata,
+ MLX5_METADATA_LEN - 2);
+ memcpy((uint8_t *)raw + MLX5_METADATA_LEN,
+ (uint8_t *)addr, 2);
+ addr += 2;
+ len -= 2;
+ raw += MLX5_METADATA_LEN + 2;
+ pkt_inline_sz += MLX5_METADATA_LEN;
+ }
if (buf->ol_flags & PKT_TX_VLAN_PKT) {
uint32_t vlan = rte_cpu_to_be_32(0x81000000 |
buf->vlan_tci);
unsigned int len = 2 * ETHER_ADDR_LEN - 2;
- addr += 2;
- length -= 2;
/* Copy Destination and source mac address. */
memcpy((uint8_t *)raw, ((uint8_t *)addr), len);
/* Copy VLAN. */
@@ -435,10 +465,10 @@ mlx5_tx_burst(void *dpdk_txq, struct rte_mbuf **pkts, uint16_t pkts_n)
addr += len + 2;
length -= (len + 2);
} else {
- memcpy((uint8_t *)raw, ((uint8_t *)addr) + 2,
+ memcpy((uint8_t *)raw, ((uint8_t *)addr),
MLX5_WQE_DWORD_SIZE);
- length -= pkt_inline_sz;
- addr += pkt_inline_sz;
+ length -= MLX5_WQE_DWORD_SIZE;
+ addr += MLX5_WQE_DWORD_SIZE;
}
raw += MLX5_WQE_DWORD_SIZE;
if (txq->tso_en) {
@@ -1572,6 +1602,59 @@ mlx5_tx_burst_empw(void *dpdk_txq, struct rte_mbuf **pkts, uint16_t pkts_n)
}
/**
+ * Process an IPsec encrypted packet.
+ *
+ * @param pkt
+ * Pointer to the first segment of the packet.
+ * @param len
+ * Already gathered packet length.
+ *
+ * @return
+ * new packet length on success, 0 on failure.
+ */
+static __rte_noinline int
+mlx5_rx_handle_ipsec(struct rte_mbuf *pkt, int len)
+{
+ struct mlx5_pkt_metadata *mdata;
+ struct ether_hdr *eth;
+
+ if (len < ETHER_HDR_LEN + MLX5_METADATA_LEN)
+ return 0;
+ eth = rte_pktmbuf_mtod(pkt, struct ether_hdr *);
+ if (eth->ether_type != rte_cpu_to_be_16(ETHER_TYPE_MLNX))
+ goto out;
+ /* Use the metadata */
+ mdata = rte_pktmbuf_mtod_offset(pkt, struct mlx5_pkt_metadata *,
+ ETHER_HDR_LEN);
+ if (mdata->syndrome == MLX5_IPSEC_RX_DECRYPTED)
+ pkt->ol_flags |= PKT_RX_SEC_OFFLOAD;
+ else if (mdata->syndrome == MLX5_IPSEC_RX_AUTH_FAIL)
+ pkt->ol_flags |= PKT_RX_SEC_OFFLOAD_FAILED;
+ else
+ return 0;
+ /*
+ * Move the data from the buffer:
+ *
+ * 6B 6B 2B 6B 2B
+ * +-----+-----+-------+----+-------+
+ * | DST | SRC | MType | MD | Etype |
+ * +-----+-----+-------+----+-------+
+ *
+ * to:
+ * 6B 6B 6B 2B
+ * +---------+-----+-----+-------+
+ * | Garbage | DST | SRC | EType |
+ * +---------+-----+-----+-------+
+ */
+ memmove((void *)((uintptr_t)mdata - 6), eth, 2 * ETHER_ADDR_LEN);
+ /* Ethertype is already in its new place */
+ rte_pktmbuf_adj(pkt, MLX5_METADATA_LEN);
+ len -= MLX5_METADATA_LEN;
+out:
+ return len;
+}
+
+/**
* Translate RX completion flags to packet type.
*
* @param[in] cqe
@@ -1772,6 +1855,7 @@ mlx5_rx_burst(void *dpdk_rxq, struct rte_mbuf **pkts, uint16_t pkts_n)
const unsigned int wqe_cnt = (1 << rxq->elts_n) - 1;
const unsigned int cqe_cnt = (1 << rxq->cqe_n) - 1;
const unsigned int sges_n = rxq->sges_n;
+ const unsigned int ipsec_en = rxq->ipsec_en;
struct rte_mbuf *pkt = NULL;
struct rte_mbuf *seg = NULL;
volatile struct mlx5_cqe *cqe =
@@ -1864,6 +1948,14 @@ mlx5_rx_burst(void *dpdk_rxq, struct rte_mbuf **pkts, uint16_t pkts_n)
}
if (rxq->crc_present)
len -= ETHER_CRC_LEN;
+ if (ipsec_en) {
+ len = mlx5_rx_handle_ipsec(pkt, len);
+ if (unlikely(len == 0)) {
+ rte_mbuf_raw_free(rep);
+ ++rxq->stats.idropped;
+ goto skip;
+ }
+ }
PKT_LEN(pkt) = len;
}
DATA_LEN(rep) = DATA_LEN(seg);
diff --git a/drivers/net/mlx5/mlx5_rxtx.h b/drivers/net/mlx5/mlx5_rxtx.h
index b8c7925a3..e219d01ee 100644
--- a/drivers/net/mlx5/mlx5_rxtx.h
+++ b/drivers/net/mlx5/mlx5_rxtx.h
@@ -115,7 +115,8 @@ struct mlx5_rxq_data {
unsigned int rss_hash:1; /* RSS hash result is enabled. */
unsigned int mark:1; /* Marked flow available on the queue. */
unsigned int pending_err:1; /* CQE error needs to be handled. */
- unsigned int :14; /* Remaining bits. */
+ unsigned int ipsec_en:1; /* IPsec is enabled on this queue. */
+ unsigned int :13; /* Remaining bits. */
volatile uint32_t *rq_db;
volatile uint32_t *cq_db;
uint16_t port_id;
@@ -195,6 +196,7 @@ struct mlx5_txq_data {
uint16_t tunnel_en:1;
/* When set TX offload for tunneled packets are supported. */
uint16_t mpw_hdr_dseg:1; /* Enable DSEGs in the title WQEBB. */
+ uint16_t ipsec_en:1; /* Whether IPsec Tx offload is enabled. */
uint16_t max_inline; /* Multiple of RTE_CACHE_LINE_SIZE to inline. */
uint16_t inline_max_packet_sz; /* Max packet size for inlining. */
uint16_t mr_cache_idx; /* Index of last hit entry. */
diff --git a/drivers/net/mlx5/mlx5_txq.c b/drivers/net/mlx5/mlx5_txq.c
index a786a6b63..4d53c6da5 100644
--- a/drivers/net/mlx5/mlx5_txq.c
+++ b/drivers/net/mlx5/mlx5_txq.c
@@ -646,6 +646,7 @@ mlx5_priv_txq_new(struct priv *priv, uint16_t idx, uint16_t desc,
}
if (priv->tunnel_en)
tmpl->txq.tunnel_en = 1;
+ tmpl->txq.ipsec_en = priv->ipsec_en;
tmpl->txq.elts =
(struct rte_mbuf *(*)[1 << tmpl->txq.elts_n])(tmpl + 1);
tmpl->txq.stats.idx = idx;
--
2.11.0
next prev parent reply other threads:[~2017-11-23 16:13 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-11-23 16:13 [dpdk-dev] [PATCH v1 0/7] net/mlx5: IPsec " Nelio Laranjeiro
2017-11-23 16:13 ` [dpdk-dev] [PATCH v1 1/7] net: define Mellanox ether type for embed metadata Nelio Laranjeiro
2017-11-23 16:13 ` [dpdk-dev] [PATCH v1 2/7] net/mlx5: handle the IPsec support from Verbs Nelio Laranjeiro
2017-11-23 16:13 ` Nelio Laranjeiro [this message]
2017-11-23 16:13 ` [dpdk-dev] [PATCH v1 4/7] net/mlx5: add security capability function Nelio Laranjeiro
2017-11-23 16:13 ` [dpdk-dev] [PATCH v1 5/7] net/mlx5: simplify error handling in flow action parsing Nelio Laranjeiro
2017-11-23 16:13 ` [dpdk-dev] [PATCH v1 6/7] net/mlx5: support security flow action Nelio Laranjeiro
2017-11-23 16:13 ` [dpdk-dev] [PATCH v1 7/7] net/mlx5: add device parameter to enabled IPsec Nelio Laranjeiro
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=78bfa76414abebb8436c1c1000a180cb6b01e0ac.1511453340.git.nelio.laranjeiro@6wind.com \
--to=nelio.laranjeiro@6wind.com \
--cc=adrien.mazarguil@6wind.com \
--cc=aviadye@mellanox.com \
--cc=dev@dpdk.org \
--cc=yskoh@mellanox.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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).