DPDK patches and discussions
 help / color / mirror / Atom feed
* [dpdk-dev] [RFC 0/7] ipsec inline
@ 2017-07-10  7:35 Boris Pismenny
  2017-07-10  7:35 ` [dpdk-dev] [RFC 1/7] ethdev: add device ipsec encrypt/decrypt capability flags Boris Pismenny
                   ` (7 more replies)
  0 siblings, 8 replies; 37+ messages in thread
From: Boris Pismenny @ 2017-07-10  7:35 UTC (permalink / raw)
  To: dev; +Cc: aviadye, borisp

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain; charset=UTF-8, Size: 9993 bytes --]

In this RFC we introduce a infrastructure for IPSec inline hardware offloading.
This RFC introduces device capabilities, configuration API and data path
processing. We also provide a comparison with a previous RFC posted on the list
for this feature.

1. Inline crypto processing 
1.1. Device Capabilities:
    o DEV_RX_OFFLOAD_IPSEC_CRYPTO            - device support inline ipsec
    decryption offload.
    o DEV_TX_OFFLOAD_IPSEC_CRYPTO_HW_TRAILER - device support inline ipsec
    encrypted offload, ipsec trailer is added by hardware.
    o DEV_TX_OFFLOAD_IPSEC_CRYPTO_TSO        - device support inline ipsec
    encrypted offload within segment large packets, ipsec trailer is added by
    hardware to each segment.

1.2. Configuration API:
    We will modify steering API in order to add IPsec transform actions.

    o Definition of ESP header: 
    
    struct esp_hdr {
        int32_t spi;  /**< Security Parameters Index */
        uint32_t seq;  /**< packet sequence number */
    } __attribute__((__packed__));

    o New flow item:

    enum rte_flow_item_type {
        ...

        /**
         * Matches a ESP header.
         *
         * See struct rte_flow_item_esp.
         */
        RTE_FLOW_ITEM_TYPE_ESP,
    };
    
    struct rte_flow_item_esp {
        struct esp_hdr hdr; /**< ESP header definition. */
    };

    struct rte_flow_item_esp {
        static const struct rte_flow_item_esp rte_flow_item_esp_mask = {
        .hdr = {
            .spi = 0xffffffff,
        },
    };

    o New ipsec transform:
    struct rte_crypto_ipsec_xform {
        enum rte_crypto_cipher_operation op;
        enum rte_crypto_cipher_algorithm algo;

        struct {
            uint8_t *data;    /**< pointer to key data */
            size_t length;    /**< key length in bytes */
        } key;

        uint32_t salt; /* salt for this security association */
    };

    /** Crypto transformation types */
    enum rte_crypto_sym_xform_type {
        ...
        RTE_CRYPTO_SYM_XFORM_CIPHER,    /**< Cipher xform  */
        RTE_CRYPTO_SYM_XFORM_IPSEC,        /**< IPsec xform  */
    };

    struct rte_crypto_sym_xform {
        ...
        struct rte_crypto_ipsec_xform ipsec;
        /**< IPsec xform */
    };
 

    o New flow action:
    
    enum rte_flow_action_type {
        ...

        /**
         * Encrypts or decrypts packets matching this flow. Must be either egress
         * or ingress, but not both.
         *
         * See struct rte_flow_action_crypto.
         */
        RTE_FLOW_ACTION_TYPE_CRYPTO,
    };

    struct rte_flow_action_crypto {
        struct rte_crypto_sym_xform xform; /* applied crypto transform */
    };

        
 Configuration Path
         |
+--------|--------+
|    Add/Remove   |
|     IPsec SA    |   <------ Build crypto flow action of ipsec transform
|        |        |
|--------|--------|
         |
+--------V--------+
|   Flow API      |
+--------|--------+
         |
+--------V--------+
|                 |
|     NIC PMD     |   <------ Add/Remove SA to/from hw context
|                 |
+--------|--------+
         |
+--------|--------+
|  HW ACCELERATED |
|        NIC      |
|                 |
+--------|--------+

o Add/Delete SA flow:
    To add a new inline SA construct a rte_flow_item for Ethernet + IP + ESP
    using the SA selectors and the rte_crypto_ipsec_xform as the rte_flow_action.
    Note that any rte_flow_items may be empty, which means it is not checked.

    In its most basic form, IPsec flow specification is as follows:
+-------+     +----------+    +--------+    +-----+ 
|  Eth  | ->  |   IP4/6  | -> |   ESP  | -> | END |
+-------+     +----------+    +--------+    +-----+ 

    However, the API can represent, IPsec crypto offload with any encapsulation:

+-------+            +--------+    +-----+
|  Eth  | ->  ... -> |   ESP  | -> | END |
+-------+            +--------+    +-----+

1.3. Data Path Processing:

1.3.1. mbuf Changes
    o New rx mbuf offload flags to indicate that a packet has gone through
    inline crypto processing on to the NIC PMD and the result of this processing.
    On failure, packets should be dropped.
    /**
     * Mask of bits used to determine the status of RX IPsec crypto.
     * - PKT_RX_IPSEC_CRYPTO_UNKNOWN     : no information about the RX IPsec crypto
     * - PKT_RX_IPSEC_CRYPTO »           : decryption and authentication were performed
     * - PKT_RX_IPSEC_CRYPTO_FAILED      : ipsec processing failed
     */
    #define PKT_RX_IPSEC_CRYPTO_UNKNOWN         0
    #define PKT_RX_IPSEC_CRYPTO                 (1ULL << 18)
    #define PKT_RX_IPSEC_CRYPTO_FAILED          (1ULL << 19)
            
    o New tx mbuf offload flags to indicate that a packet requires IPsec inline
    crypto processing and trailer construction on the NIC PMD.

    /**
     * Offload the IPsec encryption with software provided trailer.
     * This flag must be set by the application to enable this
     * offload feature for a packet to be transmitted.
     */
    #define PKT_TX_IPSEC_CRYPTO        (1ULL << 42)

    /**
       * Offload the IPsec encryption and trailer construction. This flag must
       * be set by the application to enable this offload feature for a packet
       * to be transmitted.
       */
      #define PKT_TX_IPSEC_CRYPTO_HW_TRAILER     (1ULL << 43)


  Egress Data Path
          |
+--------|--------+
|  egress IPsec   |
|        |        |
| +------V------+ |
| | SABD lookup | |
| +------|------+ |
| +------V------+ |
| |   Tunnel    | |   <------ Add tunnel header to packet
| +------|------+ |
| +------V------+ |
| |     ESP     | |   <------ Add ESP header without trailer to packet
| |             | |   <------ Mark packet to be offloaded, add trailer meta-data
| +------|------+ |              to mbuf
+--------V--------+
         |
+--------V--------+
|    L2 Stack     |
+--------|--------+
         |
+--------V--------+
|                 |
|     NIC PMD     |   <------ Set hw context for inline crypto offload
|                 |
+--------|--------+
         |
+--------|--------+
|  HW ACCELERATED |   <------ Packet Encryption/Decryption and
|        NIC      |           Authentication happens inline
|                 |
+--------|--------+



2. IPsec Gateway Sample Application
    2.1. Add/Delete SA
    SAs are configured as previously via the configuration file, the user could
    specify which SAs require inline offload by adding "offload" for that SA.
    We then store for each SA whether it is offloaded in the ipsec_sa structure.
    Additionally, we extended the ipsec_sa structure with additional fields
    related to rte_flow, which are initialized if offload is requested.
    
        struct ipsec_sa {
        ...
            #define MAX_RTE_FLOW_PATTERN (4)
            // ETH + IP + ESP + END
            union {
                    struct rte_flow_item_ipv4 ipv4;
                    struct rte_flow_item_ipv6 ipv6;
            } ip_spec;
            struct rte_flow_item_esp esp_spec;
            struct rte_flow_item pattern[MAX_RTE_FLOW_PATTERN];
            #define MAX_RTE_FLOW_ACTIONS (3)
            struct rte_flow_action_crypto crypto_action;
            struct rte_flow_action action[MAX_RTE_FLOW_ACTIONS];
            struct rte_flow *flow;
        ...
            int offload;
            #define OFFLOAD_ENABLED  1
            #define OFFLOAD_DISABLED 0
        ...
        };
    
    When a user attempts to crete a session it checks whether inline offload is
    needed. If yes, then rte_flow_create is called with the parameters
    initialized above. In any case, create_session_cryptodev is called. The
    cryptodev session is used to handle software fallback for packets that are
    not processed by hardware.
    
3. Comparison with previous RFC
    In the section we compare the previous RFC
    (http://dpdk.org/ml/archives/dev/2017-May/065513.html)
    with this RFC.

    The main difference is in NIC capabilities. Mellanox hardware
    is capable of applying IPsec inline based on packet pattern, while
    intel use mbuf metadata. This API allows application to save cycles
    by not storing metadata on each packet mbuf, but instead store metadata
    once per flow.

    Another difference is the use of Crypto PMD for inline IPsec vs.
    NIC PMD. Using the NIC PMD has several advantages. First, configuration
    is simpler - crypto is performed by the same device to which packets
    are routed, and there is no chance for configuring a crypto context on
    one device and routing packets to another device and transmitting
    plaintext as a result. Second, Crypto PMD semantics imply that data has
    been processed after dequeue. This is not true for inline IPsec, where
    data is processed only when it goes through the NIC. Finally, using the
    NIC PMD directly has better performance, because the Crypto PMD code is
    not involved.

Aviad Yehezkel (2):
  mbuf: Added next_esp_proto field
  example/ipsec_gw: Support SA offload in datapath

Boris Pismenny (5):
  ethdev: add device ipsec encrypt/decrypt capability flags
  ethdev: Add ESP header to generic flow steering
  ethdev: add rte flow action for crypto
  cryptodev: add ipsec xform
  mbuf: Add IPsec crypto flags

 examples/ipsec-secgw/esp.c            |  68 ++++++++++++----
 examples/ipsec-secgw/esp.h            |  13 +---
 examples/ipsec-secgw/ipsec.c          | 142 +++++++++++++++++++++++++++++-----
 examples/ipsec-secgw/ipsec.h          |  30 +++++++
 examples/ipsec-secgw/sa.c             | 120 ++++++++++++++++++++++++----
 lib/Makefile                          |   1 +
 lib/librte_cryptodev/rte_crypto_sym.h |  42 +++++++++-
 lib/librte_ether/rte_ethdev.h         |   4 +
 lib/librte_ether/rte_flow.h           |  50 ++++++++++++
 lib/librte_mbuf/rte_mbuf.c            |  16 ++++
 lib/librte_mbuf/rte_mbuf.h            |  38 ++++++++-
 lib/librte_net/Makefile               |   2 +-
 12 files changed, 466 insertions(+), 60 deletions(-)

-- 
1.8.3.1

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

* [dpdk-dev] [RFC 1/7] ethdev: add device ipsec encrypt/decrypt capability flags
  2017-07-10  7:35 [dpdk-dev] [RFC 0/7] ipsec inline Boris Pismenny
@ 2017-07-10  7:35 ` Boris Pismenny
  2017-07-10  7:35 ` [dpdk-dev] [RFC 2/7] ethdev: Add ESP header to generic flow steering Boris Pismenny
                   ` (6 subsequent siblings)
  7 siblings, 0 replies; 37+ messages in thread
From: Boris Pismenny @ 2017-07-10  7:35 UTC (permalink / raw)
  To: dev; +Cc: aviadye, borisp

A PMD that presents these flags supports IPsec crypto offload.
Encryption and authentication on SA entries can be offloaded to
the PMD. After adding a SA to hardware, crypto can be offloaded
on well-formed IPsec packets.

Signed-off-by: Boris Pismenny <borisp@mellanox.com>
Signed-off-by: Aviad Yehezkel <aviadye@mellanox.com>
---
 lib/librte_ether/rte_ethdev.h | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/lib/librte_ether/rte_ethdev.h b/lib/librte_ether/rte_ethdev.h
index 0f38b45..158b10c 100644
--- a/lib/librte_ether/rte_ethdev.h
+++ b/lib/librte_ether/rte_ethdev.h
@@ -883,6 +883,7 @@ struct rte_eth_conf {
 #define DEV_RX_OFFLOAD_QINQ_STRIP  0x00000020
 #define DEV_RX_OFFLOAD_OUTER_IPV4_CKSUM 0x00000040
 #define DEV_RX_OFFLOAD_MACSEC_STRIP     0x00000080
+#define DEV_RX_OFFLOAD_IPSEC_CRYPTO 0x00000100
 
 /**
  * TX offload capabilities of a device.
@@ -901,6 +902,9 @@ struct rte_eth_conf {
 #define DEV_TX_OFFLOAD_IPIP_TNL_TSO     0x00000800    /**< Used for tunneling packet. */
 #define DEV_TX_OFFLOAD_GENEVE_TNL_TSO   0x00001000    /**< Used for tunneling packet. */
 #define DEV_TX_OFFLOAD_MACSEC_INSERT    0x00002000
+#define DEV_TX_OFFLOAD_IPSEC_CRYPTO_HW_TRAILER 0x00004000
+#define DEV_TX_OFFLOAD_IPSEC_CRYPTO_TSO        0x00008000
+#define DEV_TX_OFFLOAD_IPSEC_CRYPTO_NEED_METADATA        0x00010000
 
 struct rte_pci_device;
 
-- 
1.8.3.1

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

* [dpdk-dev] [RFC 2/7] ethdev: Add ESP header to generic flow steering
  2017-07-10  7:35 [dpdk-dev] [RFC 0/7] ipsec inline Boris Pismenny
  2017-07-10  7:35 ` [dpdk-dev] [RFC 1/7] ethdev: add device ipsec encrypt/decrypt capability flags Boris Pismenny
@ 2017-07-10  7:35 ` Boris Pismenny
  2017-07-10  7:35 ` [dpdk-dev] [RFC 3/7] ethdev: add rte flow action for crypto Boris Pismenny
                   ` (5 subsequent siblings)
  7 siblings, 0 replies; 37+ messages in thread
From: Boris Pismenny @ 2017-07-10  7:35 UTC (permalink / raw)
  To: dev; +Cc: aviadye, borisp

The ESP header is required for IPsec crypto actions.

Signed-off-by: Boris Pismenny <borisp@mellanox.com>
Signed-off-by: Aviad Yehezkel <aviadye@mellanox.com>
---
 lib/librte_ether/rte_flow.h | 24 ++++++++++++++++++++++++
 lib/librte_net/Makefile     |  2 +-
 2 files changed, 25 insertions(+), 1 deletion(-)

diff --git a/lib/librte_ether/rte_flow.h b/lib/librte_ether/rte_flow.h
index c47edbc..4b78b66 100644
--- a/lib/librte_ether/rte_flow.h
+++ b/lib/librte_ether/rte_flow.h
@@ -50,6 +50,7 @@
 #include <rte_tcp.h>
 #include <rte_udp.h>
 #include <rte_byteorder.h>
+#include <rte_esp.h>
 
 #ifdef __cplusplus
 extern "C" {
@@ -297,6 +298,13 @@ enum rte_flow_item_type {
 	 * See struct rte_flow_item_gre.
 	 */
 	RTE_FLOW_ITEM_TYPE_GRE,
+
+	/**
+	 * Matches a ESP header.
+	 *
+	 * See struct rte_flow_item_esp.
+	 */
+	RTE_FLOW_ITEM_TYPE_ESP,
 };
 
 /**
@@ -701,6 +709,22 @@ struct rte_flow_item_gre {
 #endif
 
 /**
+ * RTE_FLOW_ITEM_TYPE_ESP
+ *
+ * Matches an ESP header.
+ */
+struct rte_flow_item_esp {
+	struct esp_hdr hdr; /**< ESP header definition. */
+};
+
+/** Default mask for RTE_FLOW_ITEM_TYPE_ESP. */
+static const struct rte_flow_item_esp rte_flow_item_esp_mask = {
+	.hdr = {
+		.spi = 0xffffffff,
+	},
+};
+
+/**
  * Matching pattern item definition.
  *
  * A pattern is formed by stacking items starting from the lowest protocol
diff --git a/lib/librte_net/Makefile b/lib/librte_net/Makefile
index 56727c4..0f87b23 100644
--- a/lib/librte_net/Makefile
+++ b/lib/librte_net/Makefile
@@ -42,7 +42,7 @@ SRCS-$(CONFIG_RTE_LIBRTE_NET) := rte_net.c
 SRCS-$(CONFIG_RTE_LIBRTE_NET) += rte_net_crc.c
 
 # install includes
-SYMLINK-$(CONFIG_RTE_LIBRTE_NET)-include := rte_ip.h rte_tcp.h rte_udp.h
+SYMLINK-$(CONFIG_RTE_LIBRTE_NET)-include := rte_ip.h rte_tcp.h rte_udp.h rte_esp.h
 SYMLINK-$(CONFIG_RTE_LIBRTE_NET)-include += rte_sctp.h rte_icmp.h rte_arp.h
 SYMLINK-$(CONFIG_RTE_LIBRTE_NET)-include += rte_ether.h rte_gre.h rte_net.h
 SYMLINK-$(CONFIG_RTE_LIBRTE_NET)-include += rte_net_crc.h
-- 
1.8.3.1

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

* [dpdk-dev] [RFC 3/7] ethdev: add rte flow action for crypto
  2017-07-10  7:35 [dpdk-dev] [RFC 0/7] ipsec inline Boris Pismenny
  2017-07-10  7:35 ` [dpdk-dev] [RFC 1/7] ethdev: add device ipsec encrypt/decrypt capability flags Boris Pismenny
  2017-07-10  7:35 ` [dpdk-dev] [RFC 2/7] ethdev: Add ESP header to generic flow steering Boris Pismenny
@ 2017-07-10  7:35 ` Boris Pismenny
  2017-07-10  7:35 ` [dpdk-dev] [RFC 4/7] cryptodev: add ipsec xform Boris Pismenny
                   ` (4 subsequent siblings)
  7 siblings, 0 replies; 37+ messages in thread
From: Boris Pismenny @ 2017-07-10  7:35 UTC (permalink / raw)
  To: dev; +Cc: aviadye, borisp

The crypto action is specified by an application to request
crypto offload for a flow.

Signed-off-by: Boris Pismenny <borisp@mellanox.com>
Signed-off-by: Aviad Yehezkel <aviadye@mellanox.com>
---
 lib/Makefile                |  1 +
 lib/librte_ether/rte_flow.h | 26 ++++++++++++++++++++++++++
 2 files changed, 27 insertions(+)

diff --git a/lib/Makefile b/lib/Makefile
index 07e1fd0..26c8c29 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -48,6 +48,7 @@ DEPDIRS-librte_cmdline := librte_eal
 DIRS-$(CONFIG_RTE_LIBRTE_ETHER) += librte_ether
 DEPDIRS-librte_ether := librte_net librte_eal librte_mempool librte_ring
 DEPDIRS-librte_ether += librte_mbuf
+DEPDIRS-librte_ether += librte_cryptodev
 DIRS-$(CONFIG_RTE_LIBRTE_CRYPTODEV) += librte_cryptodev
 DEPDIRS-librte_cryptodev := librte_eal librte_mempool librte_ring librte_mbuf
 DEPDIRS-librte_cryptodev += librte_kvargs
diff --git a/lib/librte_ether/rte_flow.h b/lib/librte_ether/rte_flow.h
index 4b78b66..d3f75e7 100644
--- a/lib/librte_ether/rte_flow.h
+++ b/lib/librte_ether/rte_flow.h
@@ -51,6 +51,7 @@
 #include <rte_udp.h>
 #include <rte_byteorder.h>
 #include <rte_esp.h>
+#include <rte_crypto_sym.h>
 
 #ifdef __cplusplus
 extern "C" {
@@ -905,6 +906,14 @@ enum rte_flow_action_type {
 	 * See struct rte_flow_action_vf.
 	 */
 	RTE_FLOW_ACTION_TYPE_VF,
+
+	/**
+	 * Encrypts or decrypts packets matching this flow. Must be either egress
+	 * or ingress, but not both.
+	 *
+	 * See struct rte_flow_action_crypto.
+	 */
+	RTE_FLOW_ACTION_TYPE_CRYPTO,
 };
 
 /**
@@ -998,6 +1007,23 @@ struct rte_flow_action_vf {
 };
 
 /**
+ * RTE_FLOW_ACTION_TYPE_CRYPTO
+ *
+ * Encrypts or decrypts packets matching this flow. Must be either egress
+ * or ingress, but not both.
+ *
+ * Packets matched by IPsec SA lookup, which includes at least the following:
+ * Destination IP and ESP SPI, but it may include Source IP, UDP ports, etc.
+ * Packets are encrypted in the outgoing direction and decrypted in the incoming
+ * direction.
+ *
+ * Non-terminating by default.
+ */
+struct rte_flow_action_crypto {
+	struct rte_crypto_sym_xform xform; /* applied crypto transform */
+};
+
+/**
  * Definition of a single action.
  *
  * A list of actions is terminated by a END action.
-- 
1.8.3.1

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

* [dpdk-dev] [RFC 4/7] cryptodev: add ipsec xform
  2017-07-10  7:35 [dpdk-dev] [RFC 0/7] ipsec inline Boris Pismenny
                   ` (2 preceding siblings ...)
  2017-07-10  7:35 ` [dpdk-dev] [RFC 3/7] ethdev: add rte flow action for crypto Boris Pismenny
@ 2017-07-10  7:35 ` Boris Pismenny
  2017-07-10  7:35 ` [dpdk-dev] [RFC 5/7] mbuf: Add IPsec crypto flags Boris Pismenny
                   ` (3 subsequent siblings)
  7 siblings, 0 replies; 37+ messages in thread
From: Boris Pismenny @ 2017-07-10  7:35 UTC (permalink / raw)
  To: dev; +Cc: aviadye, borisp

This patch add a xform that is used with the crypto flow
steering action to offload ipsec crypto inline.

Signed-off-by: Boris Pismenny <borisp@mellanox.com>
Signed-off-by: Aviad Yehezkel <aviadye@mellanox.com>
---
 lib/librte_cryptodev/rte_crypto_sym.h | 42 ++++++++++++++++++++++++++++++++++-
 1 file changed, 41 insertions(+), 1 deletion(-)

diff --git a/lib/librte_cryptodev/rte_crypto_sym.h b/lib/librte_cryptodev/rte_crypto_sym.h
index 3a40844..139443e 100644
--- a/lib/librte_cryptodev/rte_crypto_sym.h
+++ b/lib/librte_cryptodev/rte_crypto_sym.h
@@ -346,11 +346,49 @@ struct rte_crypto_auth_xform {
 	 */
 };
 
+/**
+ * IPsec transformation data
+ *
+ * This structure contains data relating to an IPsec crypto
+ * transforms. The fields op, algo and key are common to all
+ * IPsec encryptions and MUST be set. The salt is useful for AEAD ciphers
+ * which must provide an out-of-band nonce for each SA.
+ */
+struct rte_crypto_ipsec_xform {
+	enum rte_crypto_cipher_operation op;
+	/**< IPsec operation type */
+	enum rte_crypto_cipher_algorithm algo;
+	/**<  Encryption algorithm selection */
+
+	struct {
+		uint8_t *data;	/**< pointer to key data */
+		size_t length;	/**< key length in bytes */
+	} key;
+	/**< Cipher key
+	 *
+	 * Cipher key length is in bytes. For AES it can be 128 bits (16 bytes),
+	 * 192 bits (24 bytes) or 256 bits (32 bytes).
+	 *
+	 * For the CCM mode of operation, the only supported key length is 128
+	 * bits (16 bytes).
+	 *
+	 **/
+
+	uint32_t salt; /* salt for this security association */
+	/** <Implicit IV
+	 *
+	 * Implicit IV is set once per SA as defined by RFC 4106 (ESP AES-GCM)
+	 *
+	 **/
+
+};
+
 /** Crypto transformation types */
 enum rte_crypto_sym_xform_type {
 	RTE_CRYPTO_SYM_XFORM_NOT_SPECIFIED = 0,	/**< No xform specified */
 	RTE_CRYPTO_SYM_XFORM_AUTH,		/**< Authentication xform */
-	RTE_CRYPTO_SYM_XFORM_CIPHER		/**< Cipher xform  */
+	RTE_CRYPTO_SYM_XFORM_CIPHER,		/**< Cipher xform */
+	RTE_CRYPTO_SYM_XFORM_IPSEC,		/**< IPsec xform */
 };
 
 /**
@@ -373,6 +411,8 @@ struct rte_crypto_sym_xform {
 		/**< Authentication / hash xform */
 		struct rte_crypto_cipher_xform cipher;
 		/**< Cipher xform */
+		struct rte_crypto_ipsec_xform ipsec;
+		/**< IPsec xform */
 	};
 };
 
-- 
1.8.3.1

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

* [dpdk-dev] [RFC 5/7] mbuf: Add IPsec crypto flags
  2017-07-10  7:35 [dpdk-dev] [RFC 0/7] ipsec inline Boris Pismenny
                   ` (3 preceding siblings ...)
  2017-07-10  7:35 ` [dpdk-dev] [RFC 4/7] cryptodev: add ipsec xform Boris Pismenny
@ 2017-07-10  7:35 ` Boris Pismenny
  2017-07-10  7:35 ` [dpdk-dev] [RFC 6/7] mbuf: Added next_esp_proto field Boris Pismenny
                   ` (2 subsequent siblings)
  7 siblings, 0 replies; 37+ messages in thread
From: Boris Pismenny @ 2017-07-10  7:35 UTC (permalink / raw)
  To: dev; +Cc: aviadye, borisp

This patch adds flags to request IPsec crypto offload for
transmitted packets, and to indicate crypto result for received
packets.

Signed-off-by: Boris Pismenny <borisp@mellanox.com>
Signed-off-by: Aviad Yehezkel <aviadye@mellanox.com>
---
 lib/librte_mbuf/rte_mbuf.c | 16 ++++++++++++++++
 lib/librte_mbuf/rte_mbuf.h | 29 +++++++++++++++++++++++++++++
 2 files changed, 45 insertions(+)

diff --git a/lib/librte_mbuf/rte_mbuf.c b/lib/librte_mbuf/rte_mbuf.c
index 0e3e36a..39d0252 100644
--- a/lib/librte_mbuf/rte_mbuf.c
+++ b/lib/librte_mbuf/rte_mbuf.c
@@ -324,6 +324,10 @@ const char *rte_get_rx_ol_flag_name(uint64_t mask)
 	case PKT_RX_QINQ_STRIPPED: return "PKT_RX_QINQ_STRIPPED";
 	case PKT_RX_LRO: return "PKT_RX_LRO";
 	case PKT_RX_TIMESTAMP: return "PKT_RX_TIMESTAMP";
+	case PKT_RX_IPSEC_CRYPTO:
+		return "PKT_RX_IPSEC_CRYPTO";
+	case PKT_RX_IPSEC_CRYPTO_FAILED:
+		return "PKT_RX_IPSEC_CRYPTO_FAILED";
 	default: return NULL;
 	}
 }
@@ -359,6 +363,12 @@ struct flag_mask {
 		{ PKT_RX_QINQ_STRIPPED, PKT_RX_QINQ_STRIPPED, NULL },
 		{ PKT_RX_LRO, PKT_RX_LRO, NULL },
 		{ PKT_RX_TIMESTAMP, PKT_RX_TIMESTAMP, NULL },
+		{ PKT_RX_IPSEC_CRYPTO_UNKNOWN,
+		  PKT_RX_IPSEC_CRYPTO_UNKNOWN, "PKT_RX_IPSEC_CRYPTO_UNKNOWN" },
+		{ PKT_RX_IPSEC_CRYPTO,
+		  PKT_RX_IPSEC_CRYPTO, NULL },
+		{ PKT_RX_IPSEC_CRYPTO_FAILED,
+		  PKT_RX_IPSEC_CRYPTO_FAILED, NULL },
 	};
 	const char *name;
 	unsigned int i;
@@ -410,6 +420,9 @@ const char *rte_get_tx_ol_flag_name(uint64_t mask)
 	case PKT_TX_TUNNEL_IPIP: return "PKT_TX_TUNNEL_IPIP";
 	case PKT_TX_TUNNEL_GENEVE: return "PKT_TX_TUNNEL_GENEVE";
 	case PKT_TX_MACSEC: return "PKT_TX_MACSEC";
+	case PKT_TX_IPSEC_CRYPTO_HW_TRAILER:
+		return "PKT_TX_IPSEC_CRYPTO_HW_TRAILER";
+	case PKT_TX_IPSEC_CRYPTO: return "PKT_TX_IPSEC_CRYPTO";
 	default: return NULL;
 	}
 }
@@ -441,6 +454,9 @@ const char *rte_get_tx_ol_flag_name(uint64_t mask)
 		{ PKT_TX_TUNNEL_GENEVE, PKT_TX_TUNNEL_MASK,
 		  "PKT_TX_TUNNEL_NONE" },
 		{ PKT_TX_MACSEC, PKT_TX_MACSEC, NULL },
+		{ PKT_TX_IPSEC_CRYPTO_HW_TRAILER,
+		  PKT_TX_IPSEC_CRYPTO_HW_TRAILER, NULL },
+		{ PKT_TX_IPSEC_CRYPTO, PKT_TX_IPSEC_CRYPTO, NULL },
 	};
 	const char *name;
 	unsigned int i;
diff --git a/lib/librte_mbuf/rte_mbuf.h b/lib/librte_mbuf/rte_mbuf.h
index 1cb0310..b8ab7ed 100644
--- a/lib/librte_mbuf/rte_mbuf.h
+++ b/lib/librte_mbuf/rte_mbuf.h
@@ -190,10 +190,39 @@
 #define PKT_RX_TIMESTAMP     (1ULL << 17)
 
 /* add new RX flags here */
+/**
+ * When IPsec packet is decrypted by hardware, this flag is set in the RX
+ * mbuf to indicate that the m->crpyto fields is valid and is set according to
+ * the result of decryption.
+ */
+
+/**
+ * Mask of bits used to determine the status of RX IPsec crypto.
+ * - PKT_RX_IPSEC_CRYPTO_UNKNOWN     : no information about the RX IPsec crypto
+ * - PKT_RX_IPSEC_CRYPTO 	     : decryption and authentication were performed
+ * - PKT_RX_IPSEC_CRYPTO_FAILED      : ipsec processing failed.
+ */
+#define PKT_RX_IPSEC_CRYPTO_UNKNOWN         0
+#define PKT_RX_IPSEC_CRYPTO		   (1ULL << 18)
+#define PKT_RX_IPSEC_CRYPTO_FAILED    	   (1ULL << 19)
 
 /* add new TX flags here */
 
 /**
+ * Offload the IPsec encryption with software provided trailer.
+ * This flag must be set by the application to enable this
+ * offload feature for a packet to be transmitted.
+ */
+#define PKT_TX_IPSEC_CRYPTO		(1ULL << 42)
+
+/**
+ * Offload the IPsec encryption and trailer construction.
+ * This flag must be set by the application to enable this
+ * offload feature for a packet to be transmitted.
+ */
+#define PKT_TX_IPSEC_CRYPTO_HW_TRAILER	(1ULL << 43)
+
+/**
  * Offload the MACsec. This flag must be set by the application to enable
  * this offload feature for a packet to be transmitted.
  */
-- 
1.8.3.1

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

* [dpdk-dev] [RFC 6/7] mbuf: Added next_esp_proto field
  2017-07-10  7:35 [dpdk-dev] [RFC 0/7] ipsec inline Boris Pismenny
                   ` (4 preceding siblings ...)
  2017-07-10  7:35 ` [dpdk-dev] [RFC 5/7] mbuf: Add IPsec crypto flags Boris Pismenny
@ 2017-07-10  7:35 ` Boris Pismenny
  2017-07-10  7:35 ` [dpdk-dev] [RFC 7/7] example/ipsec_gw: Support SA offload in datapath Boris Pismenny
  2017-07-11 17:06 ` [dpdk-dev] [RFC 0/7] ipsec inline Declan Doherty
  7 siblings, 0 replies; 37+ messages in thread
From: Boris Pismenny @ 2017-07-10  7:35 UTC (permalink / raw)
  To: dev; +Cc: aviadye, borisp

From: Aviad Yehezkel <aviadye@mellanox.com>

Signed-off-by: Aviad Yehezkel <aviadye@mellanox.com>
Signed-off-by: Boris Pismenny <borisp@mellanox.com>
---
 lib/librte_mbuf/rte_mbuf.h | 9 +++++++--
 1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/lib/librte_mbuf/rte_mbuf.h b/lib/librte_mbuf/rte_mbuf.h
index b8ab7ed..234c9de 100644
--- a/lib/librte_mbuf/rte_mbuf.h
+++ b/lib/librte_mbuf/rte_mbuf.h
@@ -483,8 +483,13 @@ struct rte_mbuf {
 			uint32_t l3_type:4; /**< (Outer) L3 type. */
 			uint32_t l4_type:4; /**< (Outer) L4 type. */
 			uint32_t tun_type:4; /**< Tunnel type. */
-			uint32_t inner_l2_type:4; /**< Inner L2 type. */
-			uint32_t inner_l3_type:4; /**< Inner L3 type. */
+			union {
+				uint8_t inner_esp_next_proto;
+				struct {
+					uint8_t inner_l2_type:4; /**< Inner L2 type. */
+					uint8_t inner_l3_type:4; /**< Inner L3 type. */
+				};
+			};
 			uint32_t inner_l4_type:4; /**< Inner L4 type. */
 		};
 	};
-- 
1.8.3.1

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

* [dpdk-dev] [RFC 7/7] example/ipsec_gw: Support SA offload in datapath
  2017-07-10  7:35 [dpdk-dev] [RFC 0/7] ipsec inline Boris Pismenny
                   ` (5 preceding siblings ...)
  2017-07-10  7:35 ` [dpdk-dev] [RFC 6/7] mbuf: Added next_esp_proto field Boris Pismenny
@ 2017-07-10  7:35 ` Boris Pismenny
  2017-07-11 17:06 ` [dpdk-dev] [RFC 0/7] ipsec inline Declan Doherty
  7 siblings, 0 replies; 37+ messages in thread
From: Boris Pismenny @ 2017-07-10  7:35 UTC (permalink / raw)
  To: dev; +Cc: aviadye, borisp

From: Aviad Yehezkel <aviadye@mellanox.com>

data-path:
1. esp_outbound build ipsec headers, fill esp_next_pror
   metadata and mark packet for offload. note trailer
   will be added by hardware.
2. esp_outbound_post doing nothing for offload.
3. esp_inbound doing nothing for offload.
4. esp_inbound_post remove ipsec headers, if decrypt
   failed than print an error.
5. ipsec_enqueu skip cryptodev if offload.
6. ipsec_dequeue build pkt array depends if pkt is
   offloaded or not.

control-path:
1. parse_sa indicates that the SA uses inline crypto
   according to the "inline_port" option.
2. sa_add_rules constructs the rte_flow_item
   specification and the crypto rte_flow_action.
3. create_session calls rte_flow_create with sa
   parameters from step 2.

Signed-off-by: Aviad Yehezkel <aviadye@mellanox.com>
Signed-off-by: Boris Pismenny <borisp@mellanox.com>
---
 examples/ipsec-secgw/esp.c   |  68 ++++++++++++++++-----
 examples/ipsec-secgw/esp.h   |  13 +---
 examples/ipsec-secgw/ipsec.c | 142 +++++++++++++++++++++++++++++++++++++------
 examples/ipsec-secgw/ipsec.h |  30 +++++++++
 examples/ipsec-secgw/sa.c    | 120 ++++++++++++++++++++++++++++++++----
 5 files changed, 317 insertions(+), 56 deletions(-)

diff --git a/examples/ipsec-secgw/esp.c b/examples/ipsec-secgw/esp.c
index e77afa0..c6b48d4 100644
--- a/examples/ipsec-secgw/esp.c
+++ b/examples/ipsec-secgw/esp.c
@@ -60,8 +60,11 @@
 
 	RTE_ASSERT(m != NULL);
 	RTE_ASSERT(sa != NULL);
-	RTE_ASSERT(cop != NULL);
 
+	if (OFFLOADED_SA(sa))
+		return 0;
+
+	RTE_ASSERT(cop != NULL);
 	ip4 = rte_pktmbuf_mtod(m, struct ip *);
 	if (likely(ip4->ip_v == IPVERSION))
 		ip_hdr_len = ip4->ip_hl * 4;
@@ -159,12 +162,22 @@
 	uint8_t *nexthdr, *pad_len;
 	uint8_t *padding;
 	uint16_t i;
+	uint8_t decrypt_fail;
 
 	RTE_ASSERT(m != NULL);
 	RTE_ASSERT(sa != NULL);
-	RTE_ASSERT(cop != NULL);
 
-	if (cop->status != RTE_CRYPTO_OP_STATUS_SUCCESS) {
+	if (OFFLOADED_SA(sa)) {
+		if (m->ol_flags & PKT_RX_IPSEC_CRYPTO)
+			decrypt_fail = !!(m->ol_flags & PKT_RX_IPSEC_CRYPTO_FAILED);
+		else
+			decrypt_fail = 1;
+	} else {
+		RTE_ASSERT(cop != NULL);
+		decrypt_fail = (cop->status != RTE_CRYPTO_OP_STATUS_SUCCESS);
+	}
+
+	if (decrypt_fail) {
 		RTE_LOG(ERR, IPSEC_ESP, "failed crypto op\n");
 		return -1;
 	}
@@ -222,7 +235,6 @@
 
 	RTE_ASSERT(m != NULL);
 	RTE_ASSERT(sa != NULL);
-	RTE_ASSERT(cop != NULL);
 
 	ip_hdr_len = 0;
 
@@ -250,7 +262,6 @@
 	/* Padded payload length */
 	pad_payload_len = RTE_ALIGN_CEIL(rte_pktmbuf_pkt_len(m) -
 			ip_hdr_len + 2, sa->block_size);
-	pad_len = pad_payload_len + ip_hdr_len - rte_pktmbuf_pkt_len(m);
 
 	RTE_ASSERT(sa->flags == IP4_TUNNEL || sa->flags == IP6_TUNNEL ||
 			sa->flags == TRANSPORT);
@@ -272,12 +283,18 @@
 		return -EINVAL;
 	}
 
-	padding = (uint8_t *)rte_pktmbuf_append(m, pad_len + sa->digest_len);
-	if (unlikely(padding == NULL)) {
-		RTE_LOG(ERR, IPSEC_ESP, "not enough mbuf trailing space\n");
-		return -ENOSPC;
+	if (!OFFLOADED_SA(sa)) {
+		pad_len = pad_payload_len + ip_hdr_len - rte_pktmbuf_pkt_len(m);
+
+		padding = (uint8_t *)rte_pktmbuf_append(m, pad_len +
+							sa->digest_len);
+		if (unlikely(padding == NULL)) {
+			RTE_LOG(ERR, IPSEC_ESP,
+					"not enough mbuf trailing space\n");
+			return -ENOSPC;
+		}
+		rte_prefetch0(padding);
 	}
-	rte_prefetch0(padding);
 
 	switch (sa->flags) {
 	case IP4_TUNNEL:
@@ -311,20 +328,39 @@
 	esp->seq = rte_cpu_to_be_32((uint32_t)sa->seq);
 
 	uint64_t *iv = (uint64_t *)(esp + 1);
+	switch (sa->cipher_algo) {
+	case RTE_CRYPTO_CIPHER_NULL:
+	case RTE_CRYPTO_CIPHER_AES_CBC:
+		memset(iv, 0, sa->iv_len);
+		break;
+	case RTE_CRYPTO_CIPHER_AES_CTR:
+	case RTE_CRYPTO_CIPHER_AES_GCM:
+		*iv = sa->seq;
+		break;
+	default:
+		RTE_LOG(ERR, IPSEC_ESP, "unsupported cipher algorithm %u\n",
+				sa->cipher_algo);
+		return -EINVAL;
+	}
 
+	if (OFFLOADED_SA(sa)) {
+		m->inner_esp_next_proto = nlp;
+		m->ol_flags |= PKT_TX_IPSEC_CRYPTO_HW_TRAILER;
+		goto done;
+	}
+
+	RTE_ASSERT(cop != NULL);
 	sym_cop = get_sym_cop(cop);
 	sym_cop->m_src = m;
 	switch (sa->cipher_algo) {
 	case RTE_CRYPTO_CIPHER_NULL:
 	case RTE_CRYPTO_CIPHER_AES_CBC:
-		memset(iv, 0, sa->iv_len);
 		sym_cop->cipher.data.offset = ip_hdr_len +
 			sizeof(struct esp_hdr);
 		sym_cop->cipher.data.length = pad_payload_len + sa->iv_len;
 		break;
 	case RTE_CRYPTO_CIPHER_AES_CTR:
 	case RTE_CRYPTO_CIPHER_AES_GCM:
-		*iv = sa->seq;
 		sym_cop->cipher.data.offset = ip_hdr_len +
 			sizeof(struct esp_hdr) + sa->iv_len;
 		sym_cop->cipher.data.length = pad_payload_len;
@@ -380,18 +416,22 @@
 			rte_pktmbuf_pkt_len(m) - sa->digest_len);
 	sym_cop->auth.digest.length = sa->digest_len;
 
+done:
 	return 0;
 }
 
 int
 esp_outbound_post(struct rte_mbuf *m __rte_unused,
-		struct ipsec_sa *sa __rte_unused,
+		struct ipsec_sa *sa,
 		struct rte_crypto_op *cop)
 {
 	RTE_ASSERT(m != NULL);
 	RTE_ASSERT(sa != NULL);
-	RTE_ASSERT(cop != NULL);
 
+	if (OFFLOADED_SA(sa))
+		return 0;
+
+	RTE_ASSERT(cop != NULL);
 	if (cop->status != RTE_CRYPTO_OP_STATUS_SUCCESS) {
 		RTE_LOG(ERR, IPSEC_ESP, "Failed crypto op\n");
 		return -1;
diff --git a/examples/ipsec-secgw/esp.h b/examples/ipsec-secgw/esp.h
index fa5cc8a..e93b2aa 100644
--- a/examples/ipsec-secgw/esp.h
+++ b/examples/ipsec-secgw/esp.h
@@ -33,18 +33,9 @@
 #ifndef __RTE_IPSEC_XFORM_ESP_H__
 #define __RTE_IPSEC_XFORM_ESP_H__
 
-struct mbuf;
+#include <rte_esp.h>
 
-/* RFC4303 */
-struct esp_hdr {
-	uint32_t spi;
-	uint32_t seq;
-	/* Payload */
-	/* Padding */
-	/* Pad Length */
-	/* Next Header */
-	/* Integrity Check Value - ICV */
-};
+struct mbuf;
 
 int
 esp_inbound(struct rte_mbuf *m, struct ipsec_sa *sa,
diff --git a/examples/ipsec-secgw/ipsec.c b/examples/ipsec-secgw/ipsec.c
index edca5f0..8728f16 100644
--- a/examples/ipsec-secgw/ipsec.c
+++ b/examples/ipsec-secgw/ipsec.c
@@ -40,12 +40,32 @@
 #include <rte_cryptodev.h>
 #include <rte_mbuf.h>
 #include <rte_hash.h>
+#include <rte_flow.h>
 
 #include "ipsec.h"
 #include "esp.h"
 
+
+static inline int
+create_session_inline(struct ipsec_ctx *ipsec_ctx __rte_unused,
+		      struct ipsec_sa *sa)
+{
+	struct rte_flow_error err;
+
+	sa->flow = rte_flow_create(sa->portid, &sa->attr, sa->pattern,
+			sa->action, &err);
+	if (sa->flow == NULL) {
+		RTE_LOG(ERR, IPSEC, "Failed to create ipsec flow message: %s\n",
+				err.message);
+		return -1;
+	}
+
+	return 0;
+}
+
 static inline int
-create_session(struct ipsec_ctx *ipsec_ctx __rte_unused, struct ipsec_sa *sa)
+create_session_cryptodev(struct ipsec_ctx *ipsec_ctx __rte_unused,
+			 struct ipsec_sa *sa)
 {
 	struct rte_cryptodev_info cdev_info;
 	unsigned long cdev_id_qp = 0;
@@ -91,6 +111,15 @@
 	return 0;
 }
 
+int
+create_session(struct ipsec_ctx *ipsec_ctx, struct ipsec_sa *sa)
+{
+	if (sa->portid != -1)
+		return create_session_inline(ipsec_ctx, sa);
+	else
+		return create_session_cryptodev(ipsec_ctx, sa);
+}
+
 static inline void
 enqueue_cop(struct cdev_qp *cqp, struct rte_crypto_op *cop)
 {
@@ -117,7 +146,8 @@
 static inline void
 ipsec_enqueue(ipsec_xform_fn xform_func, struct ipsec_ctx *ipsec_ctx,
 		struct rte_mbuf *pkts[], struct ipsec_sa *sas[],
-		uint16_t nb_pkts)
+		uint16_t nb_pkts,
+		uint8_t inflight_pkt_types[], uint16_t *nb_offloaded)
 {
 	int32_t ret = 0, i;
 	struct ipsec_mbuf_metadata *priv;
@@ -142,37 +172,89 @@
 		rte_prefetch0(&priv->sym_cop);
 		priv->cop.sym = &priv->sym_cop;
 
-		if ((unlikely(sa->crypto_session == NULL)) &&
+		if ((unlikely(sa->crypto_session == NULL && sa->flow == NULL)) &&
 				create_session(ipsec_ctx, sa)) {
 			rte_pktmbuf_free(pkts[i]);
 			continue;
 		}
 
-		rte_crypto_op_attach_sym_session(&priv->cop,
-				sa->crypto_session);
-
 		ret = xform_func(pkts[i], sa, &priv->cop);
 		if (unlikely(ret)) {
 			rte_pktmbuf_free(pkts[i]);
 			continue;
 		}
 
-		RTE_ASSERT(sa->cdev_id_qp < ipsec_ctx->nb_qps);
-		enqueue_cop(&ipsec_ctx->tbl[sa->cdev_id_qp], &priv->cop);
+		if (!OFFLOADED_SA(sa)) {
+			inflight_pkt_types[i] = IPSEC_INFLIGHT_PKT_CRYPTODEV;
+			rte_crypto_op_attach_sym_session(&priv->cop,
+							 sa->crypto_session);
+
+			RTE_ASSERT(sa->cdev_id_qp < ipsec_ctx->nb_qps);
+			enqueue_cop(&ipsec_ctx->tbl[sa->cdev_id_qp],
+				    &priv->cop);
+		} else {
+			inflight_pkt_types[i] = IPSEC_INFLIGHT_PKT_OFFLOADED;
+			(*nb_offloaded)++;
+		}
+	}
+}
+
+static int32_t next_offloaded_pkt_idx(uint8_t inflight_pkt_types[],
+		int32_t curr_idx, uint16_t max_pkts)
+{
+	int32_t i = 0;
+
+	for (i = curr_idx; i < max_pkts; ++i) {
+		if (inflight_pkt_types[i] == IPSEC_INFLIGHT_PKT_OFFLOADED)
+			break;
 	}
+	return i;
+}
+
+static int32_t next_cryptodev_pkt_idx(uint8_t inflight_pkt_types[],
+		int32_t curr_idx, uint16_t max_pkts)
+{
+	int32_t i = 0;
+
+	for (i = curr_idx; i < max_pkts; ++i) {
+		if (inflight_pkt_types[i] == IPSEC_INFLIGHT_PKT_CRYPTODEV)
+			break;
+	}
+	return i;
 }
 
 static inline int
 ipsec_dequeue(ipsec_xform_fn xform_func, struct ipsec_ctx *ipsec_ctx,
-		struct rte_mbuf *pkts[], uint16_t max_pkts)
+		struct rte_mbuf *pkts[], uint16_t max_pkts,
+		uint8_t inflight_pkt_types[], uint16_t nb_offloaded)
 {
-	int32_t nb_pkts = 0, ret = 0, i, j, nb_cops;
+	int32_t nb_pkts = 0, ret = 0, i, j, idx, nb_cops;
 	struct ipsec_mbuf_metadata *priv;
 	struct rte_crypto_op *cops[max_pkts];
 	struct ipsec_sa *sa;
 	struct rte_mbuf *pkt;
 
-	for (i = 0; i < ipsec_ctx->nb_qps && nb_pkts < max_pkts; i++) {
+	/* all offloaded pkts are in place already */
+	for (i = 0, idx = 0; i < nb_offloaded; ++i) {
+		idx = next_offloaded_pkt_idx(inflight_pkt_types, idx, max_pkts);
+
+		pkt = pkts[idx];
+		rte_prefetch0(pkt);
+		priv = get_priv(pkt);
+		sa = priv->sa;
+
+		RTE_ASSERT(sa != NULL);
+
+		ret = xform_func(pkt, sa, NULL);
+		if (unlikely(ret)) {
+			rte_pktmbuf_free(pkt);
+			pkt = NULL;
+		}
+		pkts[idx++] = pkt;
+	}
+	nb_pkts += nb_offloaded;
+
+	for (i = 0, idx = 0; i < ipsec_ctx->nb_qps && nb_pkts < max_pkts; i++) {
 		struct cdev_qp *cqp;
 
 		cqp = &ipsec_ctx->tbl[ipsec_ctx->last_qp++];
@@ -197,13 +279,29 @@
 			RTE_ASSERT(sa != NULL);
 
 			ret = xform_func(pkt, sa, cops[j]);
-			if (unlikely(ret))
+			if (unlikely(ret)) {
 				rte_pktmbuf_free(pkt);
-			else
-				pkts[nb_pkts++] = pkt;
+				pkt = NULL;
+			}
+
+			idx = next_cryptodev_pkt_idx(inflight_pkt_types, idx,
+						     max_pkts);
+			pkts[idx++] = pkt;
+			nb_pkts++;
 		}
 	}
 
+	for (i = 0; i < max_pkts; ++i)
+		if (!pkts[i])
+			goto err;
+
+	goto done;
+err:
+	for (; i < max_pkts; ++i) {
+		rte_pktmbuf_free(pkts[i]);
+		--nb_pkts;
+	}
+done:
 	/* return packets */
 	return nb_pkts;
 }
@@ -213,12 +311,16 @@
 		uint16_t nb_pkts, uint16_t len)
 {
 	struct ipsec_sa *sas[nb_pkts];
+	uint8_t inflight_pkt_types[nb_pkts];
+	uint16_t nb_offloaded;
 
 	inbound_sa_lookup(ctx->sa_ctx, pkts, sas, nb_pkts);
 
-	ipsec_enqueue(esp_inbound, ctx, pkts, sas, nb_pkts);
+	ipsec_enqueue(esp_inbound, ctx, pkts, sas, nb_pkts,
+			inflight_pkt_types, &nb_offloaded);
 
-	return ipsec_dequeue(esp_inbound_post, ctx, pkts, len);
+	return ipsec_dequeue(esp_inbound_post, ctx, pkts, len,
+			inflight_pkt_types, nb_offloaded);
 }
 
 uint16_t
@@ -226,10 +328,14 @@
 		uint32_t sa_idx[], uint16_t nb_pkts, uint16_t len)
 {
 	struct ipsec_sa *sas[nb_pkts];
+	uint8_t inflight_pkt_types[nb_pkts];
+	uint16_t nb_offloaded;
 
 	outbound_sa_lookup(ctx->sa_ctx, sa_idx, sas, nb_pkts);
 
-	ipsec_enqueue(esp_outbound, ctx, pkts, sas, nb_pkts);
+	ipsec_enqueue(esp_outbound, ctx, pkts, sas, nb_pkts,
+			inflight_pkt_types, &nb_offloaded);
 
-	return ipsec_dequeue(esp_outbound_post, ctx, pkts, len);
+	return ipsec_dequeue(esp_outbound_post, ctx, pkts, len,
+			inflight_pkt_types, nb_offloaded);
 }
diff --git a/examples/ipsec-secgw/ipsec.h b/examples/ipsec-secgw/ipsec.h
index fe42661..fb2413a 100644
--- a/examples/ipsec-secgw/ipsec.h
+++ b/examples/ipsec-secgw/ipsec.h
@@ -38,6 +38,7 @@
 
 #include <rte_byteorder.h>
 #include <rte_crypto.h>
+#include <rte_flow.h>
 
 #define RTE_LOGTYPE_IPSEC       RTE_LOGTYPE_USER1
 #define RTE_LOGTYPE_IPSEC_ESP   RTE_LOGTYPE_USER2
@@ -97,6 +98,22 @@ struct ipsec_sa {
 	uint32_t cdev_id_qp;
 	uint64_t seq;
 	uint32_t salt;
+	int32_t portid;
+	struct rte_flow_attr attr;
+#define MAX_RTE_FLOW_PATTERN (4)
+	// ETH + IP + ESP + END
+	union {
+		struct rte_flow_item_ipv4 ipv4;
+		struct rte_flow_item_ipv6 ipv6;
+	} ip_spec;
+	struct rte_flow_item_esp esp_spec;
+	struct rte_flow_item pattern[MAX_RTE_FLOW_PATTERN];
+#define MAX_RTE_FLOW_ACTIONS (2)
+	// IPsec + END
+	struct rte_flow_action_crypto crypto_action;
+	struct rte_flow_action action[MAX_RTE_FLOW_ACTIONS];
+	struct rte_flow *flow;
+#define OFFLOADED_SA(sa)     ((sa)->flow)
 	struct rte_cryptodev_sym_session *crypto_session;
 	enum rte_crypto_cipher_algorithm cipher_algo;
 	enum rte_crypto_auth_algorithm auth_algo;
@@ -117,6 +134,9 @@ struct ipsec_sa {
 	struct rte_crypto_sym_xform *xforms;
 } __rte_cache_aligned;
 
+#define IPSEC_INFLIGHT_PKT_OFFLOADED (1 << 0)
+#define IPSEC_INFLIGHT_PKT_CRYPTODEV (1 << 1)
+
 struct ipsec_mbuf_metadata {
 	uint8_t buf[32];
 	struct ipsec_sa *sa;
@@ -132,6 +152,14 @@ struct cdev_qp {
 	struct rte_crypto_op *buf[MAX_PKT_BURST] __rte_aligned(sizeof(void *));
 };
 
+struct sa_ctx {
+	struct ipsec_sa sa[IPSEC_SA_MAX_ENTRIES];
+	struct {
+		struct rte_crypto_sym_xform a;
+		struct rte_crypto_sym_xform b;
+	} xf[IPSEC_SA_MAX_ENTRIES];
+};
+
 struct ipsec_ctx {
 	struct rte_hash *cdev_map;
 	struct sp_ctx *sp4_ctx;
@@ -231,4 +259,6 @@ struct cnt_blk {
 void
 rt_init(struct socket_ctx *ctx, int32_t socket_id);
 
+int
+create_session(struct ipsec_ctx *ipsec_ctx, struct ipsec_sa *sa);
 #endif /* __IPSEC_H__ */
diff --git a/examples/ipsec-secgw/sa.c b/examples/ipsec-secgw/sa.c
index 39624c4..bb17cd5 100644
--- a/examples/ipsec-secgw/sa.c
+++ b/examples/ipsec-secgw/sa.c
@@ -46,6 +46,8 @@
 #include <rte_errno.h>
 #include <rte_ip.h>
 #include <rte_random.h>
+#include <rte_flow.h>
+#include <rte_ethdev.h>
 
 #include "ipsec.h"
 #include "esp.h"
@@ -213,6 +215,7 @@ struct supported_auth_algo {
 	uint32_t src_p = 0;
 	uint32_t dst_p = 0;
 	uint32_t mode_p = 0;
+	uint32_t portid_p = 0;
 
 	if (strcmp(tokens[0], "in") == 0) {
 		ri = &nb_sa_in;
@@ -407,6 +410,8 @@ struct supported_auth_algo {
 					return;
 				rule->src.ip.ip4 = rte_bswap32(
 					(uint32_t)ip.s_addr);
+				rule->src.ip.ip4 = rte_cpu_to_be_32(
+						rule->src.ip.ip4);
 			} else if (rule->flags == IP6_TUNNEL) {
 				struct in6_addr ip;
 
@@ -450,6 +455,8 @@ struct supported_auth_algo {
 					return;
 				rule->dst.ip.ip4 = rte_bswap32(
 					(uint32_t)ip.s_addr);
+				rule->dst.ip.ip4 = rte_cpu_to_be_32(
+						rule->dst.ip.ip4);
 			} else if (rule->flags == IP6_TUNNEL) {
 				struct in6_addr ip;
 
@@ -471,6 +478,23 @@ struct supported_auth_algo {
 			continue;
 		}
 
+		if (strcmp(tokens[ti], "inline_port") == 0) {
+			APP_CHECK_PRESENCE(portid_p, tokens[ti], status);
+			if (status->status < 0)
+				return;
+
+			INCREMENT_TOKEN_INDEX(ti, n_tokens, status);
+			if (status->status < 0)
+				return;
+
+			rule->portid = atoi(tokens[ti]);
+
+			if (status->status < 0)
+				return;
+			portid_p = 1;
+			continue;
+		}
+
 		/* unrecognizeable input */
 		APP_CHECK(0, status, "unrecognized input \"%s\"",
 			tokens[ti]);
@@ -489,6 +513,10 @@ struct supported_auth_algo {
 	if (status->status < 0)
 		return;
 
+	/* This SA isn't offload */
+	if (!portid_p)
+		rule->portid = -1;
+
 	*ri = *ri + 1;
 }
 
@@ -547,14 +575,6 @@ struct supported_auth_algo {
 	printf("\n");
 }
 
-struct sa_ctx {
-	struct ipsec_sa sa[IPSEC_SA_MAX_ENTRIES];
-	struct {
-		struct rte_crypto_sym_xform a;
-		struct rte_crypto_sym_xform b;
-	} xf[IPSEC_SA_MAX_ENTRIES];
-};
-
 static struct sa_ctx *
 sa_create(const char *name, int32_t socket_id)
 {
@@ -588,11 +608,13 @@ struct sa_ctx {
 		uint32_t nb_entries, uint32_t inbound)
 {
 	struct ipsec_sa *sa;
-	uint32_t i, idx;
+	uint32_t i, idx, j;
+	struct rte_eth_dev_info dev_info;
 
 	for (i = 0; i < nb_entries; i++) {
 		idx = SPI2IDX(entries[i].spi);
 		sa = &sa_ctx->sa[idx];
+		j = 0;
 		if (sa->spi != 0) {
 			printf("Index %u already in use by SPI %u\n",
 					idx, sa->spi);
@@ -601,12 +623,75 @@ struct sa_ctx {
 		*sa = entries[i];
 		sa->seq = 0;
 
+		if (sa->portid == -1)
+			goto not_offloaded;
+
+		rte_eth_dev_info_get(sa->portid, &dev_info);
+
+		if (inbound) {
+			if ((dev_info.rx_offload_capa &
+			     DEV_RX_OFFLOAD_IPSEC_CRYPTO) == 0) {
+				RTE_LOG(WARNING, PORT,
+					"hardware RX IPSec offload is not supported\n");
+				return -EINVAL;
+			}
+		} else { /* outbound */
+			if ((dev_info.tx_offload_capa &
+			     DEV_TX_OFFLOAD_IPSEC_CRYPTO_NEED_METADATA) == 0)
+				goto inline_with_metadata;
+			if ((dev_info.tx_offload_capa &
+			     DEV_TX_OFFLOAD_IPSEC_CRYPTO_HW_TRAILER) == 0) {
+				RTE_LOG(WARNING, PORT,
+					"hardware TX IPSec offload is not supported\n");
+				return -EINVAL;
+			}
+		}
+
+		sa->pattern[j++].type = RTE_FLOW_ITEM_TYPE_ETH;
 		switch (sa->flags) {
 		case IP4_TUNNEL:
-			sa->src.ip.ip4 = rte_cpu_to_be_32(sa->src.ip.ip4);
-			sa->dst.ip.ip4 = rte_cpu_to_be_32(sa->dst.ip.ip4);
+			sa->pattern[j].type = RTE_FLOW_ITEM_TYPE_IPV4;
+			sa->pattern[j].spec = &sa->ip_spec.ipv4;
+			sa->pattern[j++].mask = &rte_flow_item_ipv4_mask;
+			sa->ip_spec.ipv4.hdr.src_addr = sa->src.ip.ip4 =
+				rte_cpu_to_be_32(sa->src.ip.ip4);
+			sa->ip_spec.ipv4.hdr.dst_addr = sa->dst.ip.ip4 =
+				rte_cpu_to_be_32(sa->dst.ip.ip4);
+			break;
+		case IP6_TUNNEL:
+			sa->pattern[j].type = RTE_FLOW_ITEM_TYPE_IPV6;
+			sa->pattern[j].spec = &sa->ip_spec.ipv6;
+			sa->pattern[j++].mask = &rte_flow_item_ipv6_mask;
+			memcpy(sa->ip_spec.ipv6.hdr.src_addr,
+					sa->src.ip.ip6.ip6_b, 16);
+			memcpy(sa->ip_spec.ipv6.hdr.dst_addr,
+					sa->dst.ip.ip6.ip6_b, 16);
+			break;
+		case TRANSPORT:
+			rte_exit(EXIT_FAILURE,
+				 "Error creating offload SA with TRANSPORT, currently not supported\n");
 		}
-
+		sa->pattern[j].type = RTE_FLOW_ITEM_TYPE_ESP;
+		sa->pattern[j].spec = &sa->esp_spec;
+		sa->pattern[j++].mask = &rte_flow_item_esp_mask;
+		sa->esp_spec.hdr.spi = entries[i].spi;
+
+		sa->pattern[j++].type = RTE_FLOW_ITEM_TYPE_END;
+
+		memset(&sa->attr, 0, sizeof(struct rte_flow_attr));
+		j = 0;
+		sa->action[j].type = RTE_FLOW_ACTION_TYPE_CRYPTO;
+		sa->action[j++].conf = &sa->crypto_action;
+		sa->crypto_action.xform.type = RTE_CRYPTO_SYM_XFORM_IPSEC;
+		sa->crypto_action.xform.ipsec.algo = RTE_CRYPTO_CIPHER_AES_GCM;
+		sa->crypto_action.xform.ipsec.key.data = sa->cipher_key;
+		sa->crypto_action.xform.ipsec.key.length = sa->cipher_key_len;
+		sa->crypto_action.xform.ipsec.salt = sa->salt;
+
+		sa->action[j].type = RTE_FLOW_ITEM_TYPE_END;
+inline_with_metadata:
+		/* Implement TX ipsec inline crypto offload with metadata here! */
+not_offloaded:
 		if (inbound) {
 			sa_ctx->xf[idx].b.type = RTE_CRYPTO_SYM_XFORM_CIPHER;
 			sa_ctx->xf[idx].b.cipher.algo = sa->cipher_algo;
@@ -628,7 +713,11 @@ struct sa_ctx {
 				sa->digest_len;
 			sa_ctx->xf[idx].a.auth.op =
 				RTE_CRYPTO_AUTH_OP_VERIFY;
-
+			if (sa->portid != -1) {
+				sa->attr.ingress = 1;
+				sa->crypto_action.xform.ipsec.op =
+						RTE_CRYPTO_CIPHER_OP_DECRYPT;
+			}
 		} else { /* outbound */
 			sa_ctx->xf[idx].a.type = RTE_CRYPTO_SYM_XFORM_CIPHER;
 			sa_ctx->xf[idx].a.cipher.algo = sa->cipher_algo;
@@ -650,6 +739,11 @@ struct sa_ctx {
 				sa->digest_len;
 			sa_ctx->xf[idx].b.auth.op =
 				RTE_CRYPTO_AUTH_OP_GENERATE;
+			if (sa->portid != -1) {
+				sa->attr.egress = 1;
+				sa->crypto_action.xform.ipsec.op =
+						RTE_CRYPTO_CIPHER_OP_ENCRYPT;
+			}
 		}
 
 		sa_ctx->xf[idx].a.next = &sa_ctx->xf[idx].b;
-- 
1.8.3.1

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

* Re: [dpdk-dev] [RFC 0/7] ipsec inline
  2017-07-10  7:35 [dpdk-dev] [RFC 0/7] ipsec inline Boris Pismenny
                   ` (6 preceding siblings ...)
  2017-07-10  7:35 ` [dpdk-dev] [RFC 7/7] example/ipsec_gw: Support SA offload in datapath Boris Pismenny
@ 2017-07-11 17:06 ` Declan Doherty
  2017-07-12 14:08   ` Boris Pismenny
  2017-07-14 11:12   ` Akhil Goyal
  7 siblings, 2 replies; 37+ messages in thread
From: Declan Doherty @ 2017-07-11 17:06 UTC (permalink / raw)
  To: Boris Pismenny, dev; +Cc: aviadye, Nicolau, Radu

On 10/07/2017 8:35 AM, Boris Pismenny wrote:
> In this RFC we introduce a infrastructure for IPSec inline hardware offloading.
> This RFC introduces device capabilities, configuration API and data path
> processing. We also provide a comparison with a previous RFC posted on the list
> for this feature.
>

Hey Boris, we've been working on v2 of the RFC based on the feedback you 
and others gave on our original , but as what we were going to propose 
is largely inline with your proposal here, with one or 2 exceptions, 
mainly on the IPsec SA management elements, I'll just comment here 
instead of sending another RFC.

We agree the rte_flow based approach as proposed here is the more 
flexible approach and should work better with futures devices which 
could offer support for other protocols as well as full protocol offload.

The main difference to your proposal below and what we are considering 
is that we would like to introduce the idea of a port based rte_security 
API which would support a generic API for security protocol 
configuration, I can see MACsec, IPsec, DTLS all working easily under 
this approach.

struct rte_security_session *
rte_security_session_create(uint8_t port_id,
		struct rte_security_sess_conf *sess_conf);


The session create function will return a opaque security session which 
would be used in the security flow action programming. The session 
configuration will contain the security protocol specific information, 
in IPsec case the SA parameter as well as the crypto xforms.

/** IPsec Security Session Configuration */
struct rte_security_conf_ipsec_sa {
	unsigned int spi;
	/**< SA security parameter index */

	enum rte_security_conf_ipsec_sa_dir {
		RTE_SECURITY_IPSEC_SA_DIR_INGRESS,
		RTE_SECURITY_IPSEC_SA_DIR_EGRESS
	} direction;
	/**< IPsec SA direction - ingress / egress */

	enum rte_security_conf_ipsec_sa_mode {
		RTE_SECURITY_IPSEC_SA_MODE_TRANSPORT,
		RTE_SECURITY_IPSEC_SA_MODE_TUNNEL
	} mode;
	/**< IPsec SA Mode - transport/tunnel */

	enum rte_security_conf_ipsec_sa_protocol {
		RTE_SECURITY_IPSEC_SA_PROTO_AH,
		RTE_SECURITY_IPSEC_SA_PROTO_ESP
	} proto;
	/**< IPsec SA Protocol - AH/ESP */

	struct ipaddr src_ip;	/**< Source IP */
	struct ipaddr dst_ip;	/**< Destination IP */
};

/**
  * Security Session Configuration
  */
struct rte_security_sess_conf {
	enum {
		RTE_SECURITY_SESS_INLINE_CRYPTO,
		RTE_SECURITY_SESS_FULL_PROTO_OFFLOAD
	} action_type;

	enum rte_security_sess_conf_type {
		SEC_CONF_DTLS,
		SEC_CONF_IPSEC,
		SEC_CONF_MACSEC

	} type;
	/**< Type of security session to be configured */

	struct {
		struct rte_security_conf_dtls dtls;
		struct rte_security_conf_ipsec_sa ipsec_sa;
		struct rte_security_conf_macsec macsec;
	};
	/* Configuration parameters for security session */

	struct rte_crypto_sym_xform *xform;
	/**< Symmetric Crypto Transform Chain */
};

The APIs would be introduced in the same manner as the flow and traffic 
management API as a plug-able component into a ethdev, and would provide 
the abstraction to configure security protocols state (IPsec SA, DTLS 
record etc.) and then the flow action would be a security flow action 
instead of the crypto flow action as proposed below.

This gives a flexible approach to future extension to other protocols 
and modes (crypto vs full offload) and also addresses an issue raised on 
the our previous RFC regarding polluting the crypto namespace with 
security protocol specific information. One other issue with putting the 
protocol information into a crypto transform is that we won't have any 
crypto devices which support them.



> 1. Inline crypto processing
> 1.1. Device Capabilities:
>     o DEV_RX_OFFLOAD_IPSEC_CRYPTO            - device support inline ipsec
>     decryption offload.
>     o DEV_TX_OFFLOAD_IPSEC_CRYPTO_HW_TRAILER - device support inline ipsec
>     encrypted offload, ipsec trailer is added by hardware.
>     o DEV_TX_OFFLOAD_IPSEC_CRYPTO_TSO        - device support inline ipsec
>     encrypted offload within segment large packets, ipsec trailer is added by
>     hardware to each segment.
>
> 1.2. Configuration API:
>     We will modify steering API in order to add IPsec transform actions.
>
>     o Definition of ESP header:
>
>     struct esp_hdr {
>         int32_t spi;  /**< Security Parameters Index */
>         uint32_t seq;  /**< packet sequence number */
>     } __attribute__((__packed__));
>
>     o New flow item:
>
>     enum rte_flow_item_type {
>         ...
>
>         /**
>          * Matches a ESP header.
>          *
>          * See struct rte_flow_item_esp.
>          */
>         RTE_FLOW_ITEM_TYPE_ESP,
>     };
>
>     struct rte_flow_item_esp {
>         struct esp_hdr hdr; /**< ESP header definition. */
>     };
>
>     struct rte_flow_item_esp {
>         static const struct rte_flow_item_esp rte_flow_item_esp_mask = {
>         .hdr = {
>             .spi = 0xffffffff,
>         },
>     };
>
>     o New ipsec transform:
>     struct rte_crypto_ipsec_xform {
>         enum rte_crypto_cipher_operation op;
>         enum rte_crypto_cipher_algorithm algo;
>
>         struct {
>             uint8_t *data;    /**< pointer to key data */
>             size_t length;    /**< key length in bytes */
>         } key;
>
>         uint32_t salt; /* salt for this security association */
>     };
>
>     /** Crypto transformation types */
>     enum rte_crypto_sym_xform_type {
>         ...
>         RTE_CRYPTO_SYM_XFORM_CIPHER,    /**< Cipher xform  */
>         RTE_CRYPTO_SYM_XFORM_IPSEC,        /**< IPsec xform  */
>     };
>
>     struct rte_crypto_sym_xform {
>         ...
>         struct rte_crypto_ipsec_xform ipsec;
>         /**< IPsec xform */
>     };
>
As mentioned above I think it would be better to keep the security 
protocol specific information separate to the crypto APIs

>
>     o New flow action:
>
>     enum rte_flow_action_type {
>         ...
>
>         /**
>          * Encrypts or decrypts packets matching this flow. Must be either egress
>          * or ingress, but not both.
>          *
>          * See struct rte_flow_action_crypto.
>          */
>         RTE_FLOW_ACTION_TYPE_CRYPTO,
>     };
>
>     struct rte_flow_action_crypto {
>         struct rte_crypto_sym_xform xform; /* applied crypto transform */
>     };
>
>
>  Configuration Path
>          |
> +--------|--------+
> |    Add/Remove   |
> |     IPsec SA    |   <------ Build crypto flow action of ipsec transform
> |        |        |
> |--------|--------|
>          |
> +--------V--------+
> |   Flow API      |
> +--------|--------+
>          |
> +--------V--------+
> |                 |
> |     NIC PMD     |   <------ Add/Remove SA to/from hw context
> |                 |
> +--------|--------+
>          |
> +--------|--------+
> |  HW ACCELERATED |
> |        NIC      |
> |                 |
> +--------|--------+
>
> o Add/Delete SA flow:
>     To add a new inline SA construct a rte_flow_item for Ethernet + IP + ESP
>     using the SA selectors and the rte_crypto_ipsec_xform as the rte_flow_action.
>     Note that any rte_flow_items may be empty, which means it is not checked.
>
>     In its most basic form, IPsec flow specification is as follows:
> +-------+     +----------+    +--------+    +-----+
> |  Eth  | ->  |   IP4/6  | -> |   ESP  | -> | END |
> +-------+     +----------+    +--------+    +-----+
>
>     However, the API can represent, IPsec crypto offload with any encapsulation:
>
> +-------+            +--------+    +-----+
> |  Eth  | ->  ... -> |   ESP  | -> | END |
> +-------+            +--------+    +-----+
>
For egress I think we need to support creating multiple flows using the 
same crypto action, i.e. multiple plaintext flows to a single IPsec SA. 
I think having the security_sess action would make this much easier than 
having to match crypto transform chains within the PMD to see if the 
action SA is the same as an existing one.

Also it will be difficult to update the tunnel state if there isn't as 
separate API for configuration.

> 1.3. Data Path Processing:
>
> 1.3.1. mbuf Changes
>     o New rx mbuf offload flags to indicate that a packet has gone through
>     inline crypto processing on to the NIC PMD and the result of this processing.
>     On failure, packets should be dropped.
>     /**
>      * Mask of bits used to determine the status of RX IPsec crypto.
>      * - PKT_RX_IPSEC_CRYPTO_UNKNOWN     : no information about the RX IPsec crypto
>      * - PKT_RX_IPSEC_CRYPTO �           : decryption and authentication were performed
>      * - PKT_RX_IPSEC_CRYPTO_FAILED      : ipsec processing failed
>      */
>     #define PKT_RX_IPSEC_CRYPTO_UNKNOWN         0
This doesn't make sense to me, it's implicit in the flag below not being 
set?

>     #define PKT_RX_IPSEC_CRYPTO                 (1ULL << 18)
>     #define PKT_RX_IPSEC_CRYPTO_FAILED          (1ULL << 19)
>
>     o New tx mbuf offload flags to indicate that a packet requires IPsec inline
>     crypto processing and trailer construction on the NIC PMD.
>
I know Thomas raised a concern of having to add multiple crypto flags 
for different protocol. If we go with the security session model, then 
PKT_RX_SECURITY & PKT_RX_SECURITY_FAILED flag would be sufficient to 
support all security protocols I think, especially if we added a generic 
field for security_session_id in the mbuf which could be populated in 
the rx_burst function.

>     /**
>      * Offload the IPsec encryption with software provided trailer.
>      * This flag must be set by the application to enable this
>      * offload feature for a packet to be transmitted.
>      */
>     #define PKT_TX_IPSEC_CRYPTO        (1ULL << 42)
>
>     /**
>        * Offload the IPsec encryption and trailer construction. This flag must
>        * be set by the application to enable this offload feature for a packet
>        * to be transmitted.
>        */
>       #define PKT_TX_IPSEC_CRYPTO_HW_TRAILER     (1ULL << 43)

Would the hw trailer not be implicit by the device you are using, or do 
you think that there may be a case when some flows would have this set 
and some wouldn't?

>
>
>   Egress Data Path
>           |
> +--------|--------+
> |  egress IPsec   |
> |        |        |
> | +------V------+ |
> | | SABD lookup | |
> | +------|------+ |
> | +------V------+ |
> | |   Tunnel    | |   <------ Add tunnel header to packet
> | +------|------+ |
> | +------V------+ |
> | |     ESP     | |   <------ Add ESP header without trailer to packet
> | |             | |   <------ Mark packet to be offloaded, add trailer meta-data
> | +------|------+ |              to mbuf
> +--------V--------+
>          |
> +--------V--------+
> |    L2 Stack     |
> +--------|--------+
>          |
> +--------V--------+
> |                 |
> |     NIC PMD     |   <------ Set hw context for inline crypto offload
> |                 |
> +--------|--------+
>          |
> +--------|--------+
> |  HW ACCELERATED |   <------ Packet Encryption/Decryption and
> |        NIC      |           Authentication happens inline
> |                 |
> +--------|--------+
>
>
>
> 2. IPsec Gateway Sample Application
>     2.1. Add/Delete SA
>     SAs are configured as previously via the configuration file, the user could
>     specify which SAs require inline offload by adding "offload" for that SA.
>     We then store for each SA whether it is offloaded in the ipsec_sa structure.
>     Additionally, we extended the ipsec_sa structure with additional fields
>     related to rte_flow, which are initialized if offload is requested.
>
>         struct ipsec_sa {
>         ...
>             #define MAX_RTE_FLOW_PATTERN (4)
>             // ETH + IP + ESP + END
>             union {
>                     struct rte_flow_item_ipv4 ipv4;
>                     struct rte_flow_item_ipv6 ipv6;
>             } ip_spec;
>             struct rte_flow_item_esp esp_spec;
>             struct rte_flow_item pattern[MAX_RTE_FLOW_PATTERN];
>             #define MAX_RTE_FLOW_ACTIONS (3)
>             struct rte_flow_action_crypto crypto_action;
>             struct rte_flow_action action[MAX_RTE_FLOW_ACTIONS];
>             struct rte_flow *flow;
>         ...
>             int offload;
>             #define OFFLOAD_ENABLED  1
>             #define OFFLOAD_DISABLED 0
>         ...
>         };
>
>     When a user attempts to crete a session it checks whether inline offload is
>     needed. If yes, then rte_flow_create is called with the parameters
>     initialized above. In any case, create_session_cryptodev is called. The
>     cryptodev session is used to handle software fallback for packets that are
>     not processed by hardware.
>
> 3. Comparison with previous RFC
>     In the section we compare the previous RFC
>     (http://dpdk.org/ml/archives/dev/2017-May/065513.html)
>     with this RFC.
>
>     The main difference is in NIC capabilities. Mellanox hardware
>     is capable of applying IPsec inline based on packet pattern, while
>     intel use mbuf metadata. This API allows application to save cycles
>     by not storing metadata on each packet mbuf, but instead store metadata
>     once per flow.
>
>     Another difference is the use of Crypto PMD for inline IPsec vs.
>     NIC PMD. Using the NIC PMD has several advantages. First, configuration
>     is simpler - crypto is performed by the same device to which packets
>     are routed, and there is no chance for configuring a crypto context on
>     one device and routing packets to another device and transmitting
>     plaintext as a result. Second, Crypto PMD semantics imply that data has
>     been processed after dequeue. This is not true for inline IPsec, where
>     data is processed only when it goes through the NIC. Finally, using the
>     NIC PMD directly has better performance, because the Crypto PMD code is
>     not involved.
>
> Aviad Yehezkel (2):
>   mbuf: Added next_esp_proto field
>   example/ipsec_gw: Support SA offload in datapath
>
> Boris Pismenny (5):
>   ethdev: add device ipsec encrypt/decrypt capability flags
>   ethdev: Add ESP header to generic flow steering
>   ethdev: add rte flow action for crypto
>   cryptodev: add ipsec xform
>   mbuf: Add IPsec crypto flags
>
>  examples/ipsec-secgw/esp.c            |  68 ++++++++++++----
>  examples/ipsec-secgw/esp.h            |  13 +---
>  examples/ipsec-secgw/ipsec.c          | 142 +++++++++++++++++++++++++++++-----
>  examples/ipsec-secgw/ipsec.h          |  30 +++++++
>  examples/ipsec-secgw/sa.c             | 120 ++++++++++++++++++++++++----
>  lib/Makefile                          |   1 +
>  lib/librte_cryptodev/rte_crypto_sym.h |  42 +++++++++-
>  lib/librte_ether/rte_ethdev.h         |   4 +
>  lib/librte_ether/rte_flow.h           |  50 ++++++++++++
>  lib/librte_mbuf/rte_mbuf.c            |  16 ++++
>  lib/librte_mbuf/rte_mbuf.h            |  38 ++++++++-
>  lib/librte_net/Makefile               |   2 +-
>  12 files changed, 466 insertions(+), 60 deletions(-)
>

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

* Re: [dpdk-dev] [RFC 0/7] ipsec inline
  2017-07-11 17:06 ` [dpdk-dev] [RFC 0/7] ipsec inline Declan Doherty
@ 2017-07-12 14:08   ` Boris Pismenny
  2017-07-14 11:12   ` Akhil Goyal
  1 sibling, 0 replies; 37+ messages in thread
From: Boris Pismenny @ 2017-07-12 14:08 UTC (permalink / raw)
  To: Declan Doherty, dev; +Cc: Aviad Yehezkel, Nicolau, Radu, Liran Liss

Hi Declan,

> Hey Boris, we've been working on v2 of the RFC based on the feedback you
> and others gave on our original , but as what we were going to propose
> is largely inline with your proposal here, with one or 2 exceptions,
> mainly on the IPsec SA management elements, I'll just comment here
> instead of sending another RFC.
> 
> We agree the rte_flow based approach as proposed here is the more
> flexible approach and should work better with futures devices which
> could offer support for other protocols as well as full protocol offload.

That's great.

> 
> The main difference to your proposal below and what we are considering
> is that we would like to introduce the idea of a port based rte_security
> API which would support a generic API for security protocol
> configuration, I can see MACsec, IPsec, DTLS all working easily under
> this approach.
> 
> struct rte_security_session *
> rte_security_session_create(uint8_t port_id,
> 		struct rte_security_sess_conf *sess_conf);
> 
> 
> The session create function will return a opaque security session which
> would be used in the security flow action programming. The session
> configuration will contain the security protocol specific information,
> in IPsec case the SA parameter as well as the crypto xforms.
> 
> /** IPsec Security Session Configuration */
> struct rte_security_conf_ipsec_sa {
> 	unsigned int spi;
> 	/**< SA security parameter index */

When not using full protocol offload. What does this field mean?

> 
> 	enum rte_security_conf_ipsec_sa_dir {
> 		RTE_SECURITY_IPSEC_SA_DIR_INGRESS,
> 		RTE_SECURITY_IPSEC_SA_DIR_EGRESS
> 	} direction;
> 	/**< IPsec SA direction - ingress / egress */
> 
> 	enum rte_security_conf_ipsec_sa_mode {
> 		RTE_SECURITY_IPSEC_SA_MODE_TRANSPORT,
> 		RTE_SECURITY_IPSEC_SA_MODE_TUNNEL
> 	} mode;
> 	/**< IPsec SA Mode - transport/tunnel */
> 
> 	enum rte_security_conf_ipsec_sa_protocol {
> 		RTE_SECURITY_IPSEC_SA_PROTO_AH,
> 		RTE_SECURITY_IPSEC_SA_PROTO_ESP
> 	} proto;
> 	/**< IPsec SA Protocol - AH/ESP */
> 
> 	struct ipaddr src_ip;	/**< Source IP */
> 	struct ipaddr dst_ip;	/**< Destination IP */

When not using full protocol offload, and when not using tunnel mode.
What do these fields mean?

I think we need a separate rte_security_conf_ipsec_sa for full proto offload
and maybe a separate one for tunnel/transport mode as well to avoid redundant
fields.
Moreover, we could split full protocol offload into 2 steps - encap/decap
and crypto. rte_create_flow already supports using multiple actions.

> };
> 
> /**
>   * Security Session Configuration
>   */
> struct rte_security_sess_conf {
> 	enum {
> 		RTE_SECURITY_SESS_INLINE_CRYPTO,
> 		RTE_SECURITY_SESS_FULL_PROTO_OFFLOAD
> 	} action_type;
> 
> 	enum rte_security_sess_conf_type {
> 		SEC_CONF_DTLS,
> 		SEC_CONF_IPSEC,
> 		SEC_CONF_MACSEC
> 
> 	} type;
> 	/**< Type of security session to be configured */
> 
> 	struct {
> 		struct rte_security_conf_dtls dtls;
> 		struct rte_security_conf_ipsec_sa ipsec_sa;
> 		struct rte_security_conf_macsec macsec;
> 	};
> 	/* Configuration parameters for security session */
> 
> 	struct rte_crypto_sym_xform *xform;
> 	/**< Symmetric Crypto Transform Chain */

> };
> 
> The APIs would be introduced in the same manner as the flow and traffic
> management API as a plug-able component into a ethdev, and would provide
> the abstraction to configure security protocols state (IPsec SA, DTLS
> record etc.) and then the flow action would be a security flow action
> instead of the crypto flow action as proposed below.
> 
> This gives a flexible approach to future extension to other protocols
> and modes (crypto vs full offload) and also addresses an issue raised on
> the our previous RFC regarding polluting the crypto namespace with
> security protocol specific information. One other issue with putting the
> protocol information into a crypto transform is that we won't have any
> crypto devices which support them.
> 
> 

We agree that it makes sense to use opaque handles for the crypto session.

The main advantage as you've mentioned below is less overhead during
updates. However, the update problem is relevant for all rte_flow_action
and crypto is not special in that sense. It would be possible to generalize
the rte_security_sess_* api to something like rte_flow_action_sess_*.

Some examples that are not related to crypto where it would be useful:
- encap/decap: add a flow to be encap/decap using specific parameters
or update the tunnel parameters.
- rss: add a flow to go through rss using specific hash or update the hash
key.

> 
> > 1. Inline crypto processing
> > 1.1. Device Capabilities:
> >     o DEV_RX_OFFLOAD_IPSEC_CRYPTO            - device support inline ipsec
> >     decryption offload.
> >     o DEV_TX_OFFLOAD_IPSEC_CRYPTO_HW_TRAILER - device support inline
> ipsec
> >     encrypted offload, ipsec trailer is added by hardware.
> >     o DEV_TX_OFFLOAD_IPSEC_CRYPTO_TSO        - device support inline ipsec
> >     encrypted offload within segment large packets, ipsec trailer is added by
> >     hardware to each segment.
> >
> > 1.2. Configuration API:
> >     We will modify steering API in order to add IPsec transform actions.
> >
> >     o Definition of ESP header:
> >
> >     struct esp_hdr {
> >         int32_t spi;  /**< Security Parameters Index */
> >         uint32_t seq;  /**< packet sequence number */
> >     } __attribute__((__packed__));
> >
> >     o New flow item:
> >
> >     enum rte_flow_item_type {
> >         ...
> >
> >         /**
> >          * Matches a ESP header.
> >          *
> >          * See struct rte_flow_item_esp.
> >          */
> >         RTE_FLOW_ITEM_TYPE_ESP,
> >     };
> >
> >     struct rte_flow_item_esp {
> >         struct esp_hdr hdr; /**< ESP header definition. */
> >     };
> >
> >     struct rte_flow_item_esp {
> >         static const struct rte_flow_item_esp rte_flow_item_esp_mask = {
> >         .hdr = {
> >             .spi = 0xffffffff,
> >         },
> >     };
> >
> >     o New ipsec transform:
> >     struct rte_crypto_ipsec_xform {
> >         enum rte_crypto_cipher_operation op;
> >         enum rte_crypto_cipher_algorithm algo;
> >
> >         struct {
> >             uint8_t *data;    /**< pointer to key data */
> >             size_t length;    /**< key length in bytes */
> >         } key;
> >
> >         uint32_t salt; /* salt for this security association */
> >     };
> >
> >     /** Crypto transformation types */
> >     enum rte_crypto_sym_xform_type {
> >         ...
> >         RTE_CRYPTO_SYM_XFORM_CIPHER,    /**< Cipher xform  */
> >         RTE_CRYPTO_SYM_XFORM_IPSEC,        /**< IPsec xform  */
> >     };
> >
> >     struct rte_crypto_sym_xform {
> >         ...
> >         struct rte_crypto_ipsec_xform ipsec;
> >         /**< IPsec xform */
> >     };
> >
> As mentioned above I think it would be better to keep the security
> protocol specific information separate to the crypto APIs
> 
> >
> >     o New flow action:
> >
> >     enum rte_flow_action_type {
> >         ...
> >
> >         /**
> >          * Encrypts or decrypts packets matching this flow. Must be either egress
> >          * or ingress, but not both.
> >          *
> >          * See struct rte_flow_action_crypto.
> >          */
> >         RTE_FLOW_ACTION_TYPE_CRYPTO,
> >     };
> >
> >     struct rte_flow_action_crypto {
> >         struct rte_crypto_sym_xform xform; /* applied crypto transform */
> >     };
> >
> >
> >  Configuration Path
> >          |
> > +--------|--------+
> > |    Add/Remove   |
> > |     IPsec SA    |   <------ Build crypto flow action of ipsec transform
> > |        |        |
> > |--------|--------|
> >          |
> > +--------V--------+
> > |   Flow API      |
> > +--------|--------+
> >          |
> > +--------V--------+
> > |                 |
> > |     NIC PMD     |   <------ Add/Remove SA to/from hw context
> > |                 |
> > +--------|--------+
> >          |
> > +--------|--------+
> > |  HW ACCELERATED |
> > |        NIC      |
> > |                 |
> > +--------|--------+
> >
> > o Add/Delete SA flow:
> >     To add a new inline SA construct a rte_flow_item for Ethernet + IP + ESP
> >     using the SA selectors and the rte_crypto_ipsec_xform as the
> rte_flow_action.
> >     Note that any rte_flow_items may be empty, which means it is not checked.
> >
> >     In its most basic form, IPsec flow specification is as follows:
> > +-------+     +----------+    +--------+    +-----+
> > |  Eth  | ->  |   IP4/6  | -> |   ESP  | -> | END |
> > +-------+     +----------+    +--------+    +-----+
> >
> >     However, the API can represent, IPsec crypto offload with any
> encapsulation:
> >
> > +-------+            +--------+    +-----+
> > |  Eth  | ->  ... -> |   ESP  | -> | END |
> > +-------+            +--------+    +-----+
> >
> For egress I think we need to support creating multiple flows using the
> same crypto action, i.e. multiple plaintext flows to a single IPsec SA.
> I think having the security_sess action would make this much easier than
> having to match crypto transform chains within the PMD to see if the
> action SA is the same as an existing one.
> 
> Also it will be difficult to update the tunnel state if there isn't as
> separate API for configuration.
> 

I agree. As I've said above, this is true for all rte_flow_action.

> > 1.3. Data Path Processing:
> >
> > 1.3.1. mbuf Changes
> >     o New rx mbuf offload flags to indicate that a packet has gone through
> >     inline crypto processing on to the NIC PMD and the result of this processing.
> >     On failure, packets should be dropped.
> >     /**
> >      * Mask of bits used to determine the status of RX IPsec crypto.
> >      * - PKT_RX_IPSEC_CRYPTO_UNKNOWN     : no information about the RX
> IPsec crypto
> >      * - PKT_RX_IPSEC_CRYPTO �           : decryption and authentication were
> performed
> >      * - PKT_RX_IPSEC_CRYPTO_FAILED      : ipsec processing failed
> >      */
> >     #define PKT_RX_IPSEC_CRYPTO_UNKNOWN         0
> This doesn't make sense to me, it's implicit in the flag below not being
> set?
> 

This is similar to PKT_RX_IP_CKSUM_UNKNOWN and it appears here to
make things more clear to the reader.

> >     #define PKT_RX_IPSEC_CRYPTO                 (1ULL << 18)
> >     #define PKT_RX_IPSEC_CRYPTO_FAILED          (1ULL << 19)
> >
> >     o New tx mbuf offload flags to indicate that a packet requires IPsec inline
> >     crypto processing and trailer construction on the NIC PMD.
> >
> I know Thomas raised a concern of having to add multiple crypto flags
> for different protocol. If we go with the security session model, then
> PKT_RX_SECURITY & PKT_RX_SECURITY_FAILED flag would be sufficient to
> support all security protocols I think, especially if we added a generic
> field for security_session_id in the mbuf which could be populated in
> the rx_burst function.
> 
> >     /**
> >      * Offload the IPsec encryption with software provided trailer.
> >      * This flag must be set by the application to enable this
> >      * offload feature for a packet to be transmitted.
> >      */
> >     #define PKT_TX_IPSEC_CRYPTO        (1ULL << 42)
> >
> >     /**
> >        * Offload the IPsec encryption and trailer construction. This flag must
> >        * be set by the application to enable this offload feature for a packet
> >        * to be transmitted.
> >        */
> >       #define PKT_TX_IPSEC_CRYPTO_HW_TRAILER     (1ULL << 43)
> 
> Would the hw trailer not be implicit by the device you are using, or do
> you think that there may be a case when some flows would have this set
> and some wouldn't?
> 

What do you mean by "implicit by the device"?

The IPsec trailer would be constructed by the device for packets which set this flag.
Some devices might require the user to provide the trailer of the ESP packet.

Doesn't your device require that?

Users of these devices could use the PKT_TX_IPSEC_CRYPTO alone to indicate
that software provides the trailer and expects inline crypto offload.

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

* Re: [dpdk-dev] [RFC 0/7] ipsec inline
  2017-07-11 17:06 ` [dpdk-dev] [RFC 0/7] ipsec inline Declan Doherty
  2017-07-12 14:08   ` Boris Pismenny
@ 2017-07-14 11:12   ` Akhil Goyal
  2017-07-25 11:21     ` [dpdk-dev] [RFC PATCH 0/1] IPSec Inline and look aside crypto offload Akhil Goyal
  1 sibling, 1 reply; 37+ messages in thread
From: Akhil Goyal @ 2017-07-14 11:12 UTC (permalink / raw)
  To: Declan Doherty, Boris Pismenny, dev; +Cc: aviadye, Nicolau, Radu, sandeep.malik

Hi Declan/Boris,

On 7/11/2017 10:36 PM, Declan Doherty wrote:
> On 10/07/2017 8:35 AM, Boris Pismenny wrote:
>> In this RFC we introduce a infrastructure for IPSec inline hardware 
>> offloading.
>> This RFC introduces device capabilities, configuration API and data path
>> processing. We also provide a comparison with a previous RFC posted on 
>> the list
>> for this feature.
>>
> 
> Hey Boris, we've been working on v2 of the RFC based on the feedback you 
> and others gave on our original , but as what we were going to propose 
> is largely inline with your proposal here, with one or 2 exceptions, 
> mainly on the IPsec SA management elements, I'll just comment here 
> instead of sending another RFC.
> 
> We agree the rte_flow based approach as proposed here is the more 
> flexible approach and should work better with futures devices which 
> could offer support for other protocols as well as full protocol offload.
> 
> The main difference to your proposal below and what we are considering 
> is that we would like to introduce the idea of a port based rte_security 
> API which would support a generic API for security protocol 
> configuration, I can see MACsec, IPsec, DTLS all working easily under 
> this approach.
> 
> struct rte_security_session *
> rte_security_session_create(uint8_t port_id,
>          struct rte_security_sess_conf *sess_conf);
> 
Is this a proposal to add another library to add APIs and structures 
rte_security_XXX.

If not, is it not worth to add a generic security library which can be 
used both by ethdev and cryptodev. We may have crypto devices(dpaa2_sec) 
which can also support look-aside protocol offload.

rte_security_session_create(), may take a dev_id and device type as 
input and call respective device's security session create.

> 
> The session create function will return a opaque security session which 
> would be used in the security flow action programming. The session 
> configuration will contain the security protocol specific information, 
> in IPsec case the SA parameter as well as the crypto xforms.
> 
> /** IPsec Security Session Configuration */
> struct rte_security_conf_ipsec_sa {
>      unsigned int spi;
>      /**< SA security parameter index */
> 
>      enum rte_security_conf_ipsec_sa_dir {
>          RTE_SECURITY_IPSEC_SA_DIR_INGRESS,
>          RTE_SECURITY_IPSEC_SA_DIR_EGRESS
>      } direction;
>      /**< IPsec SA direction - ingress / egress */
> 
>      enum rte_security_conf_ipsec_sa_mode {
>          RTE_SECURITY_IPSEC_SA_MODE_TRANSPORT,
>          RTE_SECURITY_IPSEC_SA_MODE_TUNNEL
>      } mode;
>      /**< IPsec SA Mode - transport/tunnel */
> 
>      enum rte_security_conf_ipsec_sa_protocol {
>          RTE_SECURITY_IPSEC_SA_PROTO_AH,
>          RTE_SECURITY_IPSEC_SA_PROTO_ESP
>      } proto;
>      /**< IPsec SA Protocol - AH/ESP */
> 
>      struct ipaddr src_ip;    /**< Source IP */
>      struct ipaddr dst_ip;    /**< Destination IP */
> };
> 
> /**
>   * Security Session Configuration
>   */
> struct rte_security_sess_conf {
>      enum {
>          RTE_SECURITY_SESS_INLINE_CRYPTO,
>          RTE_SECURITY_SESS_FULL_PROTO_OFFLOAD
>      } action_type;
> 
>      enum rte_security_sess_conf_type {
>          SEC_CONF_DTLS,
>          SEC_CONF_IPSEC,
>          SEC_CONF_MACSEC
> 
>      } type;
>      /**< Type of security session to be configured */
> 
>      struct {
>          struct rte_security_conf_dtls dtls;
>          struct rte_security_conf_ipsec_sa ipsec_sa;
>          struct rte_security_conf_macsec macsec;
>      };
>      /* Configuration parameters for security session */
> 
>      struct rte_crypto_sym_xform *xform;
>      /**< Symmetric Crypto Transform Chain */
> };
> 
> The APIs would be introduced in the same manner as the flow and traffic 
> management API as a plug-able component into a ethdev, and would provide 
> the abstraction to configure security protocols state (IPsec SA, DTLS 
> record etc.) and then the flow action would be a security flow action 
> instead of the crypto flow action as proposed below.
> 
> This gives a flexible approach to future extension to other protocols 
> and modes (crypto vs full offload) and also addresses an issue raised on 
> the our previous RFC regarding polluting the crypto namespace with 
> security protocol specific information. One other issue with putting the 
> protocol information into a crypto transform is that we won't have any 
> crypto devices which support them.
> 
> 
> 
>> 1. Inline crypto processing
>> 1.1. Device Capabilities:
>>     o DEV_RX_OFFLOAD_IPSEC_CRYPTO            - device support inline 
>> ipsec
>>     decryption offload.
>>     o DEV_TX_OFFLOAD_IPSEC_CRYPTO_HW_TRAILER - device support inline 
>> ipsec
>>     encrypted offload, ipsec trailer is added by hardware.
>>     o DEV_TX_OFFLOAD_IPSEC_CRYPTO_TSO        - device support inline 
>> ipsec
>>     encrypted offload within segment large packets, ipsec trailer is 
>> added by
>>     hardware to each segment.
>>
>> 1.2. Configuration API:
>>     We will modify steering API in order to add IPsec transform actions.
>>
>>     o Definition of ESP header:
>>
>>     struct esp_hdr {
>>         int32_t spi;  /**< Security Parameters Index */
>>         uint32_t seq;  /**< packet sequence number */
>>     } __attribute__((__packed__));
>>
>>     o New flow item:
>>
>>     enum rte_flow_item_type {
>>         ...
>>
>>         /**
>>          * Matches a ESP header.
>>          *
>>          * See struct rte_flow_item_esp.
>>          */
>>         RTE_FLOW_ITEM_TYPE_ESP,
>>     };
>>
>>     struct rte_flow_item_esp {
>>         struct esp_hdr hdr; /**< ESP header definition. */
>>     };
>>
>>     struct rte_flow_item_esp {
>>         static const struct rte_flow_item_esp rte_flow_item_esp_mask = {
>>         .hdr = {
>>             .spi = 0xffffffff,
>>         },
>>     };
>>
>>     o New ipsec transform:
>>     struct rte_crypto_ipsec_xform {
>>         enum rte_crypto_cipher_operation op;
>>         enum rte_crypto_cipher_algorithm algo;
>>
>>         struct {
>>             uint8_t *data;    /**< pointer to key data */
>>             size_t length;    /**< key length in bytes */
>>         } key;
>>
>>         uint32_t salt; /* salt for this security association */
>>     };
>>

Authentication algos and key missing.


-Akhil

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

* [dpdk-dev] [RFC PATCH 0/1] IPSec Inline and look aside crypto offload
  2017-07-14 11:12   ` Akhil Goyal
@ 2017-07-25 11:21     ` Akhil Goyal
  2017-07-25 11:21       ` [dpdk-dev] [RFC PATCH 1/1] rte_security: proposal Akhil Goyal
                         ` (3 more replies)
  0 siblings, 4 replies; 37+ messages in thread
From: Akhil Goyal @ 2017-07-25 11:21 UTC (permalink / raw)
  To: dev, borisp, declan.doherty
  Cc: radu.nicolau, aviadye, sandeep.malik, hemant.agrawal,
	pablo.de.lara.guarch, Akhil Goyal

Below is a counter proposal for the RFC sent by Boris.
If we find some consensus, we can have implementation for this proposal in a few weeks.

The proposal is largely inline with the thoughts from Declan with a few exceptions.
Here we are proposing a security framework which can be used both by crypto drivers
and the hw offloaded NIC to showcase the protocol offload support as well as inline
ipsec in hw offloaded NIC.

The placement of the rte_security.X can either be a separate library like
lib/librte_security/ or it can be taken as an extension to the lib/librte_cryptodev/.
The reason for placing this in the cryptodev is that we are referring to some
crypto enums and the APIs look similar to that of cryptodev.

Here we propose that the application may be able to configure either NIC or
crypto PMD to perform IPSec and other security operations.
This is configured using the API

int
rte_security_configure(uint16_t dev_id, char *dev_name);

This API take dev_id and dev_name to identify which device needs to perform security
operation. Once the device is enabled for Security operations, the application can
create and initialize the session for the enabled device.

struct rte_security_session *
rte_security_session_create(struct rte_mempool *mempool);

int
rte_security_session_init(uint16_t dev_id, char *dev_name,
                          struct rte_security_session *sess,
                          struct rte_security_sess_conf *conf,
                          struct rte_mempool *mempool);

These two APIs are similar to the rte_cryptodev_sym_session_create and
rte_cryptodev_sym_session_init respectively, except that rte_security_session_init
takes device name also to identify between the NIC(IPSEC inline or full offload)
or crypto(look aside protocol offload).

These sessions can be cleared and freed with the APIs

int
rte_security_session_clear(uint8_t dev_id, char *dev_name,
                           struct rte_security_session *sess);
int
rte_security_session_free(struct rte_security_session *sess);

The details for various structures used are mentioned in the below patch.
These are very similar to what Declan proposed with a few additions.
This can be updated further for other security protocols like MACSec and DTLS

Now, after the application configures the session using above APIs, it needs to
attach the  session with the crypto_op in case the session is configured for
crypto look aside protocol offload. For IPSec inline/ full protocol offload
using NIC, the mbuf ol_flags can be set as per the RFC suggested by Boris.

Configuration path for both crypto and NIC can be illustrated as below

  Configuration Path                       Configuration Path
       for NIC                                  for Crypto
          |                                         |
 +--------|--------+                       +--------|--------+
 |    Add/Remove   |                       |   Add/Remove    |
 |     IPsec SA    |                       |    IPSec SA     |
 |        |        |                       |        |        |
 |--------|--------|                       +--------|--------+
          |                                         |
 +--------V--------+                                |
 |   Flow API      |                                |
 +--------|--------+                                |
          |                                         |
 +--------V--------+                       +--------V--------+
 |                 |                       |                 |
 |     NIC PMD     |                       |    Crypto PMD   |
 |                 |                       |                 |
 +--------|--------+                       +--------|--------+
          |                                         |
 +--------|--------+                       +--------|--------+
 |  HW ACCELERATED |                       |     HW Crypto   |
 |        NIC      |                       |  Protocol Aware |
 |                 |                       |     Device      |
 +--------|--------+                       +--------|--------+


Now the application(ipsec-secgw) have 4 paths to decide for the data path.
1. Non-protocol offload (currently implemented)
2. IPSec inline(only crypto operations using NIC)
3. full protocol offload(crypto operations along with all the IPsec header
   and trailer processing using NIC)
4. look aside protocol offload(single-pass encryption and authentication with
   additional levels of protocol processing offload using crypto device)

The application can decide using the below action types
enum rte_security_session_action_type {
        RTE_SECURITY_SESS_ETH_INLINE_CRYPTO,
        /**< Crypto operations are performed by Network interface */
        RTE_SECURITY_SESS_ETH_PROTO_OFFLOAD,
        /**< Crypto operations with protocol support are performed
         * by Network/ethernet device.
         */
        RTE_SECURITY_SESS_CRYPTO_PROTO_OFFLOAD,
        /**< Crypto operations with protocol support are performed
         * by Crypto device.
         */
        RTE_SECURITY_SESS_NONE
	/**< Non protocol offload. Application need to manage everything */
};


 Egress Data Path

For ETH_INLINE_CRYPTO                  For CRYPTO_PROTO_OFFLOAD
         |                                         |
+--------|--------+                    +-----------|-----------+
|  egress IPsec   |                    | Plain packet from NIC |
|        |        |                    |           |           |
| +------V------+ |                    |  +--------V--------+  |
| | SABD lookup | |                    |  |    SA lookup    |  |
| +------|------+ |                    |  +--------|--------+  |
| +------V------+ |                    |  +--------V--------+  |
| |   Tunnel    | |                    |  |  session attach |  |
| +------|------+ |                    |  +--------|--------+  |   +------------+
| +------V------+ |                    |  +--------V--------+  |   | Hw crypto  |
| |     ESP     | |                    |  |Enqueue to crypto|------>  Device    |      <--- Headers are added by the HW device.
| |             | |                    |  |     Device      |  |   |            |
| +------|------+ |                    |  +-----------------+  |   +-----|------+
+--------V--------+                    |  +-----------------+  |         |
         |                             |  |  Dequeue from   |<-----------+   
+--------V--------+                    |  |  Crypto Device  |  |
|    L2 Stack     |                    |  +--------|--------+  |
+--------|--------+                    |  +--------V--------+  |
         |                             |  |   L2 Stack      |  |
+--------V--------+                    |  +--------|--------+  |
|                 |                    +-----------|-----------+
|     NIC PMD     |                                |
|                 |                    +-----------V-----------+
+--------|--------+                    |        NIC PMD        |
         |                             |   (packet sent out)   |
+--------|--------+                    +-----------|-----------+
|  HW ACCELERATED |   
|        NIC      |          
|                 |
+--------|--------+

   Ingress Data Path

For ETH_INLINE_CRYPTO                  For CRYPTO_PROTO_OFFLOAD
         |                                         |
+--------|--------+                    +-----------|-----------+
|  Ingress ipsec  |                    | Encap packet from NIC |
|        |        |                    |           |           |
| +------V------+ |                    |  +--------V--------+  |
| | HW ACC NIC  | |                    |  |     SA lookup   |  |
| +------|------+ |                    |  +--------|--------+  |
| +------V------+ |                    |  +--------V--------+  |
| |validate ESP | |                    |  |  session attach |  |
| +------|------+ |                    |  +--------|--------+  |   +------------+
| +------V------+ |                    |  +--------V--------+  |   | Hw crypto  |
| |Remove  ESP  | |                    |  |Enqueue to crypto|------>  Device    |      <--- Headers are removed by the HW device.
| | and Tunnel  | |                    |  |     Device      |  |   |            |
| +------|------+ |                    |  +-----------------+  |   +-----|------+
+--------V--------+                    |  +-----------------+  |         |
         |                             |  |  Dequeue from   |<-----------+   
+--------V----------+                  |  |  Crypto Device  |  |
|Plain packet to App|                  |  +--------|--------+  |
+--------|----------+                  |  +--------V--------+  |
                                       |  |Plain packet to  |  |
                                       |  |    app          |  |
                                       |  +-----------------+  |
                                       +-----------------------+


Akhil Goyal (1):
  RFC: rte_security: proposal

 lib/librte_security/rte_security.h | 405 +++++++++++++++++++++++++++++++++++++
 1 file changed, 405 insertions(+)
 create mode 100644 lib/librte_security/rte_security.h

-- 
2.9.3

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

* [dpdk-dev] [RFC PATCH 1/1] rte_security: proposal
  2017-07-25 11:21     ` [dpdk-dev] [RFC PATCH 0/1] IPSec Inline and look aside crypto offload Akhil Goyal
@ 2017-07-25 11:21       ` Akhil Goyal
  2017-07-26 13:46       ` [dpdk-dev] [RFC PATCH 0/1] IPSec Inline and look aside crypto offload Declan Doherty
                         ` (2 subsequent siblings)
  3 siblings, 0 replies; 37+ messages in thread
From: Akhil Goyal @ 2017-07-25 11:21 UTC (permalink / raw)
  To: dev, borisp, declan.doherty
  Cc: radu.nicolau, aviadye, sandeep.malik, hemant.agrawal,
	pablo.de.lara.guarch, Akhil Goyal

Detailed description is added in the coverletter

Signed-off-by: Akhil Goyal <akhil.goyal@nxp.com>
---
 lib/librte_security/rte_security.h | 405 +++++++++++++++++++++++++++++++++++++
 1 file changed, 405 insertions(+)
 create mode 100644 lib/librte_security/rte_security.h

diff --git a/lib/librte_security/rte_security.h b/lib/librte_security/rte_security.h
new file mode 100644
index 0000000..b46e096
--- /dev/null
+++ b/lib/librte_security/rte_security.h
@@ -0,0 +1,405 @@
+#ifndef _RTE_SECURITY_H_
+#define _RTE_SECURITY_H_
+
+/**
+ * @file rte_security.h
+ *
+ * RTE Security Common Definitions
+ *
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+#include <rte_mbuf.h>
+#include <rte_memory.h>
+#include <rte_mempool.h>
+#include <rte_common.h>
+
+#include <rte_crypto.h>
+#include <rte_cryptodev.h>
+
+/** Security Assosiation direction for IPSec */
+enum rte_security_conf_ipsec_sa_dir {
+	RTE_SECURITY_IPSEC_SA_DIR_INGRESS,
+	/**< Ingress path */
+	RTE_SECURITY_IPSEC_SA_DIR_EGRESS
+	/**< Egress path */
+};
+
+/** IPSec protocol mode */
+enum rte_security_conf_ipsec_sa_mode {
+	RTE_SECURITY_IPSEC_SA_MODE_TRANSPORT,
+	/**< IPSec Transport mode */
+	RTE_SECURITY_IPSEC_SA_MODE_TUNNEL
+	/**< IPSec Tunnel mode */
+};
+
+/** IPSec Protocol */
+enum rte_security_conf_ipsec_sa_protocol {
+	RTE_SECURITY_IPSEC_SA_PROTO_AH,
+	/**< AH protocol */
+	RTE_SECURITY_IPSEC_SA_PROTO_ESP
+	/**< ESP protocol */
+};
+
+/** IPSEC tunnel type */
+enum rte_security_ipsec_tunnel_type {
+	RTE_SECURITY_IPSEC_TUNNEL_IPV4 = 0,
+	/**< Outer header is IPv4 */
+	RTE_SECURITY_IPSEC_TUNNEL_IPV6
+	/**< Outer header is IPv6 */
+};
+
+/**
+ * IPSEC tunnel parameters
+ *
+ * These parameters are used to build outbound tunnel headers.
+ */
+struct rte_security_ipsec_tunnel_param {
+	struct rte_security_ipsec_tunnel_type type;
+	/**< Tunnel type: IPv4 or IPv6 */
+
+	union {
+		struct {
+			struct ipaddr src_ip;
+			/**< IPv4 source address */
+			struct ipaddr dst_ip;
+			/**< IPv4 destination address */
+			uint8_t dscp;
+			/**< IPv4 Differentiated Services Code Point */
+			uint8_t df;
+			/**< IPv4 Don't Fragment bit */
+			uint8_t ttl;
+			/**< IPv4 Time To Live */
+		} ipv4; /**< IPv4 header parameters */
+
+		struct {
+			struct ip6addr *src_addr;
+			/**< IPv6 source address */
+			struct ip6addr *dst_addr;
+			/**< IPv6 destination address */
+			uint8_t dscp;
+			/**< IPv6 Differentiated Services Code Point */
+			uint32_t flabel;
+			/**< IPv6 flow label */
+			uint8_t hlimit;
+			/**< IPv6 hop limit */
+		} ipv6; /**< IPv6 header parameters */
+	}; /**< Various tunnel parameters */
+};
+
+/**
+ * IPSEC SA option flags
+ */
+struct rte_security_ipsec_sa_options {
+	/** Extended Sequence Numbers (ESN)
+	  *
+	  * * 1: Use extended (64 bit) sequence numbers
+	  * * 0: Use normal sequence numbers
+	  */
+	uint32_t esn : 1;
+
+	/** UDP encapsulation
+	  *
+	  * * 1: Do UDP encapsulation/decapsulation so that IPSEC packets can
+	  *      traverse through NAT boxes.
+	  * * 0: No UDP encapsulation
+	  */
+	uint32_t udp_encap : 1;
+
+	/** Copy DSCP bits
+	  *
+	  * * 1: Copy IPv4 or IPv6 DSCP bits from inner IP header to
+	  *      the outer IP header in encapsulation, and vice versa in
+	  *      decapsulation.
+	  * * 0: Use values from odp_ipsec_tunnel_param_t in encapsulation and
+	  *      do not change DSCP field in decapsulation.
+	  */
+	uint32_t copy_dscp : 1;
+
+	/** Copy IPv6 Flow Label
+	  *
+	  * * 1: Copy IPv6 flow label from inner IPv6 header to the
+	  *      outer IPv6 header.
+	  * * 0: Use value from odp_ipsec_tunnel_param_t
+	  */
+	uint32_t copy_flabel : 1;
+
+	/** Copy IPv4 Don't Fragment bit
+	  *
+	  * * 1: Copy the DF bit from the inner IPv4 header to the outer
+	  *      IPv4 header.
+	  * * 0: Use value from odp_ipsec_tunnel_param_t
+	  */
+	uint32_t copy_df : 1;
+
+	/** Decrement inner packet Time To Live (TTL) field
+	  *
+	  * * 1: In tunnel mode, decrement inner packet IPv4 TTL or
+	  *      IPv6 Hop Limit after tunnel decapsulation, or before tunnel
+	  *      encapsulation.
+	  * * 0: Inner packet is not modified.
+	  */
+	uint32_t dec_ttl : 1;
+
+};
+
+/** IPSec Operations */
+enum rte_security_ipsec_operation {
+	RTE_SECURITY_IPSEC_OP_ENCAP,
+	/**< Encrypt and generate digest */
+	RTE_SECURITY_IPSEC_OP_DECAP
+	/**< Verify digest and decrypt */
+};
+
+/**
+ * IPSec Setup Data.
+ *
+ * This structure contains data relating to IPSec
+ * used to create a session.
+ */
+struct rte_security_ipsec_xform {
+	enum rte_security_ipsec_operation op;
+	/**< IPSec operation - Encap or Decap */
+	enum rte_crypto_cipher_algorithm cipher_alg;
+	/**< Cipher Algorithm */
+	struct {
+		uint8_t *data;  /**< pointer to key data */
+		size_t length;   /**< key length in bytes */
+	} cipher_key;
+	enum rte_crypto_auth_algorithm auth_alg;
+	/**< Authentication Algorithm */
+	struct {
+		uint8_t *data;  /**< pointer to key data */
+		size_t length;   /**< key length in bytes */
+	} auth_key;
+	uint32_t salt;	/**< salt for this SA */
+};
+
+/** IPsec Security Session Configuration */
+struct rte_security_conf_ipsec_sa {
+	unsigned int spi;
+	/**< SA security parameter index */
+
+	enum rte_security_conf_ipsec_sa_dir sa_dir;
+	/**< IPsec SA direction - ingress / egress */
+
+	enum rte_security_conf_ipsec_sa_mode mode;
+	/**< IPsec SA Mode - transport/tunnel */
+
+	enum rte_security_conf_ipsec_sa_protocol proto;
+	/**< IPsec SA Protocol - AH/ESP */
+
+	struct rte_security_ipsec_xform *ipsec_xform;
+	/**< IPsec Transform */
+
+	struct rte_security_ipsec_tunnel_param *tunnel;
+	/**< Tunnel parameters, NULL for transport mode */
+
+	struct rte_security_ipsec_sa_options *options;
+	/**< various SA options */
+};
+
+/** IPsec Security Session Configuration */
+struct rte_security_conf_dtls {
+	/** To be Filled */
+};
+
+/** IPsec Security Session Configuration */
+struct rte_security_conf_macsec {
+	/** To be Filled */
+};
+
+/**< Security Session action type */
+enum rte_security_session_action_type {
+	RTE_SECURITY_SESS_ETH_INLINE_CRYPTO,
+	/**< Crypto operations are performed by Network interface */
+	RTE_SECURITY_SESS_ETH_PROTO_OFFLOAD,
+	/**< Crypto operations with protocol support are performed
+	 * by Network/ethernet device.
+	 */
+	RTE_SECURITY_SESS_CRYPTO_PROTO_OFFLOAD,
+	/**< Crypto operations with protocol support are performed
+	 * by Crypto device.
+	 */
+	RTE_SECURITY_SESS_NONE
+	/**< Non protocol offload. Application need to manage everything */
+};
+
+/** Security Session Protocols */
+enum rte_security_sess_protocol {
+	RTE_SEC_CONF_DTLS,
+	/**< DTLS Protocol */
+	RTE_SEC_CONF_IPSEC,
+	/**< IPSec Protocol */
+	RTE_SEC_CONF_MACSEC
+	/**< MACSec Protocol */
+};
+/**
+ * Security Session Configuration
+ */
+struct rte_security_sess_conf {
+	enum rte_security_session_action_type action_type;
+	/**< Type of action to be performed on the session */
+	enum rte_security_sess_protocol protocol;
+	/**< Security protocol to be configured */
+
+	union {
+		struct rte_security_conf_ipsec_sa ipsec_sa;
+		struct rte_security_conf_dtls dtls;
+		struct rte_security_conf_macsec macsec;
+	};
+	/**< Configuration parameters for security session */
+};
+
+struct rte_security_session {
+	__extension__ void *sess_private_data[0];
+	/**< Private session material */
+};
+
+/**
+ * Configure device(crypto/ethernet) to enable Security operations
+ *
+ * @param   dev_id    Device id on which Security operations need to be enabled
+ * @param   dev_name  Device name - crypto or ethernet device
+ * @return
+ *  - On success, zero
+ *  - On failure, a negative value.
+ */
+int
+rte_security_configure(uint16_t dev_id, char *dev_name);
+
+/**
+ * Create Security session header (generic with no private data)
+ *
+ * @param   mempool    Session mempool to allocate session objects from
+ * @return
+ *  - On success, pointer to session
+ *  - On failure, NULL
+ */
+struct rte_security_session *
+rte_security_session_create(struct rte_mempool *mempool);
+
+/**
+ * Fill out private data for the device, based on its device id and name.
+ *
+ * @param   dev_id   Device id that we want the session to be used on
+ * @param   dev_name Device name for which session is to be used
+ * @param   sess     Session where the private data will be attached to
+ * @param   conf     Security config to apply on flow
+ *                   processed with this session
+ * @param   mempool  Mempool where the private data is allocated.
+ *
+ * @return
+ *  - On success, zero.
+ *  - On failure, a negative value.
+ */
+int
+rte_security_session_init(uint16_t dev_id, char *dev_name,
+			  struct rte_security_session *sess,
+			  struct rte_security_sess_conf *conf,
+			  struct rte_mempool *mempool);
+
+/**
+ * Frees Security session header, after checking that all
+ * the device private data has been freed, returning it
+ * to its original mempool.
+ *
+ * @param   sess     Session header to be freed.
+ *
+ * @return
+ *  - 0 if successful.
+ *  - -EINVAL if session is NULL.
+ *  - -EBUSY if not all device private data has been freed.
+ */
+int
+rte_security_session_free(struct rte_security_session *sess);
+
+/**
+ * Frees private data for the device id, based on its device name,
+ * returning it to its mempool.
+ *
+ * @param   dev_id   ID of device that uses the session.
+ * @param   dev_name Name of device that uses the session.
+ * @param   sess     Session containing the reference to the private data
+ *
+ * @return
+ *  - 0 if successful.
+ *  - -EINVAL if device is invalid or session is NULL.
+ */
+int
+rte_security_session_clear(uint8_t dev_id, char *dev_name,
+			   struct rte_security_session *sess);
+
+
+/**
+ * Attach a session to a crypto operation.
+ * This API is needed only in case of RTE_SECURITY_SESS_CRYPTO_PROTO_OFFLOAD
+ * For other rte_security_session_action_type, ol_flags in rte_mbuf may be
+ * defined to perform security operations.
+ *
+ * @param	op	crypto operation
+ * @param	sess	security session
+ */
+static inline int
+rte_security_attach_session(struct rte_crypto_op *op,
+			    struct rte_security_session *sess);
+
+/**
+ * Security Capability
+ */
+struct rte_security_capability {
+	enum rte_security_sess_protocol protocol;
+	RTE_STD_C11
+	union {
+		struct {
+			enum rte_crypto_auth_algorithm algo;
+			/**< authentication algorithm */
+			enum rte_crypto_cipher_algorithm algo;
+			/**< cipher algorithm */
+			uint16_t block_size;
+			/**< algorithm block size */
+			struct rte_crypto_param_range c_key_size;
+			/**< cipher key size range */
+			struct rte_crypto_param_range a_key_size;
+			/**< auth key size range */
+			struct rte_crypto_param_range digest_size;
+			/**< digest size range */
+			struct rte_crypto_param_range iv_size;
+			/**< Initialisation vector data size range */
+		} ipsec;
+		/**< IPSEC transform capabilities */
+		struct {
+			/* To be Filled */
+		} dtls;
+		/**< DTLS transform capabilities */
+		struct {
+			/* To be Filled */
+		} macsec;
+		/**< MACSEC transform capabilities */
+	};
+};
+
+/**
+ *  Provide capabilities available for defined device and algorithm
+ *
+ * @param	dev_id		The identifier of the device.
+ * @param	dev_name	Device name for which capability is needed
+ * @param	protocol	Protocol for which capability is required
+ *
+ * @return
+ *   - Return description of the security capability if exist.
+ *   - Return NULL if the capability not exist.
+ */
+const struct rte_security_capability *
+rte_security_capability_get(uint8_t dev_id, char *dev_name,
+		enum rte_security_sess_protocol protocol);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _RTE_SECURITY_H_ */
-- 
2.9.3

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

* Re: [dpdk-dev] [RFC PATCH 0/1] IPSec Inline and look aside crypto offload
  2017-07-25 11:21     ` [dpdk-dev] [RFC PATCH 0/1] IPSec Inline and look aside crypto offload Akhil Goyal
  2017-07-25 11:21       ` [dpdk-dev] [RFC PATCH 1/1] rte_security: proposal Akhil Goyal
@ 2017-07-26 13:46       ` Declan Doherty
  2017-08-02 13:16         ` Hemant Agrawal
  2017-08-15  6:35       ` [dpdk-dev] [RFC PATCH v2 0/4] " Akhil Goyal
  2017-08-29 14:49       ` [dpdk-dev] [RFC PATCH 0/1] IPSec Inline and look aside crypto offload Thomas Monjalon
  3 siblings, 1 reply; 37+ messages in thread
From: Declan Doherty @ 2017-07-26 13:46 UTC (permalink / raw)
  To: Akhil Goyal, dev, borisp
  Cc: radu.nicolau, aviadye, sandeep.malik, hemant.agrawal,
	pablo.de.lara.guarch

Hey Akhil, I like the proposal of allowing the rte_secruity API to be 
supported on both NIC and crypto devices as I think it allows us to 
cover all the protocol offload scenarios in a consist manner.

The main concern I have is in regards to the device identification in a 
consistent manner between device types, and I'm not exactly clear from 
your description below on how you want to do that, as the dev_id and 
port_id can overlap.

If we follow this model, I think it would a good time to introduce a 
sudo UUID into each device in DPDK, not necessarily a 16 byte UUID but I 
think a unit16_t or uint32_t would be more than sufficient for DPDK 
needs. As we now have a common rte_device structure in all device types, 
we can add the UUID here, and then allow common APIs like this to use 
the UUID as the key. We could also then support some generic device APIs 
such as:

uuid_t rte_device_get_uuid_by_name(char *dev_name);

uuid_t rte_ethdev_get_port_uuid(uint8_t pid);
uuid_t rte_cryptodev_get_device_uuid(uint8_t pid);

Which will allow easy retrieval handle to use in the rte_security APIs.

Also I don't know if we need all the semantic of the cryptodev API in 
regards the way sessions are managed as I these security sessions are 
implicitly linked to hardware there isn't any need to support moving 
session between devices?

int rte_security_configure(uuid_t uuid, struct rte_mempool *mempool);

struct rte_security_session *sess
rte_security_session_create(uuid_t uuid,
			struct rte_security_sess_conf *conf);


On 25/07/2017 12:21 PM, Akhil Goyal wrote:
> Below is a counter proposal for the RFC sent by Boris.
> If we find some consensus, we can have implementation for this proposal in a few weeks.
>
> The proposal is largely inline with the thoughts from Declan with a few exceptions.
> Here we are proposing a security framework which can be used both by crypto drivers
> and the hw offloaded NIC to showcase the protocol offload support as well as inline
> ipsec in hw offloaded NIC.
>
> The placement of the rte_security.X can either be a separate library like
> lib/librte_security/ or it can be taken as an extension to the lib/librte_cryptodev/.
> The reason for placing this in the cryptodev is that we are referring to some
> crypto enums and the APIs look similar to that of cryptodev.
>
> Here we propose that the application may be able to configure either NIC or
> crypto PMD to perform IPSec and other security operations.
> This is configured using the API
>
> int
> rte_security_configure(uint16_t dev_id, char *dev_name);
>
> This API take dev_id and dev_name to identify which device needs to perform security
> operation. Once the device is enabled for Security operations, the application can
> create and initialize the session for the enabled device.
>
> struct rte_security_session *
> rte_security_session_create(struct rte_mempool *mempool);
>
> int
> rte_security_session_init(uint16_t dev_id, char *dev_name,
>                           struct rte_security_session *sess,
>                           struct rte_security_sess_conf *conf,
>                           struct rte_mempool *mempool);
>
> These two APIs are similar to the rte_cryptodev_sym_session_create and
> rte_cryptodev_sym_session_init respectively, except that rte_security_session_init
> takes device name also to identify between the NIC(IPSEC inline or full offload)
> or crypto(look aside protocol offload).
>
> These sessions can be cleared and freed with the APIs
>
> int
> rte_security_session_clear(uint8_t dev_id, char *dev_name,
>                            struct rte_security_session *sess);
> int
> rte_security_session_free(struct rte_security_session *sess);
>
> The details for various structures used are mentioned in the below patch.
> These are very similar to what Declan proposed with a few additions.
> This can be updated further for other security protocols like MACSec and DTLS
>
> Now, after the application configures the session using above APIs, it needs to
> attach the  session with the crypto_op in case the session is configured for
> crypto look aside protocol offload. For IPSec inline/ full protocol offload
> using NIC, the mbuf ol_flags can be set as per the RFC suggested by Boris.
>
> Configuration path for both crypto and NIC can be illustrated as below
>
>   Configuration Path                       Configuration Path
>        for NIC                                  for Crypto
>           |                                         |
>  +--------|--------+                       +--------|--------+
>  |    Add/Remove   |                       |   Add/Remove    |
>  |     IPsec SA    |                       |    IPSec SA     |
>  |        |        |                       |        |        |
>  |--------|--------|                       +--------|--------+
>           |                                         |
>  +--------V--------+                                |
>  |   Flow API      |                                |
>  +--------|--------+                                |
>           |                                         |
>  +--------V--------+                       +--------V--------+
>  |                 |                       |                 |
>  |     NIC PMD     |                       |    Crypto PMD   |
>  |                 |                       |                 |
>  +--------|--------+                       +--------|--------+
>           |                                         |
>  +--------|--------+                       +--------|--------+
>  |  HW ACCELERATED |                       |     HW Crypto   |
>  |        NIC      |                       |  Protocol Aware |
>  |                 |                       |     Device      |
>  +--------|--------+                       +--------|--------+
>
>
> Now the application(ipsec-secgw) have 4 paths to decide for the data path.
> 1. Non-protocol offload (currently implemented)
> 2. IPSec inline(only crypto operations using NIC)
> 3. full protocol offload(crypto operations along with all the IPsec header
>    and trailer processing using NIC)
> 4. look aside protocol offload(single-pass encryption and authentication with
>    additional levels of protocol processing offload using crypto device)
>
> The application can decide using the below action types
> enum rte_security_session_action_type {
>         RTE_SECURITY_SESS_ETH_INLINE_CRYPTO,
>         /**< Crypto operations are performed by Network interface */
>         RTE_SECURITY_SESS_ETH_PROTO_OFFLOAD,
>         /**< Crypto operations with protocol support are performed
>          * by Network/ethernet device.
>          */
>         RTE_SECURITY_SESS_CRYPTO_PROTO_OFFLOAD,
>         /**< Crypto operations with protocol support are performed
>          * by Crypto device.
>          */
>         RTE_SECURITY_SESS_NONE
> 	/**< Non protocol offload. Application need to manage everything */
> };
>
>
>  Egress Data Path
>
> For ETH_INLINE_CRYPTO                  For CRYPTO_PROTO_OFFLOAD
>          |                                         |
> +--------|--------+                    +-----------|-----------+
> |  egress IPsec   |                    | Plain packet from NIC |
> |        |        |                    |           |           |
> | +------V------+ |                    |  +--------V--------+  |
> | | SABD lookup | |                    |  |    SA lookup    |  |
> | +------|------+ |                    |  +--------|--------+  |
> | +------V------+ |                    |  +--------V--------+  |
> | |   Tunnel    | |                    |  |  session attach |  |
> | +------|------+ |                    |  +--------|--------+  |   +------------+
> | +------V------+ |                    |  +--------V--------+  |   | Hw crypto  |
> | |     ESP     | |                    |  |Enqueue to crypto|------>  Device    |      <--- Headers are added by the HW device.
> | |             | |                    |  |     Device      |  |   |            |
> | +------|------+ |                    |  +-----------------+  |   +-----|------+
> +--------V--------+                    |  +-----------------+  |         |
>          |                             |  |  Dequeue from   |<-----------+
> +--------V--------+                    |  |  Crypto Device  |  |
> |    L2 Stack     |                    |  +--------|--------+  |
> +--------|--------+                    |  +--------V--------+  |
>          |                             |  |   L2 Stack      |  |
> +--------V--------+                    |  +--------|--------+  |
> |                 |                    +-----------|-----------+
> |     NIC PMD     |                                |
> |                 |                    +-----------V-----------+
> +--------|--------+                    |        NIC PMD        |
>          |                             |   (packet sent out)   |
> +--------|--------+                    +-----------|-----------+
> |  HW ACCELERATED |
> |        NIC      |
> |                 |
> +--------|--------+
>
>    Ingress Data Path
>
> For ETH_INLINE_CRYPTO                  For CRYPTO_PROTO_OFFLOAD
>          |                                         |
> +--------|--------+                    +-----------|-----------+
> |  Ingress ipsec  |                    | Encap packet from NIC |
> |        |        |                    |           |           |
> | +------V------+ |                    |  +--------V--------+  |
> | | HW ACC NIC  | |                    |  |     SA lookup   |  |
> | +------|------+ |                    |  +--------|--------+  |
> | +------V------+ |                    |  +--------V--------+  |
> | |validate ESP | |                    |  |  session attach |  |
> | +------|------+ |                    |  +--------|--------+  |   +------------+
> | +------V------+ |                    |  +--------V--------+  |   | Hw crypto  |
> | |Remove  ESP  | |                    |  |Enqueue to crypto|------>  Device    |      <--- Headers are removed by the HW device.
> | | and Tunnel  | |                    |  |     Device      |  |   |            |
> | +------|------+ |                    |  +-----------------+  |   +-----|------+
> +--------V--------+                    |  +-----------------+  |         |
>          |                             |  |  Dequeue from   |<-----------+
> +--------V----------+                  |  |  Crypto Device  |  |
> |Plain packet to App|                  |  +--------|--------+  |
> +--------|----------+                  |  +--------V--------+  |
>                                        |  |Plain packet to  |  |
>                                        |  |    app          |  |
>                                        |  +-----------------+  |
>                                        +-----------------------+
>
>
> Akhil Goyal (1):
>   RFC: rte_security: proposal
>
>  lib/librte_security/rte_security.h | 405 +++++++++++++++++++++++++++++++++++++
>  1 file changed, 405 insertions(+)
>  create mode 100644 lib/librte_security/rte_security.h
>

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

* Re: [dpdk-dev] [RFC PATCH 0/1] IPSec Inline and look aside crypto offload
  2017-07-26 13:46       ` [dpdk-dev] [RFC PATCH 0/1] IPSec Inline and look aside crypto offload Declan Doherty
@ 2017-08-02 13:16         ` Hemant Agrawal
  2017-08-03 11:25           ` Akhil Goyal
  0 siblings, 1 reply; 37+ messages in thread
From: Hemant Agrawal @ 2017-08-02 13:16 UTC (permalink / raw)
  To: Declan Doherty, Akhil Goyal, dev, borisp
  Cc: radu.nicolau, aviadye, sandeep.malik, pablo.de.lara.guarch

Hi Declan,

On 7/26/2017 7:16 PM, Declan Doherty wrote:
> Hey Akhil, I like the proposal of allowing the rte_secruity API to be
> supported on both NIC and crypto devices as I think it allows us to
> cover all the protocol offload scenarios in a consist manner.
>
> The main concern I have is in regards to the device identification in a
> consistent manner between device types, and I'm not exactly clear from
> your description below on how you want to do that, as the dev_id and
> port_id can overlap.
>
> If we follow this model, I think it would a good time to introduce a
> sudo UUID into each device in DPDK, not necessarily a 16 byte UUID but I
> think a unit16_t or uint32_t would be more than sufficient for DPDK
> needs. As we now have a common rte_device structure in all device types,
> we can add the UUID here, and then allow common APIs like this to use
> the UUID as the key. We could also then support some generic device APIs
> such as:
>
> uuid_t rte_device_get_uuid_by_name(char *dev_name);
>
> uuid_t rte_ethdev_get_port_uuid(uint8_t pid);
> uuid_t rte_cryptodev_get_device_uuid(uint8_t pid);
>
> Which will allow easy retrieval handle to use in the rte_security APIs.
>
> Also I don't know if we need all the semantic of the cryptodev API in
> regards the way sessions are managed as I these security sessions are
> implicitly linked to hardware there isn't any need to support moving
> session between devices?
>
> int rte_security_configure(uuid_t uuid, struct rte_mempool *mempool);
>
> struct rte_security_session *sess
> rte_security_session_create(uuid_t uuid,
>             struct rte_security_sess_conf *conf);
>

Thanks for the comment.  The uuid idea is good, we should work on it.
But this work can be started without uuid as well. the port and platform 
type shall be able to help identifying the destination.

We shall do it in next phase.

>
> On 25/07/2017 12:21 PM, Akhil Goyal wrote:
>> Below is a counter proposal for the RFC sent by Boris.
>> If we find some consensus, we can have implementation for this
>> proposal in a few weeks.
>>
>> The proposal is largely inline with the thoughts from Declan with a
>> few exceptions.
>> Here we are proposing a security framework which can be used both by
>> crypto drivers
>> and the hw offloaded NIC to showcase the protocol offload support as
>> well as inline
>> ipsec in hw offloaded NIC.
>>
>> The placement of the rte_security.X can either be a separate library like
>> lib/librte_security/ or it can be taken as an extension to the
>> lib/librte_cryptodev/.
>> The reason for placing this in the cryptodev is that we are referring
>> to some
>> crypto enums and the APIs look similar to that of cryptodev.
>>
>> Here we propose that the application may be able to configure either
>> NIC or
>> crypto PMD to perform IPSec and other security operations.
>> This is configured using the API
>>
>> int
>> rte_security_configure(uint16_t dev_id, char *dev_name);
>>
>> This API take dev_id and dev_name to identify which device needs to
>> perform security
>> operation. Once the device is enabled for Security operations, the
>> application can
>> create and initialize the session for the enabled device.
>>
>> struct rte_security_session *
>> rte_security_session_create(struct rte_mempool *mempool);
>>
>> int
>> rte_security_session_init(uint16_t dev_id, char *dev_name,
>>                           struct rte_security_session *sess,
>>                           struct rte_security_sess_conf *conf,
>>                           struct rte_mempool *mempool);
>>
>> These two APIs are similar to the rte_cryptodev_sym_session_create and
>> rte_cryptodev_sym_session_init respectively, except that
>> rte_security_session_init
>> takes device name also to identify between the NIC(IPSEC inline or
>> full offload)
>> or crypto(look aside protocol offload).
>>
>> These sessions can be cleared and freed with the APIs
>>
>> int
>> rte_security_session_clear(uint8_t dev_id, char *dev_name,
>>                            struct rte_security_session *sess);
>> int
>> rte_security_session_free(struct rte_security_session *sess);
>>
>> The details for various structures used are mentioned in the below patch.
>> These are very similar to what Declan proposed with a few additions.
>> This can be updated further for other security protocols like MACSec
>> and DTLS
>>
>> Now, after the application configures the session using above APIs, it
>> needs to
>> attach the  session with the crypto_op in case the session is
>> configured for
>> crypto look aside protocol offload. For IPSec inline/ full protocol
>> offload
>> using NIC, the mbuf ol_flags can be set as per the RFC suggested by
>> Boris.
>>
>> Configuration path for both crypto and NIC can be illustrated as below
>>
>>   Configuration Path                       Configuration Path
>>        for NIC                                  for Crypto
>>           |                                         |
>>  +--------|--------+                       +--------|--------+
>>  |    Add/Remove   |                       |   Add/Remove    |
>>  |     IPsec SA    |                       |    IPSec SA     |
>>  |        |        |                       |        |        |
>>  |--------|--------|                       +--------|--------+
>>           |                                         |
>>  +--------V--------+                                |
>>  |   Flow API      |                                |
>>  +--------|--------+                                |
>>           |                                         |
>>  +--------V--------+                       +--------V--------+
>>  |                 |                       |                 |
>>  |     NIC PMD     |                       |    Crypto PMD   |
>>  |                 |                       |                 |
>>  +--------|--------+                       +--------|--------+
>>           |                                         |
>>  +--------|--------+                       +--------|--------+
>>  |  HW ACCELERATED |                       |     HW Crypto   |
>>  |        NIC      |                       |  Protocol Aware |
>>  |                 |                       |     Device      |
>>  +--------|--------+                       +--------|--------+
>>
>>
>> Now the application(ipsec-secgw) have 4 paths to decide for the data
>> path.
>> 1. Non-protocol offload (currently implemented)
>> 2. IPSec inline(only crypto operations using NIC)
>> 3. full protocol offload(crypto operations along with all the IPsec
>> header
>>    and trailer processing using NIC)
>> 4. look aside protocol offload(single-pass encryption and
>> authentication with
>>    additional levels of protocol processing offload using crypto device)
>>
>> The application can decide using the below action types
>> enum rte_security_session_action_type {
>>         RTE_SECURITY_SESS_ETH_INLINE_CRYPTO,
>>         /**< Crypto operations are performed by Network interface */
>>         RTE_SECURITY_SESS_ETH_PROTO_OFFLOAD,
>>         /**< Crypto operations with protocol support are performed
>>          * by Network/ethernet device.
>>          */
>>         RTE_SECURITY_SESS_CRYPTO_PROTO_OFFLOAD,
>>         /**< Crypto operations with protocol support are performed
>>          * by Crypto device.
>>          */
>>         RTE_SECURITY_SESS_NONE
>>     /**< Non protocol offload. Application need to manage everything */
>> };
>>
>>
>>  Egress Data Path
>>
>> For ETH_INLINE_CRYPTO                  For CRYPTO_PROTO_OFFLOAD
>>          |                                         |
>> +--------|--------+                    +-----------|-----------+
>> |  egress IPsec   |                    | Plain packet from NIC |
>> |        |        |                    |           |           |
>> | +------V------+ |                    |  +--------V--------+  |
>> | | SABD lookup | |                    |  |    SA lookup    |  |
>> | +------|------+ |                    |  +--------|--------+  |
>> | +------V------+ |                    |  +--------V--------+  |
>> | |   Tunnel    | |                    |  |  session attach |  |
>> | +------|------+ |                    |  +--------|--------+  |
>> +------------+
>> | +------V------+ |                    |  +--------V--------+  |   |
>> Hw crypto  |
>> | |     ESP     | |                    |  |Enqueue to crypto|------>
>> Device    |      <--- Headers are added by the HW device.
>> | |             | |                    |  |     Device      |  |
>> |            |
>> | +------|------+ |                    |  +-----------------+  |
>> +-----|------+
>> +--------V--------+                    |  +-----------------+
>> |         |
>>          |                             |  |  Dequeue from
>> |<-----------+
>> +--------V--------+                    |  |  Crypto Device  |  |
>> |    L2 Stack     |                    |  +--------|--------+  |
>> +--------|--------+                    |  +--------V--------+  |
>>          |                             |  |   L2 Stack      |  |
>> +--------V--------+                    |  +--------|--------+  |
>> |                 |                    +-----------|-----------+
>> |     NIC PMD     |                                |
>> |                 |                    +-----------V-----------+
>> +--------|--------+                    |        NIC PMD        |
>>          |                             |   (packet sent out)   |
>> +--------|--------+                    +-----------|-----------+
>> |  HW ACCELERATED |
>> |        NIC      |
>> |                 |
>> +--------|--------+
>>
>>    Ingress Data Path
>>
>> For ETH_INLINE_CRYPTO                  For CRYPTO_PROTO_OFFLOAD
>>          |                                         |
>> +--------|--------+                    +-----------|-----------+
>> |  Ingress ipsec  |                    | Encap packet from NIC |
>> |        |        |                    |           |           |
>> | +------V------+ |                    |  +--------V--------+  |
>> | | HW ACC NIC  | |                    |  |     SA lookup   |  |
>> | +------|------+ |                    |  +--------|--------+  |
>> | +------V------+ |                    |  +--------V--------+  |
>> | |validate ESP | |                    |  |  session attach |  |
>> | +------|------+ |                    |  +--------|--------+  |
>> +------------+
>> | +------V------+ |                    |  +--------V--------+  |   |
>> Hw crypto  |
>> | |Remove  ESP  | |                    |  |Enqueue to crypto|------>
>> Device    |      <--- Headers are removed by the HW device.
>> | | and Tunnel  | |                    |  |     Device      |  |
>> |            |
>> | +------|------+ |                    |  +-----------------+  |
>> +-----|------+
>> +--------V--------+                    |  +-----------------+
>> |         |
>>          |                             |  |  Dequeue from
>> |<-----------+
>> +--------V----------+                  |  |  Crypto Device  |  |
>> |Plain packet to App|                  |  +--------|--------+  |
>> +--------|----------+                  |  +--------V--------+  |
>>                                        |  |Plain packet to  |  |
>>                                        |  |    app          |  |
>>                                        |  +-----------------+  |
>>                                        +-----------------------+
>>
>>
>> Akhil Goyal (1):
>>   RFC: rte_security: proposal
>>
>>  lib/librte_security/rte_security.h | 405
>> +++++++++++++++++++++++++++++++++++++
>>  1 file changed, 405 insertions(+)
>>  create mode 100644 lib/librte_security/rte_security.h
>>
>
>

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

* Re: [dpdk-dev] [RFC PATCH 0/1] IPSec Inline and look aside crypto offload
  2017-08-02 13:16         ` Hemant Agrawal
@ 2017-08-03 11:25           ` Akhil Goyal
  0 siblings, 0 replies; 37+ messages in thread
From: Akhil Goyal @ 2017-08-03 11:25 UTC (permalink / raw)
  To: Hemant Agrawal, Declan Doherty, dev, borisp
  Cc: radu.nicolau, aviadye, sandeep.malik, pablo.de.lara.guarch

On 8/2/2017 6:46 PM, Hemant Agrawal wrote:
> Hi Declan,
> 
> On 7/26/2017 7:16 PM, Declan Doherty wrote:
>> Hey Akhil, I like the proposal of allowing the rte_secruity API to be
>> supported on both NIC and crypto devices as I think it allows us to
>> cover all the protocol offload scenarios in a consist manner.
>>
>> The main concern I have is in regards to the device identification in a
>> consistent manner between device types, and I'm not exactly clear from
>> your description below on how you want to do that, as the dev_id and
>> port_id can overlap.
>>
>> If we follow this model, I think it would a good time to introduce a
>> sudo UUID into each device in DPDK, not necessarily a 16 byte UUID but I
>> think a unit16_t or uint32_t would be more than sufficient for DPDK
>> needs. As we now have a common rte_device structure in all device types,
>> we can add the UUID here, and then allow common APIs like this to use
>> the UUID as the key. We could also then support some generic device APIs
>> such as:
>>
>> uuid_t rte_device_get_uuid_by_name(char *dev_name);
>>
>> uuid_t rte_ethdev_get_port_uuid(uint8_t pid);
>> uuid_t rte_cryptodev_get_device_uuid(uint8_t pid);
>>
>> Which will allow easy retrieval handle to use in the rte_security APIs.
>>
>> Also I don't know if we need all the semantic of the cryptodev API in
>> regards the way sessions are managed as I these security sessions are
>> implicitly linked to hardware there isn't any need to support moving
>> session between devices?
>>
>> int rte_security_configure(uuid_t uuid, struct rte_mempool *mempool);
>>
>> struct rte_security_session *sess
>> rte_security_session_create(uuid_t uuid,
>>             struct rte_security_sess_conf *conf);
>>
> 
> Thanks for the comment.  The uuid idea is good, we should work on it.
> But this work can be started without uuid as well. the port and platform 
> type shall be able to help identifying the destination.
> 
> We shall do it in next phase.

On another thought, we can do away with dev_name for the rte_security 
APIs. rte_security APIs can configure crypto/NIC based on the 
action_type which the application provides. If it uses 
RTE_SECURITY_SESS_CRYPTO_PROTO_OFFLOAD, then crypto device is configured 
else for other cases, it will configure NIC device.

>>> Now the application(ipsec-secgw) have 4 paths to decide for the data
>>> path.
>>> 1. Non-protocol offload (currently implemented)
>>> 2. IPSec inline(only crypto operations using NIC)
>>> 3. full protocol offload(crypto operations along with all the IPsec
>>> header
>>>    and trailer processing using NIC)
>>> 4. look aside protocol offload(single-pass encryption and
>>> authentication with
>>>    additional levels of protocol processing offload using crypto device)
>>>
>>> The application can decide using the below action types
>>> enum rte_security_session_action_type {
>>>         RTE_SECURITY_SESS_ETH_INLINE_CRYPTO,
>>>         /**< Crypto operations are performed by Network interface */
>>>         RTE_SECURITY_SESS_ETH_PROTO_OFFLOAD,
>>>         /**< Crypto operations with protocol support are performed
>>>          * by Network/ethernet device.
>>>          */
>>>         RTE_SECURITY_SESS_CRYPTO_PROTO_OFFLOAD,
>>>         /**< Crypto operations with protocol support are performed
>>>          * by Crypto device.
>>>          */
>>>         RTE_SECURITY_SESS_NONE
>>>     /**< Non protocol offload. Application need to manage everything */
>>> };
>>>


Also there would be one more structure required to add the security 
operations into rte_cryptodev or rte_eth_dev

struct rte_security_ops {
	security_configure_session_t session_configure;
	/**< Configure a Security session. */
	security_free_session_t session_clear;
	/**< Clear a security sessions private data. */
	....
}

And the rte_security_capability can be added in the 
rte_eth_dev_info/rte_cryptodev_info



- Akhil

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

* [dpdk-dev] [RFC PATCH v2 0/4] IPSec Inline and look aside crypto offload
  2017-07-25 11:21     ` [dpdk-dev] [RFC PATCH 0/1] IPSec Inline and look aside crypto offload Akhil Goyal
  2017-07-25 11:21       ` [dpdk-dev] [RFC PATCH 1/1] rte_security: proposal Akhil Goyal
  2017-07-26 13:46       ` [dpdk-dev] [RFC PATCH 0/1] IPSec Inline and look aside crypto offload Declan Doherty
@ 2017-08-15  6:35       ` Akhil Goyal
  2017-08-15  6:35         ` [dpdk-dev] [RFC PATCH 1/4] rte_security: API definitions Akhil Goyal
                           ` (3 more replies)
  2017-08-29 14:49       ` [dpdk-dev] [RFC PATCH 0/1] IPSec Inline and look aside crypto offload Thomas Monjalon
  3 siblings, 4 replies; 37+ messages in thread
From: Akhil Goyal @ 2017-08-15  6:35 UTC (permalink / raw)
  To: dev, declan.doherty, thomas, radu.nicolau, aviadye, borisp,
	pablo.de.lara.guarch, sergio.gonzalez.monroy
  Cc: hemant.agrawal, sandeep.malik, Akhil Goyal

This patchet showcases the definition and usage of the rte_security
APIs described in the RFC v1 sent earlier.

The data path and configuration path is similar to what was proposed in
version 1. However, rte_security_configure API is removed, as it looked
redundant.

Also the rte_security.x files are placed inside the lib/librte_cryptodev/
as the APIs are defined with the help of crypto APIs and it makes more sense
to extend the cryptodev library instead of a separate library which perform
similar actions.

Some of the parameters of the APIs are also modified for better usability.
The parameter ``dev_name`` is removed as the appropriate device(crypto/eth)
can be obtained by using the action type.

The patchset is still in work in progress state and there may be some changes
and cleanup in the next version. This is just to enable others to work
in parallel on the crypto offloading using ethernet devices.

This patchset include the definition of rte_security APIs in patch 1,
changes required in cryptodev in patch 2, sample driver implementation
in patch 3 and ipsec-secgw application changes in patch 4.

Akhil Goyal (4):
  RFC2: rte_security: API definitions
  cryptodev: entend cryptodev to support security APIs
  crypto/dpaa2_sec: add support for protocol offload ipsec
  example/ipsec-secgw: add support for offloading crypto op

 drivers/crypto/dpaa2_sec/dpaa2_sec_dpseci.c | 368 ++++++++++++++++++++++++-
 drivers/crypto/dpaa2_sec/dpaa2_sec_priv.h   |  33 +++
 examples/ipsec-secgw/ipsec.c                | 125 ++++++---
 examples/ipsec-secgw/ipsec.h                |  13 +-
 examples/ipsec-secgw/sa.c                   | 142 +++++++---
 lib/librte_cryptodev/Makefile               |   3 +-
 lib/librte_cryptodev/rte_crypto_sym.h       |  15 +
 lib/librte_cryptodev/rte_cryptodev.h        |  20 +-
 lib/librte_cryptodev/rte_cryptodev_pmd.h    |  35 +++
 lib/librte_cryptodev/rte_security.c         | 171 ++++++++++++
 lib/librte_cryptodev/rte_security.h         | 409 ++++++++++++++++++++++++++++
 11 files changed, 1243 insertions(+), 91 deletions(-)
 create mode 100644 lib/librte_cryptodev/rte_security.c
 create mode 100644 lib/librte_cryptodev/rte_security.h

-- 
2.9.3

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

* [dpdk-dev] [RFC PATCH 1/4] rte_security: API definitions
  2017-08-15  6:35       ` [dpdk-dev] [RFC PATCH v2 0/4] " Akhil Goyal
@ 2017-08-15  6:35         ` Akhil Goyal
  2017-08-15 11:04           ` Radu Nicolau
  2017-08-15  6:35         ` [dpdk-dev] [RFC PATCH 2/4] cryptodev: entend cryptodev to support security APIs Akhil Goyal
                           ` (2 subsequent siblings)
  3 siblings, 1 reply; 37+ messages in thread
From: Akhil Goyal @ 2017-08-15  6:35 UTC (permalink / raw)
  To: dev, declan.doherty, thomas, radu.nicolau, aviadye, borisp,
	pablo.de.lara.guarch, sergio.gonzalez.monroy
  Cc: hemant.agrawal, sandeep.malik, Akhil Goyal

Detailed description is added in the coverletter

Signed-off-by: Akhil Goyal <akhil.goyal@nxp.com>
---
 lib/librte_cryptodev/rte_security.c | 171 +++++++++++++++
 lib/librte_cryptodev/rte_security.h | 409 ++++++++++++++++++++++++++++++++++++
 2 files changed, 580 insertions(+)
 create mode 100644 lib/librte_cryptodev/rte_security.c
 create mode 100644 lib/librte_cryptodev/rte_security.h

diff --git a/lib/librte_cryptodev/rte_security.c b/lib/librte_cryptodev/rte_security.c
new file mode 100644
index 0000000..7c73c93
--- /dev/null
+++ b/lib/librte_cryptodev/rte_security.c
@@ -0,0 +1,171 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright 2017 NXP.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of NXP nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <rte_log.h>
+#include <rte_debug.h>
+#include <rte_dev.h>
+#include <rte_memory.h>
+#include <rte_memcpy.h>
+#include <rte_launch.h>
+#include <rte_common.h>
+#include <rte_mempool.h>
+#include <rte_malloc.h>
+#include <rte_errno.h>
+
+#include "rte_crypto.h"
+#include "rte_cryptodev_pmd.h"
+#include "rte_security.h"
+#include "rte_ethdev.h"
+#include "rte_cryptodev.h"
+
+
+struct rte_security_session *
+rte_security_session_create(struct rte_mempool *mp)
+{
+	struct rte_security_session *sess;
+
+	/* Allocate a session structure from the session pool */
+	if (rte_mempool_get(mp, (void *)&sess)) {
+		CDEV_LOG_ERR("couldn't get object from session mempool");
+		return NULL;
+	}
+
+	/* Clear device session pointer */
+	memset(sess, 0, (sizeof(void *) *
+		RTE_MAX(rte_eth_dev_count(), rte_cryptodev_count())));
+
+	return sess;
+}
+
+int
+rte_security_session_init(uint16_t dev_id,
+			  struct rte_security_session *sess,
+			  struct rte_security_sess_conf *conf,
+			  struct rte_mempool *mp)
+{
+	struct rte_cryptodev *cdev = NULL;
+	struct rte_eth_dev *dev = NULL;
+	uint8_t index;
+	int ret;
+
+	if (sess == NULL || conf == NULL)
+		return -EINVAL;
+
+	switch (conf->action_type) {
+	case RTE_SECURITY_SESS_CRYPTO_PROTO_OFFLOAD:
+		if (!rte_cryptodev_pmd_is_valid_dev(dev_id))
+			return -EINVAL;
+		cdev = rte_cryptodev_pmd_get_dev(dev_id);
+		index = cdev->driver_id;
+		if (sess->sess_private_data[index] == NULL) {
+			ret = cdev->sec_ops->session_configure(cdev, conf, sess, mp);
+			if (ret < 0) {
+				CDEV_LOG_ERR(
+					"cdev_id %d failed to configure session details",
+					dev_id);
+				return ret;
+			}
+		}
+		break;
+	case RTE_SECURITY_SESS_ETH_INLINE_CRYPTO:
+	case RTE_SECURITY_SESS_ETH_PROTO_OFFLOAD:
+		dev = &rte_eth_devices[dev_id];
+		index = dev->data->port_id;
+		if (sess->sess_private_data[index] == NULL) {
+//			ret = dev->sec_ops->session_configure(dev, conf, sess, mp);
+//			if (ret < 0) {
+//				CDEV_LOG_ERR(
+//					"dev_id %d failed to configure session details",
+//					dev_id);
+//				return ret;
+//			}
+		}
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+int
+rte_security_session_free(struct rte_security_session *sess)
+{
+	uint8_t i, nb_drivers = RTE_MAX(rte_eth_dev_count(),
+					rte_cryptodev_count());
+	void *sess_priv;
+	struct rte_mempool *sess_mp;
+
+	if (sess == NULL)
+		return -EINVAL;
+
+	/* Check that all device private data has been freed */
+	for (i = 0; i < nb_drivers; i++) {
+		sess_priv = get_sec_session_private_data(sess, i);
+		if (sess_priv != NULL)
+			return -EBUSY;
+	}
+
+	/* Return session to mempool */
+	sess_mp = rte_mempool_from_obj(sess);
+	rte_mempool_put(sess_mp, sess);
+
+	return 0;
+}
+
+int
+rte_security_session_clear(uint8_t dev_id,
+		enum rte_security_session_action_type action_type,
+		struct rte_security_session *sess)
+{
+	struct rte_cryptodev *cdev = NULL;
+	struct rte_eth_dev *dev = NULL;
+	switch (action_type) {
+	case RTE_SECURITY_SESS_CRYPTO_PROTO_OFFLOAD:
+		cdev =  rte_cryptodev_pmd_get_dev(dev_id);
+		if (cdev == NULL || sess == NULL)
+			return -EINVAL;
+		cdev->sec_ops->session_clear(cdev, sess);
+		break;
+	case RTE_SECURITY_SESS_ETH_INLINE_CRYPTO:
+	case RTE_SECURITY_SESS_ETH_PROTO_OFFLOAD:
+		dev = &rte_eth_devices[dev_id];
+		if (dev == NULL || sess == NULL)
+			return -EINVAL;
+//		dev->dev_ops->session_clear(dev, sess);
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	return 0;
+}
diff --git a/lib/librte_cryptodev/rte_security.h b/lib/librte_cryptodev/rte_security.h
new file mode 100644
index 0000000..9747d5e
--- /dev/null
+++ b/lib/librte_cryptodev/rte_security.h
@@ -0,0 +1,409 @@
+#ifndef _RTE_SECURITY_H_
+#define _RTE_SECURITY_H_
+
+/**
+ * @file rte_security.h
+ *
+ * RTE Security Common Definitions
+ *
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <netinet/in.h>
+#include <netinet/ip.h>
+#include <netinet/ip6.h>
+
+#include <rte_mbuf.h>
+#include <rte_memory.h>
+#include <rte_mempool.h>
+#include <rte_common.h>
+#include <rte_crypto.h>
+
+/** IPSec protocol mode */
+enum rte_security_conf_ipsec_sa_mode {
+	RTE_SECURITY_IPSEC_SA_MODE_TRANSPORT,
+	/**< IPSec Transport mode */
+	RTE_SECURITY_IPSEC_SA_MODE_TUNNEL,
+	/**< IPSec Tunnel mode */
+};
+
+/** IPSec Protocol */
+enum rte_security_conf_ipsec_sa_protocol {
+	RTE_SECURITY_IPSEC_SA_PROTO_AH,
+	/**< AH protocol */
+	RTE_SECURITY_IPSEC_SA_PROTO_ESP,
+	/**< ESP protocol */
+};
+
+/** IPSEC tunnel type */
+enum rte_security_ipsec_tunnel_type {
+	RTE_SECURITY_IPSEC_TUNNEL_IPV4 = 0,
+	/**< Outer header is IPv4 */
+	RTE_SECURITY_IPSEC_TUNNEL_IPV6,
+	/**< Outer header is IPv6 */
+};
+
+/**
+ * IPSEC tunnel parameters
+ *
+ * These parameters are used to build outbound tunnel headers.
+ */
+struct rte_security_ipsec_tunnel_param {
+	enum rte_security_ipsec_tunnel_type type;
+	/**< Tunnel type: IPv4 or IPv6 */
+
+	union {
+		struct {
+			struct in_addr src_ip;
+			/**< IPv4 source address */
+			struct in_addr dst_ip;
+			/**< IPv4 destination address */
+			uint8_t dscp;
+			/**< IPv4 Differentiated Services Code Point */
+			uint8_t df;
+			/**< IPv4 Don't Fragment bit */
+			uint8_t ttl;
+			/**< IPv4 Time To Live */
+		} ipv4; /**< IPv4 header parameters */
+
+		struct {
+			struct in6_addr *src_addr;
+			/**< IPv6 source address */
+			struct in6_addr *dst_addr;
+			/**< IPv6 destination address */
+			uint8_t dscp;
+			/**< IPv6 Differentiated Services Code Point */
+			uint32_t flabel;
+			/**< IPv6 flow label */
+			uint8_t hlimit;
+			/**< IPv6 hop limit */
+		} ipv6; /**< IPv6 header parameters */
+	}; /**< Various tunnel parameters */
+};
+
+/**
+ * IPSEC SA option flags
+ */
+struct rte_security_ipsec_sa_options {
+	/** Extended Sequence Numbers (ESN)
+	  *
+	  * * 1: Use extended (64 bit) sequence numbers
+	  * * 0: Use normal sequence numbers
+	  */
+	uint32_t esn : 1;
+
+	/** UDP encapsulation
+	  *
+	  * * 1: Do UDP encapsulation/decapsulation so that IPSEC packets can
+	  *      traverse through NAT boxes.
+	  * * 0: No UDP encapsulation
+	  */
+	uint32_t udp_encap : 1;
+
+	/** Copy DSCP bits
+	  *
+	  * * 1: Copy IPv4 or IPv6 DSCP bits from inner IP header to
+	  *      the outer IP header in encapsulation, and vice versa in
+	  *      decapsulation.
+	  * * 0: Use values from odp_ipsec_tunnel_param_t in encapsulation and
+	  *      do not change DSCP field in decapsulation.
+	  */
+	uint32_t copy_dscp : 1;
+
+	/** Copy IPv6 Flow Label
+	  *
+	  * * 1: Copy IPv6 flow label from inner IPv6 header to the
+	  *      outer IPv6 header.
+	  * * 0: Use value from odp_ipsec_tunnel_param_t
+	  */
+	uint32_t copy_flabel : 1;
+
+	/** Copy IPv4 Don't Fragment bit
+	  *
+	  * * 1: Copy the DF bit from the inner IPv4 header to the outer
+	  *      IPv4 header.
+	  * * 0: Use value from odp_ipsec_tunnel_param_t
+	  */
+	uint32_t copy_df : 1;
+
+	/** Decrement inner packet Time To Live (TTL) field
+	  *
+	  * * 1: In tunnel mode, decrement inner packet IPv4 TTL or
+	  *      IPv6 Hop Limit after tunnel decapsulation, or before tunnel
+	  *      encapsulation.
+	  * * 0: Inner packet is not modified.
+	  */
+	uint32_t dec_ttl : 1;
+
+};
+
+/** IPSec Operations */
+enum rte_security_ipsec_operation {
+	RTE_SECURITY_IPSEC_OP_ENCAP,
+	/**< Encrypt and generate digest */
+	RTE_SECURITY_IPSEC_OP_DECAP,
+	/**< Verify digest and decrypt */
+};
+
+/**
+ * IPSec Setup Data.
+ *
+ * This structure contains data relating to IPSec
+ * used to create a session.
+ */
+struct rte_security_ipsec_xform {
+	enum rte_security_ipsec_operation op;
+	/**< IPSec operation - Encap or Decap */
+	unsigned int spi;
+	/**< SA security parameter index */
+	enum rte_crypto_cipher_algorithm cipher_alg;
+	/**< Cipher Algorithm */
+	struct {
+		uint8_t *data;  /**< pointer to key data */
+		size_t length;   /**< key length in bytes */
+	} cipher_key;
+	enum rte_crypto_auth_algorithm auth_alg;
+	/**< Authentication Algorithm */
+	struct {
+		uint8_t *data;  /**< pointer to key data */
+		size_t length;   /**< key length in bytes */
+	} auth_key;
+	uint32_t salt;	/**< salt for this SA */
+	enum rte_security_conf_ipsec_sa_mode mode;
+	/**< IPsec SA Mode - transport/tunnel */
+	enum rte_security_conf_ipsec_sa_protocol proto;
+	/**< IPsec SA Protocol - AH/ESP */
+	struct rte_security_ipsec_tunnel_param tunnel;
+	/**< Tunnel parameters, NULL for transport mode */
+	struct rte_security_ipsec_sa_options options;
+	/**< various SA options */
+};
+
+/** IPsec Security Session Configuration */
+struct rte_security_dtls_xform {
+	/** To be Filled */
+};
+
+/** IPsec Security Session Configuration */
+struct rte_security_macsec_xform {
+	/** To be Filled */
+};
+
+/**< Security Session action type */
+enum rte_security_session_action_type {
+	RTE_SECURITY_SESS_NONE,
+	/**< Non protocol offload. Application need to manage everything */
+	RTE_SECURITY_SESS_ETH_INLINE_CRYPTO,
+	/**< Crypto operations are performed by Network interface */
+	RTE_SECURITY_SESS_ETH_PROTO_OFFLOAD,
+	/**< Crypto operations with protocol support are performed
+	 * by Network/ethernet device.
+	 */
+	RTE_SECURITY_SESS_CRYPTO_PROTO_OFFLOAD,
+	/**< Crypto operations with protocol support are performed
+	 * by Crypto device.
+	 */
+};
+
+/** Security Session Protocols */
+enum rte_security_sess_protocol {
+	RTE_SEC_CONF_DTLS,
+	/**< DTLS Protocol */
+	RTE_SEC_CONF_IPSEC,
+	/**< IPSec Protocol */
+	RTE_SEC_CONF_MACSEC,
+	/**< MACSec Protocol */
+};
+
+/**
+ * Security Session Configuration
+ */
+struct rte_security_sess_conf {
+	enum rte_security_session_action_type action_type;
+	/**< Type of action to be performed on the session */
+	enum rte_security_sess_protocol protocol;
+	/**< Security protocol to be configured */
+
+	union {
+		struct rte_security_ipsec_xform *ipsec_xform;
+		struct rte_security_dtls_xform *dtls_xform;
+		struct rte_security_macsec_xform *macsec_xform;
+	};
+	/**< Configuration parameters for security session */
+};
+
+struct rte_security_session {
+	__extension__ void *sess_private_data[0];
+	/**< Private session material */
+};
+
+/**
+ * Create Security session header (generic with no private data)
+ *
+ * @param   mempool    Session mempool to allocate session objects from
+ * @return
+ *  - On success, pointer to session
+ *  - On failure, NULL
+ */
+struct rte_security_session *
+rte_security_session_create(struct rte_mempool *mempool);
+
+/**
+ * Fill out private data for the device, based on its device id and name.
+ *
+ * @param   dev_id   Device id that we want the session to be used on
+ * @param   dev_name Device name for which session is to be used
+ * @param   sess     Session where the private data will be attached to
+ * @param   conf     Security config to apply on flow
+ *                   processed with this session
+ * @param   mempool  Mempool where the private data is allocated.
+ *
+ * @return
+ *  - On success, zero.
+ *  - On failure, a negative value.
+ */
+int
+rte_security_session_init(uint16_t dev_id,
+			  struct rte_security_session *sess,
+			  struct rte_security_sess_conf *conf,
+			  struct rte_mempool *mempool);
+
+/**
+ * Frees Security session header, after checking that all
+ * the device private data has been freed, returning it
+ * to its original mempool.
+ *
+ * @param   sess     Session header to be freed.
+ *
+ * @return
+ *  - 0 if successful.
+ *  - -EINVAL if session is NULL.
+ *  - -EBUSY if not all device private data has been freed.
+ */
+int
+rte_security_session_free(struct rte_security_session *sess);
+
+/**
+ * Frees private data for the device id, based on its device name,
+ * returning it to its mempool.
+ *
+ * @param   dev_id	ID of device that uses the session.
+ * @param   action_type	Action type for Security operation.
+ * @param   sess	Session containing the reference to the private data
+ *
+ * @return
+ *  - 0 if successful.
+ *  - -EINVAL if device is invalid or session is NULL.
+ */
+int
+rte_security_session_clear(uint8_t dev_id,
+			   enum rte_security_session_action_type action_type,
+			   struct rte_security_session *sess);
+
+/**
+ * Attach a session to a symmetric crypto operation
+ *
+ * @param	sym_op	crypto operation
+ * @param	sess	security session
+ */
+static inline int
+__rte_security_attach_session(struct rte_crypto_sym_op *sym_op,
+			      struct rte_security_session *sess)
+{
+	sym_op->sec_session = sess;
+
+	return 0;
+}
+
+static inline void *
+get_sec_session_private_data(const struct rte_security_session *sess,
+		uint8_t driver_id) {
+	return sess->sess_private_data[driver_id];
+}
+
+static inline void
+set_sec_session_private_data(struct rte_security_session *sess,
+		uint8_t driver_id, void *private_data)
+{
+	sess->sess_private_data[driver_id] = private_data;
+}
+
+/**
+ * Attach a session to a crypto operation.
+ * This API is needed only in case of RTE_SECURITY_SESS_CRYPTO_PROTO_OFFLOAD
+ * For other rte_security_session_action_type, ol_flags in rte_mbuf may be
+ * defined to perform security operations.
+ *
+ * @param	op	crypto operation
+ * @param	sess	security session
+ */
+static inline int
+rte_security_attach_session(struct rte_crypto_op *op,
+			    struct rte_security_session *sess)
+{
+	if (unlikely(op->type != RTE_CRYPTO_OP_TYPE_SYMMETRIC))
+		return -1;
+
+	op->sess_type = RTE_CRYPTO_OP_WITH_SESSION;
+
+	return __rte_security_attach_session(op->sym, sess);
+}
+
+/**
+ * Security Capability
+ */
+struct rte_security_capabilities {
+	enum rte_security_sess_protocol protocol;
+	RTE_STD_C11
+	union {
+		struct {
+			enum rte_crypto_auth_algorithm a_algo;
+			/**< authentication algorithm */
+			enum rte_crypto_cipher_algorithm c_algo;
+			/**< cipher algorithm */
+			uint16_t block_size;
+			/**< algorithm block size */
+			struct rte_crypto_param_range c_key_size;
+			/**< cipher key size range */
+			struct rte_crypto_param_range a_key_size;
+			/**< auth key size range */
+			struct rte_crypto_param_range digest_size;
+			/**< digest size range */
+			struct rte_crypto_param_range iv_size;
+			/**< Initialisation vector data size range */
+		} ipsec;
+		/**< IPSEC transform capabilities */
+		struct {
+			/* To be Filled */
+		} dtls;
+		/**< DTLS transform capabilities */
+		struct {
+			/* To be Filled */
+		} macsec;
+		/**< MACSEC transform capabilities */
+	};
+};
+
+/**
+ *  Provide capabilities available for defined device and algorithm
+ *
+ * @param	dev_id		The identifier of the device.
+ * @param	dev_name	Device name for which capability is needed
+ * @param	protocol	Protocol for which capability is required
+ *
+ * @return
+ *   - Return description of the security capability if exist.
+ *   - Return NULL if the capability not exist.
+ */
+const struct rte_security_capabilities *
+rte_security_capability_get(uint8_t dev_id, char *dev_name,
+		enum rte_security_sess_protocol protocol);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _RTE_SECURITY_H_ */
-- 
2.9.3

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

* [dpdk-dev] [RFC PATCH 2/4] cryptodev: entend cryptodev to support security APIs
  2017-08-15  6:35       ` [dpdk-dev] [RFC PATCH v2 0/4] " Akhil Goyal
  2017-08-15  6:35         ` [dpdk-dev] [RFC PATCH 1/4] rte_security: API definitions Akhil Goyal
@ 2017-08-15  6:35         ` Akhil Goyal
  2017-08-15  6:35         ` [dpdk-dev] [RFC PATCH 3/4] crypto/dpaa2_sec: add support for protocol offload ipsec Akhil Goyal
  2017-08-15  6:35         ` [dpdk-dev] [RFC PATCH 4/4] example/ipsec-secgw: add support for offloading crypto op Akhil Goyal
  3 siblings, 0 replies; 37+ messages in thread
From: Akhil Goyal @ 2017-08-15  6:35 UTC (permalink / raw)
  To: dev, declan.doherty, thomas, radu.nicolau, aviadye, borisp,
	pablo.de.lara.guarch, sergio.gonzalez.monroy
  Cc: hemant.agrawal, sandeep.malik, Akhil Goyal

cryptodev library is extended to support security APIs
Similar changes needs to be done for ether devices also
to support security APIs

Signed-off-by: Akhil Goyal <akhil.goyal@nxp.com>
---
 lib/librte_cryptodev/Makefile            |  3 ++-
 lib/librte_cryptodev/rte_crypto_sym.h    | 15 ++++++++++++++
 lib/librte_cryptodev/rte_cryptodev.h     | 20 ++++++------------
 lib/librte_cryptodev/rte_cryptodev_pmd.h | 35 ++++++++++++++++++++++++++++++++
 4 files changed, 58 insertions(+), 15 deletions(-)

diff --git a/lib/librte_cryptodev/Makefile b/lib/librte_cryptodev/Makefile
index 6ac331b..376a275 100644
--- a/lib/librte_cryptodev/Makefile
+++ b/lib/librte_cryptodev/Makefile
@@ -41,7 +41,7 @@ CFLAGS += -O3
 CFLAGS += $(WERROR_FLAGS)
 
 # library source files
-SRCS-y += rte_cryptodev.c rte_cryptodev_pmd.c
+SRCS-y += rte_cryptodev.c rte_cryptodev_pmd.c rte_security.c
 
 # export include files
 SYMLINK-y-include += rte_crypto.h
@@ -50,6 +50,7 @@ SYMLINK-y-include += rte_cryptodev.h
 SYMLINK-y-include += rte_cryptodev_pmd.h
 SYMLINK-y-include += rte_cryptodev_vdev.h
 SYMLINK-y-include += rte_cryptodev_pci.h
+SYMLINK-y-include += rte_security.h
 
 # versioning export map
 EXPORT_MAP := rte_cryptodev_version.map
diff --git a/lib/librte_cryptodev/rte_crypto_sym.h b/lib/librte_cryptodev/rte_crypto_sym.h
index 0ceaa91..d804e70 100644
--- a/lib/librte_cryptodev/rte_crypto_sym.h
+++ b/lib/librte_cryptodev/rte_crypto_sym.h
@@ -53,6 +53,19 @@ extern "C" {
 #include <rte_mempool.h>
 #include <rte_common.h>
 
+/**
+ * Crypto parameters range description
+ */
+struct rte_crypto_param_range {
+	uint16_t min;	/**< minimum size */
+	uint16_t max;	/**< maximum size */
+	uint16_t increment;
+	/**< if a range of sizes are supported,
+	 * this parameter is used to indicate
+	 * increments in byte size that are supported
+	 * between the minimum and maximum
+	 */
+};
 
 /** Symmetric Cipher Algorithms */
 enum rte_crypto_cipher_algorithm {
@@ -505,6 +518,8 @@ struct rte_crypto_sym_op {
 		/**< Handle for the initialised session context */
 		struct rte_crypto_sym_xform *xform;
 		/**< Session-less API crypto operation parameters */
+		struct rte_security_session *sec_session;
+		/**< Handle for the initialised security session context */
 	};
 
 	RTE_STD_C11
diff --git a/lib/librte_cryptodev/rte_cryptodev.h b/lib/librte_cryptodev/rte_cryptodev.h
index 7ec9c4b..2a544e9 100644
--- a/lib/librte_cryptodev/rte_cryptodev.h
+++ b/lib/librte_cryptodev/rte_cryptodev.h
@@ -47,6 +47,7 @@ extern "C" {
 
 #include "rte_kvargs.h"
 #include "rte_crypto.h"
+#include "rte_security.h"
 #include "rte_dev.h"
 #include <rte_common.h>
 #include <rte_vdev.h>
@@ -114,20 +115,6 @@ extern const char **rte_cyptodev_names;
 	(phys_addr_t)((c)->phys_addr + (o))
 
 /**
- * Crypto parameters range description
- */
-struct rte_crypto_param_range {
-	uint16_t min;	/**< minimum size */
-	uint16_t max;	/**< maximum size */
-	uint16_t increment;
-	/**< if a range of sizes are supported,
-	 * this parameter is used to indicate
-	 * increments in byte size that are supported
-	 * between the minimum and maximum
-	 */
-};
-
-/**
  * Symmetric Crypto Capability
  */
 struct rte_cryptodev_symmetric_capability {
@@ -376,6 +363,9 @@ struct rte_cryptodev_info {
 	const struct rte_cryptodev_capabilities *capabilities;
 	/**< Array of devices supported capabilities */
 
+	const struct rte_security_capabilities *sec_capabilities;
+	/**< Array of devices supported security capabilities */
+
 	unsigned max_nb_queue_pairs;
 	/**< Maximum number of queues pairs supported by device. */
 
@@ -745,6 +735,8 @@ struct rte_cryptodev {
 	/**< Pointer to device data */
 	struct rte_cryptodev_ops *dev_ops;
 	/**< Functions exported by PMD */
+	struct rte_security_ops *sec_ops;
+	/**< Security functions exported by PMD */
 	uint64_t feature_flags;
 	/**< Supported features */
 	struct rte_device *device;
diff --git a/lib/librte_cryptodev/rte_cryptodev_pmd.h b/lib/librte_cryptodev/rte_cryptodev_pmd.h
index c983eb2..219fba6 100644
--- a/lib/librte_cryptodev/rte_cryptodev_pmd.h
+++ b/lib/librte_cryptodev/rte_cryptodev_pmd.h
@@ -357,6 +357,41 @@ struct rte_cryptodev_ops {
 	/**< Detach session from queue pair. */
 };
 
+/**
+ * Configure a security session on a device.
+ *
+ * @param	dev		Crypto device pointer
+ * @param	conf		Security session configuration
+ * @param	sess		Pointer to Security private session structure
+ * @param	mp		Mempool where the private session is allocated
+ *
+ * @return
+ *  - Returns 0 if private session structure have been created successfully.
+ *  - Returns -EINVAL if input parameters are invalid.
+ *  - Returns -ENOTSUP if crypto device does not support the crypto transform.
+ *  - Returns -ENOMEM if the private session could not be allocated.
+ */
+typedef int (*security_configure_session_t)(struct rte_cryptodev *dev,
+		struct rte_security_sess_conf *conf,
+		struct rte_security_session *sess,
+		struct rte_mempool *mp);
+
+/**
+ * Free driver private session data.
+ *
+ * @param	dev		Crypto device pointer
+ * @param	sess		Security session structure
+ */
+typedef void (*security_free_session_t)(struct rte_cryptodev *dev,
+		struct rte_security_session *sess);
+
+/** Security operations function pointer table */
+struct rte_security_ops {
+	security_configure_session_t session_configure;
+	/**< Configure a Security session. */
+	security_free_session_t session_clear;
+	/**< Clear a security sessions private data. */
+};
 
 /**
  * Function for internal use by dummy drivers primarily, e.g. ring-based
-- 
2.9.3

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

* [dpdk-dev] [RFC PATCH 3/4] crypto/dpaa2_sec: add support for protocol offload ipsec
  2017-08-15  6:35       ` [dpdk-dev] [RFC PATCH v2 0/4] " Akhil Goyal
  2017-08-15  6:35         ` [dpdk-dev] [RFC PATCH 1/4] rte_security: API definitions Akhil Goyal
  2017-08-15  6:35         ` [dpdk-dev] [RFC PATCH 2/4] cryptodev: entend cryptodev to support security APIs Akhil Goyal
@ 2017-08-15  6:35         ` Akhil Goyal
  2017-08-15  6:35         ` [dpdk-dev] [RFC PATCH 4/4] example/ipsec-secgw: add support for offloading crypto op Akhil Goyal
  3 siblings, 0 replies; 37+ messages in thread
From: Akhil Goyal @ 2017-08-15  6:35 UTC (permalink / raw)
  To: dev, declan.doherty, thomas, radu.nicolau, aviadye, borisp,
	pablo.de.lara.guarch, sergio.gonzalez.monroy
  Cc: hemant.agrawal, sandeep.malik, Akhil Goyal

driver implementation to support rte_security APIs

Signed-off-by: Akhil Goyal <akhil.goyal@nxp.com>
---
 drivers/crypto/dpaa2_sec/dpaa2_sec_dpseci.c | 368 +++++++++++++++++++++++++++-
 drivers/crypto/dpaa2_sec/dpaa2_sec_priv.h   |  33 +++
 2 files changed, 399 insertions(+), 2 deletions(-)

diff --git a/drivers/crypto/dpaa2_sec/dpaa2_sec_dpseci.c b/drivers/crypto/dpaa2_sec/dpaa2_sec_dpseci.c
index e0f6cfc..45f41d5 100644
--- a/drivers/crypto/dpaa2_sec/dpaa2_sec_dpseci.c
+++ b/drivers/crypto/dpaa2_sec/dpaa2_sec_dpseci.c
@@ -73,12 +73,46 @@
 #define FLE_POOL_NUM_BUFS	32000
 #define FLE_POOL_BUF_SIZE	256
 #define FLE_POOL_CACHE_SIZE	512
+#define SEC_FLC_DHR_OUTBOUND	-114
+#define SEC_FLC_DHR_INBOUND	0
 
 enum rta_sec_era rta_sec_era = RTA_SEC_ERA_8;
 
 static uint8_t cryptodev_driver_id;
 
 static inline int
+build_proto_fd(dpaa2_sec_session *sess,
+	       struct rte_crypto_op *op,
+	       struct qbman_fd *fd, uint16_t bpid)
+{
+	struct rte_crypto_sym_op *sym_op = op->sym;
+	struct ctxt_priv *priv = sess->ctxt;
+	struct sec_flow_context *flc;
+	struct rte_mbuf *mbuf = sym_op->m_src;
+
+	if (likely(bpid < MAX_BPID)) {
+		DPAA2_SET_FD_BPID(fd, bpid);
+	} else {
+		DPAA2_SET_FD_IVP(fd);
+	}
+
+	/* Save the shared descriptor */
+	flc = &priv->flc_desc[0].flc;
+
+	DPAA2_SET_FD_ADDR(fd, DPAA2_MBUF_VADDR_TO_IOVA(sym_op->m_src));
+	DPAA2_SET_FD_OFFSET(fd, sym_op->m_src->data_off + sym_op->m_src->l2_len);
+	DPAA2_SET_FD_LEN(fd, sym_op->m_src->pkt_len - sym_op->m_src->l2_len);
+	DPAA2_SET_FD_FLC(fd, ((uint64_t)flc));
+
+	/* save physical address of mbuf */
+	op->sym->aead.digest.phys_addr = mbuf->buf_physaddr;
+	mbuf->buf_physaddr = (uint64_t)op;
+
+	return 0;
+}
+
+
+static inline int
 build_authenc_gcm_fd(dpaa2_sec_session *sess,
 		     struct rte_crypto_op *op,
 		     struct qbman_fd *fd, uint16_t bpid)
@@ -565,6 +599,9 @@ build_sec_fd(dpaa2_sec_session *sess, struct rte_crypto_op *op,
 	case DPAA2_SEC_CIPHER_HASH:
 		ret = build_authenc_fd(sess, op, fd, bpid);
 		break;
+	case DPAA2_SEC_IPSEC:
+		ret = build_proto_fd(sess, op, fd, bpid);
+		break;
 	case DPAA2_SEC_HASH_CIPHER:
 	default:
 		RTE_LOG(ERR, PMD, "error: Unsupported session\n");
@@ -649,12 +686,44 @@ dpaa2_sec_enqueue_burst(void *qp, struct rte_crypto_op **ops,
 }
 
 static inline struct rte_crypto_op *
-sec_fd_to_mbuf(const struct qbman_fd *fd)
+sec_simple_fd_to_mbuf(const struct qbman_fd *fd, __rte_unused uint8_t id)
+{
+	struct rte_crypto_op *op;
+	uint16_t len = DPAA2_GET_FD_LEN(fd);
+	uint16_t diff = 0;
+	dpaa2_sec_session *sess_priv;
+
+	struct rte_mbuf *mbuf = DPAA2_INLINE_MBUF_FROM_BUF(
+		DPAA2_IOVA_TO_VADDR(DPAA2_GET_FD_ADDR(fd)),
+		rte_dpaa2_bpid_info[DPAA2_GET_FD_BPID(fd)].meta_data_size);
+
+	op = (struct rte_crypto_op *)mbuf->buf_physaddr;
+	mbuf->buf_physaddr = op->sym->aead.digest.phys_addr;
+	op->sym->aead.digest.phys_addr = 0L;
+
+	sess_priv = (dpaa2_sec_session *)get_sec_session_private_data(
+				op->sym->sec_session, id);
+	if (sess_priv->dir == DIR_ENC)
+		mbuf->data_off += SEC_FLC_DHR_OUTBOUND;
+	else
+		mbuf->data_off += SEC_FLC_DHR_INBOUND;
+	diff = len - mbuf->pkt_len;
+	mbuf->pkt_len += diff;
+	mbuf->data_len += diff;
+
+	return op;
+}
+
+static inline struct rte_crypto_op *
+sec_fd_to_mbuf(const struct qbman_fd *fd, uint8_t driver_id)
 {
 	struct qbman_fle *fle;
 	struct rte_crypto_op *op;
 	struct ctxt_priv *priv;
 
+	if (DPAA2_FD_GET_FORMAT(fd) == qbman_fd_single)
+		return sec_simple_fd_to_mbuf(fd, driver_id);
+
 	fle = (struct qbman_fle *)DPAA2_IOVA_TO_VADDR(DPAA2_GET_FD_ADDR(fd));
 
 	PMD_RX_LOG(DEBUG, "FLE addr = %x - %x, offset = %x",
@@ -701,6 +770,7 @@ dpaa2_sec_dequeue_burst(void *qp, struct rte_crypto_op **ops,
 {
 	/* Function is responsible to receive frames for a given device and VQ*/
 	struct dpaa2_sec_qp *dpaa2_qp = (struct dpaa2_sec_qp *)qp;
+	struct rte_cryptodev *dev = (struct rte_cryptodev *)(dpaa2_qp->rx_vq.dev);
 	struct qbman_result *dq_storage;
 	uint32_t fqid = dpaa2_qp->rx_vq.fqid;
 	int ret, num_rx = 0;
@@ -770,7 +840,7 @@ dpaa2_sec_dequeue_burst(void *qp, struct rte_crypto_op **ops,
 		}
 
 		fd = qbman_result_DQ_fd(dq_storage);
-		ops[num_rx] = sec_fd_to_mbuf(fd);
+		ops[num_rx] = sec_fd_to_mbuf(fd, dev->driver_id);
 
 		if (unlikely(fd->simple.frc)) {
 			/* TODO Parse SEC errors */
@@ -1547,6 +1617,293 @@ dpaa2_sec_set_session_parameters(struct rte_cryptodev *dev,
 }
 
 static int
+dpaa2_sec_set_ipsec_session(struct rte_cryptodev *dev,
+		struct rte_security_ipsec_xform *xform,
+		void *sess)
+{
+	dpaa2_sec_session *session = (dpaa2_sec_session *)sess;
+	struct ctxt_priv *priv;
+	struct ipsec_encap_pdb encap_pdb;
+	struct ipsec_decap_pdb decap_pdb;
+	struct alginfo authdata, cipherdata;
+	unsigned int bufsize;
+//	unsigned int i;
+	struct sec_flow_context *flc;
+
+	PMD_INIT_FUNC_TRACE();
+
+	priv = (struct ctxt_priv *)rte_zmalloc(NULL,
+				sizeof(struct ctxt_priv) +
+				sizeof(struct sec_flc_desc),
+				RTE_CACHE_LINE_SIZE);
+
+	if (priv == NULL) {
+		RTE_LOG(ERR, PMD, "\nNo memory for priv CTXT");
+		return -ENOMEM;
+	}
+
+	flc = &priv->flc_desc[0].flc;
+
+	session->ctxt_type = DPAA2_SEC_IPSEC;
+	session->cipher_key.data = rte_zmalloc(NULL,
+					       xform->cipher_key.length,
+					       RTE_CACHE_LINE_SIZE);
+	if (session->cipher_key.data == NULL &&
+			xform->cipher_key.length > 0) {
+		RTE_LOG(ERR, PMD, "No Memory for cipher key\n");
+		rte_free(priv);
+		return -ENOMEM;
+	}
+
+	session->cipher_key.length = xform->cipher_key.length;
+	session->auth_key.data = rte_zmalloc(NULL,
+					     xform->auth_key.length,
+					     RTE_CACHE_LINE_SIZE);
+	if (session->auth_key.data == NULL &&
+			xform->auth_key.length > 0) {
+		RTE_LOG(ERR, PMD, "No Memory for auth key\n");
+		rte_free(session->cipher_key.data);
+		rte_free(priv);
+		return -ENOMEM;
+	}
+	session->auth_key.length = xform->auth_key.length;
+	memcpy(session->cipher_key.data, xform->cipher_key.data,
+			xform->cipher_key.length);
+	memcpy(session->auth_key.data, xform->auth_key.data,
+			xform->auth_key.length);
+
+	authdata.key = (uint64_t)session->auth_key.data;
+	authdata.keylen = session->auth_key.length;
+	authdata.key_enc_flags = 0;
+	authdata.key_type = RTA_DATA_IMM;
+	switch (xform->auth_alg) {
+	case RTE_CRYPTO_AUTH_SHA1_HMAC:
+		authdata.algtype = OP_PCL_IPSEC_HMAC_SHA1_96;
+		authdata.algmode = OP_ALG_AAI_HMAC;
+		session->auth_alg = RTE_CRYPTO_AUTH_SHA1_HMAC;
+		break;
+	case RTE_CRYPTO_AUTH_MD5_HMAC:
+		authdata.algtype = OP_PCL_IPSEC_HMAC_MD5_96;
+		authdata.algmode = OP_ALG_AAI_HMAC;
+		session->auth_alg = RTE_CRYPTO_AUTH_MD5_HMAC;
+		break;
+	case RTE_CRYPTO_AUTH_SHA256_HMAC:
+		authdata.algtype = OP_PCL_IPSEC_HMAC_SHA2_256_128;
+		authdata.algmode = OP_ALG_AAI_HMAC;
+		session->auth_alg = RTE_CRYPTO_AUTH_SHA256_HMAC;
+		break;
+	case RTE_CRYPTO_AUTH_SHA384_HMAC:
+		authdata.algtype = OP_PCL_IPSEC_HMAC_SHA2_384_192;
+		authdata.algmode = OP_ALG_AAI_HMAC;
+		session->auth_alg = RTE_CRYPTO_AUTH_SHA384_HMAC;
+		break;
+	case RTE_CRYPTO_AUTH_SHA512_HMAC:
+		authdata.algtype = OP_PCL_IPSEC_HMAC_SHA2_512_256;
+		authdata.algmode = OP_ALG_AAI_HMAC;
+		session->auth_alg = RTE_CRYPTO_AUTH_SHA512_HMAC;
+		break;
+	case RTE_CRYPTO_AUTH_AES_CMAC:
+		authdata.algtype = OP_PCL_IPSEC_AES_CMAC_96;
+		session->auth_alg = RTE_CRYPTO_AUTH_AES_CMAC;
+		break;
+	case RTE_CRYPTO_AUTH_NULL:
+		authdata.algtype = OP_PCL_IPSEC_HMAC_NULL;
+		session->auth_alg = RTE_CRYPTO_AUTH_NULL;
+		break;
+	case RTE_CRYPTO_AUTH_SHA224_HMAC:
+	case RTE_CRYPTO_AUTH_AES_XCBC_MAC:
+	case RTE_CRYPTO_AUTH_SNOW3G_UIA2:
+	case RTE_CRYPTO_AUTH_SHA1:
+	case RTE_CRYPTO_AUTH_SHA256:
+	case RTE_CRYPTO_AUTH_SHA512:
+	case RTE_CRYPTO_AUTH_SHA224:
+	case RTE_CRYPTO_AUTH_SHA384:
+	case RTE_CRYPTO_AUTH_MD5:
+	case RTE_CRYPTO_AUTH_AES_GMAC:
+	case RTE_CRYPTO_AUTH_KASUMI_F9:
+	case RTE_CRYPTO_AUTH_AES_CBC_MAC:
+	case RTE_CRYPTO_AUTH_ZUC_EIA3:
+		RTE_LOG(ERR, PMD, "Crypto: Unsupported auth alg %u\n",
+			xform->auth_alg);
+		goto out;
+	default:
+		RTE_LOG(ERR, PMD, "Crypto: Undefined Auth specified %u\n",
+			xform->auth_alg);
+		goto out;
+	}
+	cipherdata.key = (uint64_t)session->cipher_key.data;
+	cipherdata.keylen = session->cipher_key.length;
+	cipherdata.key_enc_flags = 0;
+	cipherdata.key_type = RTA_DATA_IMM;
+
+	switch (xform->cipher_alg) {
+	case RTE_CRYPTO_CIPHER_AES_CBC:
+		cipherdata.algtype = OP_PCL_IPSEC_AES_CBC;
+		cipherdata.algmode = OP_ALG_AAI_CBC;
+		session->cipher_alg = RTE_CRYPTO_CIPHER_AES_CBC;
+		break;
+	case RTE_CRYPTO_CIPHER_3DES_CBC:
+		cipherdata.algtype = OP_PCL_IPSEC_3DES;
+		cipherdata.algmode = OP_ALG_AAI_CBC;
+		session->cipher_alg = RTE_CRYPTO_CIPHER_3DES_CBC;
+		break;
+	case RTE_CRYPTO_CIPHER_AES_CTR:
+		cipherdata.algtype = OP_PCL_IPSEC_AES_CTR;
+		cipherdata.algmode = OP_ALG_AAI_CTR;
+		session->cipher_alg = RTE_CRYPTO_CIPHER_AES_CTR;
+		break;
+	case RTE_CRYPTO_CIPHER_NULL:
+		cipherdata.algtype = OP_PCL_IPSEC_NULL;
+		break;
+	case RTE_CRYPTO_CIPHER_SNOW3G_UEA2:
+	case RTE_CRYPTO_CIPHER_3DES_ECB:
+	case RTE_CRYPTO_CIPHER_AES_ECB:
+	case RTE_CRYPTO_CIPHER_KASUMI_F8:
+		RTE_LOG(ERR, PMD, "Crypto: Unsupported Cipher alg %u\n",
+			xform->cipher_alg);
+		goto out;
+	default:
+		RTE_LOG(ERR, PMD, "Crypto: Undefined Cipher specified %u\n",
+			xform->cipher_alg);
+		goto out;
+	}
+
+	if (xform->op == RTE_SECURITY_IPSEC_OP_ENCAP) {
+		flc->dhr = SEC_FLC_DHR_OUTBOUND;
+		struct ip ip4_hdr;
+		ip4_hdr.ip_v = IPVERSION;
+		ip4_hdr.ip_hl = 5;
+		ip4_hdr.ip_len = rte_cpu_to_be_16(sizeof(ip4_hdr));
+		ip4_hdr.ip_tos = xform->tunnel.ipv4.dscp;
+		ip4_hdr.ip_id = 0;
+		ip4_hdr.ip_off = 0;
+		ip4_hdr.ip_ttl = xform->tunnel.ipv4.ttl;
+		ip4_hdr.ip_p = 0x32;
+		ip4_hdr.ip_sum = 0;
+		ip4_hdr.ip_src = xform->tunnel.ipv4.src_ip;
+		ip4_hdr.ip_dst = xform->tunnel.ipv4.dst_ip;
+		ip4_hdr.ip_sum = calc_chksum((uint16_t *)(void *)&ip4_hdr,
+			sizeof(struct ip));
+
+		/* For Sec Proto only one descriptor is required. */
+		memset(&encap_pdb, 0, sizeof(struct ipsec_encap_pdb));
+		encap_pdb.options = (IPVERSION << PDBNH_ESP_ENCAP_SHIFT) |
+			PDBOPTS_ESP_OIHI_PDB_INL |
+			PDBOPTS_ESP_IVSRC |
+			PDBHMO_ESP_ENCAP_DTTL;
+		encap_pdb.spi = xform->spi;
+		encap_pdb.ip_hdr_len = sizeof(struct ip);
+
+		session->dir = DIR_ENC;
+		bufsize = cnstr_shdsc_ipsec_new_encap(priv->flc_desc[0].desc,
+				1, 0, &encap_pdb,
+				(uint8_t *)&ip4_hdr,
+				&cipherdata, &authdata);
+	} else if (xform->op == RTE_SECURITY_IPSEC_OP_DECAP) {
+		flc->dhr = SEC_FLC_DHR_INBOUND;
+		memset(&decap_pdb, 0, sizeof(struct ipsec_decap_pdb));
+		decap_pdb.options = sizeof(struct ip) << 16;
+		session->dir = DIR_DEC;
+		bufsize = cnstr_shdsc_ipsec_new_decap(priv->flc_desc[0].desc, 1, 0,
+				&decap_pdb, &cipherdata, &authdata);
+	} else
+		goto out;
+	flc->word1_sdl = (uint8_t)bufsize;
+//#if !defined(BUILD_LS2080) && !defined(BUILD_LS2085)
+	/*Enable the stashing control bit*/
+	DPAA2_SET_FLC_RSC(flc);
+	flc->word2_rflc_31_0 = lower_32_bits(
+			(uint64_t)&(((struct dpaa2_sec_qp *)
+			dev->data->queue_pairs[0])->rx_vq) | 0x14);
+	flc->word3_rflc_63_32 = upper_32_bits(
+			(uint64_t)&(((struct dpaa2_sec_qp *)
+			dev->data->queue_pairs[0])->rx_vq));
+//#endif
+	/* Set EWS bit i.e. enable write-safe */
+	DPAA2_SET_FLC_EWS(flc);
+	/* Set BS = 1 i.e reuse input buffers as output buffers */
+	DPAA2_SET_FLC_REUSE_BS(flc);
+	/* Set FF = 10 (bit)
+	Reuse input buffers if they provide sufficient space */
+	DPAA2_SET_FLC_REUSE_FF(flc);
+
+//	for (i = 0;i < bufsize; i++)
+//		printf("\nDESC[%u]: %x",i,priv->flc_desc[0].desc[i]);
+//	for (i = 0;i < 16;i++)
+//		printf("\nFLC[%u]: %x",i,((uint32_t *)flc)[i]);
+	session->ctxt = priv;
+	return 0;
+out:
+	rte_free(session->auth_key.data);
+	rte_free(session->cipher_key.data);
+	rte_free(priv);
+	return -1;
+}
+
+
+static int
+dpaa2_sec_security_session_configure(struct rte_cryptodev *dev,
+		struct rte_security_sess_conf *conf,
+		struct rte_security_session *sess,
+		struct rte_mempool *mempool)
+{
+	void *sess_private_data;
+	int ret;
+
+	if (rte_mempool_get(mempool, &sess_private_data)) {
+		CDEV_LOG_ERR(
+			"Couldn't get object from session mempool");
+		return -ENOMEM;
+	}
+
+	switch (conf->protocol) {
+	case RTE_SEC_CONF_IPSEC:
+		ret = dpaa2_sec_set_ipsec_session(dev, conf->ipsec_xform,
+				sess_private_data);
+		break;
+	case RTE_SEC_CONF_DTLS:
+	case RTE_SEC_CONF_MACSEC:
+		return -ENOTSUP;
+	default:
+		return -EINVAL;
+	}
+	if (ret != 0) {
+		PMD_DRV_LOG(ERR, "DPAA2 PMD: failed to configure "
+				"session parameters");
+
+		/* Return session to mempool */
+		rte_mempool_put(mempool, sess_private_data);
+		return ret;
+	}
+
+	set_sec_session_private_data(sess, dev->driver_id,
+		sess_private_data);
+
+	return ret;
+}
+
+/** Clear the memory of session so it doesn't leave key material behind */
+static void
+dpaa2_sec_security_session_clear(struct rte_cryptodev *dev,
+		struct rte_security_session *sess)
+{
+	PMD_INIT_FUNC_TRACE();
+	uint8_t index = dev->driver_id;
+	void *sess_priv = get_sec_session_private_data(sess, index);
+	dpaa2_sec_session *s = (dpaa2_sec_session *)sess_priv;
+
+	if (sess_priv) {
+		rte_free(s->ctxt);
+		rte_free(s->cipher_key.data);
+		rte_free(s->auth_key.data);
+		memset(sess, 0, sizeof(dpaa2_sec_session));
+		struct rte_mempool *sess_mp = rte_mempool_from_obj(sess_priv);
+		set_sec_session_private_data(sess, index, NULL);
+		rte_mempool_put(sess_mp, sess_priv);
+	}
+}
+
+static int
 dpaa2_sec_session_configure(struct rte_cryptodev *dev,
 		struct rte_crypto_sym_xform *xform,
 		struct rte_cryptodev_sym_session *sess,
@@ -1820,6 +2177,12 @@ static struct rte_cryptodev_ops crypto_ops = {
 	.session_clear        = dpaa2_sec_session_clear,
 };
 
+static struct rte_security_ops security_ops = {
+	.session_configure    = dpaa2_sec_security_session_configure,
+	.session_clear        = dpaa2_sec_security_session_clear,
+};
+
+
 static int
 dpaa2_sec_uninit(const struct rte_cryptodev *dev)
 {
@@ -1855,6 +2218,7 @@ dpaa2_sec_dev_init(struct rte_cryptodev *cryptodev)
 
 	cryptodev->driver_id = cryptodev_driver_id;
 	cryptodev->dev_ops = &crypto_ops;
+	cryptodev->sec_ops = &security_ops;
 
 	cryptodev->enqueue_burst = dpaa2_sec_enqueue_burst;
 	cryptodev->dequeue_burst = dpaa2_sec_dequeue_burst;
diff --git a/drivers/crypto/dpaa2_sec/dpaa2_sec_priv.h b/drivers/crypto/dpaa2_sec/dpaa2_sec_priv.h
index 3849a05..99f20c9 100644
--- a/drivers/crypto/dpaa2_sec/dpaa2_sec_priv.h
+++ b/drivers/crypto/dpaa2_sec/dpaa2_sec_priv.h
@@ -67,6 +67,11 @@ enum shr_desc_type {
 #define DIR_ENC                 1
 #define DIR_DEC                 0
 
+#define DPAA2_SET_FLC_EWS(flc)  flc->word1_bits23_16 |= 0x1
+#define DPAA2_SET_FLC_RSC(flc)  (flc->word1_bits31_24 |= 0x1)
+#define DPAA2_SET_FLC_REUSE_BS(flc) flc->mode_bits |= 0x8000
+#define DPAA2_SET_FLC_REUSE_FF(flc) flc->mode_bits |= 0x2000
+
 /* SEC Flow Context Descriptor */
 struct sec_flow_context {
 	/* word 0 */
@@ -411,4 +416,32 @@ static const struct rte_cryptodev_capabilities dpaa2_sec_capabilities[] = {
 
 	RTE_CRYPTODEV_END_OF_CAPABILITIES_LIST()
 };
+/**
+ * Checksum
+ *
+ * @param buffer calculate chksum for buffer
+ * @param len    buffer length
+ *
+ * @return checksum value in host cpu order
+ */
+static inline uint16_t calc_chksum(void *buffer, int len)
+{
+	uint16_t *buf = (uint16_t *)buffer;
+	uint32_t sum = 0;
+	uint16_t result;
+
+	for (sum = 0; len > 1; len -= 2)
+		sum += *buf++;
+
+	if (len == 1)
+		sum += *(unsigned char *)buf;
+
+	sum = (sum >> 16) + (sum & 0xFFFF);
+	sum += (sum >> 16);
+	result = ~sum;
+
+	return  result;
+}
+
+
 #endif /* _RTE_DPAA2_SEC_PMD_PRIVATE_H_ */
-- 
2.9.3

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

* [dpdk-dev] [RFC PATCH 4/4] example/ipsec-secgw: add support for offloading crypto op
  2017-08-15  6:35       ` [dpdk-dev] [RFC PATCH v2 0/4] " Akhil Goyal
                           ` (2 preceding siblings ...)
  2017-08-15  6:35         ` [dpdk-dev] [RFC PATCH 3/4] crypto/dpaa2_sec: add support for protocol offload ipsec Akhil Goyal
@ 2017-08-15  6:35         ` Akhil Goyal
  3 siblings, 0 replies; 37+ messages in thread
From: Akhil Goyal @ 2017-08-15  6:35 UTC (permalink / raw)
  To: dev, declan.doherty, thomas, radu.nicolau, aviadye, borisp,
	pablo.de.lara.guarch, sergio.gonzalez.monroy
  Cc: hemant.agrawal, sandeep.malik, Akhil Goyal

ipsec-secgw application is modified so that it can support
following type of actions for crypto operations
1. full protocol offload using crypto devices.
2. inline ipsec using ethernet devices to perform crypto operations
3. full protocol offload using ethernet devices.
4. non protocol offload

action type 1 is implemented as part of this patch.
action type 2 and 3 will be added as part of the original RFC in this
thread. action type 4 is already supported.

Signed-off-by: Akhil Goyal <akhil.goyal@nxp.com>
---
 examples/ipsec-secgw/ipsec.c | 125 +++++++++++++++++++++++++------------
 examples/ipsec-secgw/ipsec.h |  13 +++-
 examples/ipsec-secgw/sa.c    | 142 ++++++++++++++++++++++++++++++++-----------
 3 files changed, 206 insertions(+), 74 deletions(-)

diff --git a/examples/ipsec-secgw/ipsec.c b/examples/ipsec-secgw/ipsec.c
index 0afb9d6..c8fde1c 100644
--- a/examples/ipsec-secgw/ipsec.c
+++ b/examples/ipsec-secgw/ipsec.c
@@ -37,6 +37,7 @@
 #include <rte_branch_prediction.h>
 #include <rte_log.h>
 #include <rte_crypto.h>
+#include <rte_security.h>
 #include <rte_cryptodev.h>
 #include <rte_mbuf.h>
 #include <rte_hash.h>
@@ -71,22 +72,40 @@ create_session(struct ipsec_ctx *ipsec_ctx, struct ipsec_sa *sa)
 			ipsec_ctx->tbl[cdev_id_qp].id,
 			ipsec_ctx->tbl[cdev_id_qp].qp);
 
-	sa->crypto_session = rte_cryptodev_sym_session_create(
-			ipsec_ctx->session_pool);
-	rte_cryptodev_sym_session_init(ipsec_ctx->tbl[cdev_id_qp].id,
-			sa->crypto_session, sa->xforms,
-			ipsec_ctx->session_pool);
-
-	rte_cryptodev_info_get(ipsec_ctx->tbl[cdev_id_qp].id, &cdev_info);
-	if (cdev_info.sym.max_nb_sessions_per_qp > 0) {
-		ret = rte_cryptodev_queue_pair_attach_sym_session(
-				ipsec_ctx->tbl[cdev_id_qp].id,
-				ipsec_ctx->tbl[cdev_id_qp].qp,
-				sa->crypto_session);
+	if (sa->type == RTE_SECURITY_SESS_NONE) {
+		sa->crypto_session = rte_cryptodev_sym_session_create(
+				ipsec_ctx->session_pool);
+		rte_cryptodev_sym_session_init(ipsec_ctx->tbl[cdev_id_qp].id,
+				sa->crypto_session, sa->xforms,
+				ipsec_ctx->session_pool);
+
+		rte_cryptodev_info_get(ipsec_ctx->tbl[cdev_id_qp].id, &cdev_info);
+		if (cdev_info.sym.max_nb_sessions_per_qp > 0) {
+			ret = rte_cryptodev_queue_pair_attach_sym_session(
+					ipsec_ctx->tbl[cdev_id_qp].id,
+					ipsec_ctx->tbl[cdev_id_qp].qp,
+					sa->crypto_session);
+			if (ret < 0) {
+				RTE_LOG(ERR, IPSEC,
+					"Session cannot be attached to qp %u ",
+					ipsec_ctx->tbl[cdev_id_qp].qp);
+				return -1;
+			}
+		}
+	} else {
+		struct rte_security_sess_conf sess_conf;
+
+		sa->sec_session = rte_security_session_create(
+				ipsec_ctx->session_pool);
+		sess_conf.action_type = sa->type;
+		sess_conf.protocol = RTE_SEC_CONF_IPSEC;
+		sess_conf.ipsec_xform = sa->sec_xform;
+
+		ret = rte_security_session_init(sa->portid, sa->sec_session,
+					&sess_conf, ipsec_ctx->session_pool);
 		if (ret < 0) {
-			RTE_LOG(ERR, IPSEC,
-				"Session cannot be attached to qp %u ",
-				ipsec_ctx->tbl[cdev_id_qp].qp);
+			RTE_LOG(ERR, IPSEC, "SEC Session init failed: err: %d",
+					ret);
 			return -1;
 		}
 	}
@@ -125,6 +144,7 @@ ipsec_enqueue(ipsec_xform_fn xform_func, struct ipsec_ctx *ipsec_ctx,
 {
 	int32_t ret = 0, i;
 	struct ipsec_mbuf_metadata *priv;
+	struct rte_crypto_sym_op *sym_cop;
 	struct ipsec_sa *sa;
 
 	for (i = 0; i < nb_pkts; i++) {
@@ -140,24 +160,50 @@ ipsec_enqueue(ipsec_xform_fn xform_func, struct ipsec_ctx *ipsec_ctx,
 		sa = sas[i];
 		priv->sa = sa;
 
-		priv->cop.type = RTE_CRYPTO_OP_TYPE_SYMMETRIC;
-		priv->cop.status = RTE_CRYPTO_OP_STATUS_NOT_PROCESSED;
-
-		rte_prefetch0(&priv->sym_cop);
-
-		if ((unlikely(sa->crypto_session == NULL)) &&
-				create_session(ipsec_ctx, sa)) {
-			rte_pktmbuf_free(pkts[i]);
-			continue;
-		}
-
-		rte_crypto_op_attach_sym_session(&priv->cop,
-				sa->crypto_session);
-
-		ret = xform_func(pkts[i], sa, &priv->cop);
-		if (unlikely(ret)) {
-			rte_pktmbuf_free(pkts[i]);
-			continue;
+		switch (sa->type) {
+		case RTE_SECURITY_SESS_CRYPTO_PROTO_OFFLOAD:
+			priv->cop.type = RTE_CRYPTO_OP_TYPE_SYMMETRIC;
+			priv->cop.status = RTE_CRYPTO_OP_STATUS_NOT_PROCESSED;
+
+			rte_prefetch0(&priv->sym_cop);
+
+			if ((unlikely(sa->sec_session == NULL)) &&
+					create_session(ipsec_ctx, sa)) {
+				rte_pktmbuf_free(pkts[i]);
+				continue;
+			}
+
+			sym_cop = get_sym_cop(&priv->cop);
+			sym_cop->m_src = pkts[i];
+
+			rte_security_attach_session(&priv->cop,
+					sa->sec_session);
+			break;
+		case RTE_SECURITY_SESS_NONE:
+
+			priv->cop.type = RTE_CRYPTO_OP_TYPE_SYMMETRIC;
+			priv->cop.status = RTE_CRYPTO_OP_STATUS_NOT_PROCESSED;
+
+			rte_prefetch0(&priv->sym_cop);
+
+			if ((unlikely(sa->crypto_session == NULL)) &&
+					create_session(ipsec_ctx, sa)) {
+				rte_pktmbuf_free(pkts[i]);
+				continue;
+			}
+
+			rte_crypto_op_attach_sym_session(&priv->cop,
+					sa->crypto_session);
+
+			ret = xform_func(pkts[i], sa, &priv->cop);
+			if (unlikely(ret)) {
+				rte_pktmbuf_free(pkts[i]);
+				continue;
+			}
+			break;
+		case RTE_SECURITY_SESS_ETH_PROTO_OFFLOAD:
+		case RTE_SECURITY_SESS_ETH_INLINE_CRYPTO:
+			break;
 		}
 
 		RTE_ASSERT(sa->cdev_id_qp < ipsec_ctx->nb_qps);
@@ -199,11 +245,14 @@ ipsec_dequeue(ipsec_xform_fn xform_func, struct ipsec_ctx *ipsec_ctx,
 
 			RTE_ASSERT(sa != NULL);
 
-			ret = xform_func(pkt, sa, cops[j]);
-			if (unlikely(ret))
-				rte_pktmbuf_free(pkt);
-			else
-				pkts[nb_pkts++] = pkt;
+			if (sa->type == RTE_SECURITY_SESS_NONE) {
+				ret = xform_func(pkt, sa, cops[j]);
+				if (unlikely(ret)) {
+					rte_pktmbuf_free(pkt);
+					continue;
+				}
+			}
+			pkts[nb_pkts++] = pkt;
 		}
 	}
 
diff --git a/examples/ipsec-secgw/ipsec.h b/examples/ipsec-secgw/ipsec.h
index da1fb1b..6291d86 100644
--- a/examples/ipsec-secgw/ipsec.h
+++ b/examples/ipsec-secgw/ipsec.h
@@ -38,6 +38,7 @@
 
 #include <rte_byteorder.h>
 #include <rte_crypto.h>
+#include <rte_security.h>
 
 #define RTE_LOGTYPE_IPSEC       RTE_LOGTYPE_USER1
 #define RTE_LOGTYPE_IPSEC_ESP   RTE_LOGTYPE_USER2
@@ -99,7 +100,10 @@ struct ipsec_sa {
 	uint32_t cdev_id_qp;
 	uint64_t seq;
 	uint32_t salt;
-	struct rte_cryptodev_sym_session *crypto_session;
+	union {
+		struct rte_cryptodev_sym_session *crypto_session;
+		struct rte_security_session *sec_session;
+	};
 	enum rte_crypto_cipher_algorithm cipher_algo;
 	enum rte_crypto_auth_algorithm auth_algo;
 	enum rte_crypto_aead_algorithm aead_algo;
@@ -117,7 +121,12 @@ struct ipsec_sa {
 	uint8_t auth_key[MAX_KEY_SIZE];
 	uint16_t auth_key_len;
 	uint16_t aad_len;
-	struct rte_crypto_sym_xform *xforms;
+	union {
+		struct rte_crypto_sym_xform *xforms;
+		struct rte_security_ipsec_xform *sec_xform;
+	};
+	enum rte_security_session_action_type type;
+	uint16_t portid;
 } __rte_cache_aligned;
 
 struct ipsec_mbuf_metadata {
diff --git a/examples/ipsec-secgw/sa.c b/examples/ipsec-secgw/sa.c
index 7be0e62..851262b 100644
--- a/examples/ipsec-secgw/sa.c
+++ b/examples/ipsec-secgw/sa.c
@@ -41,6 +41,7 @@
 
 #include <rte_memzone.h>
 #include <rte_crypto.h>
+#include <rte_security.h>
 #include <rte_cryptodev.h>
 #include <rte_byteorder.h>
 #include <rte_errno.h>
@@ -51,6 +52,8 @@
 #include "esp.h"
 #include "parser.h"
 
+#define IPDEFTTL 64
+
 struct supported_cipher_algo {
 	const char *keyword;
 	enum rte_crypto_cipher_algorithm algo;
@@ -238,6 +241,8 @@ parse_sa_tokens(char **tokens, uint32_t n_tokens,
 	uint32_t src_p = 0;
 	uint32_t dst_p = 0;
 	uint32_t mode_p = 0;
+	uint32_t type_p = 0;
+	uint32_t portid_p = 0;
 
 	if (strcmp(tokens[0], "in") == 0) {
 		ri = &nb_sa_in;
@@ -550,6 +555,47 @@ parse_sa_tokens(char **tokens, uint32_t n_tokens,
 			continue;
 		}
 
+		if (strcmp(tokens[ti], "type") == 0) {
+			APP_CHECK_PRESENCE(type_p, tokens[ti], status);
+			if (status->status < 0)
+				return;
+
+			INCREMENT_TOKEN_INDEX(ti, n_tokens, status);
+			if (status->status < 0)
+				return;
+
+			if (strcmp(tokens[ti], "eth-inline-crypto") == 0)
+				rule->type = RTE_SECURITY_SESS_ETH_INLINE_CRYPTO;
+			else if (strcmp(tokens[ti], "eth-proto-offload") == 0)
+				rule->type = RTE_SECURITY_SESS_ETH_PROTO_OFFLOAD;
+			else if (strcmp(tokens[ti], "crypto-proto-offload") == 0)
+				rule->type = RTE_SECURITY_SESS_CRYPTO_PROTO_OFFLOAD;
+			else if (strcmp(tokens[ti], "non-proto") == 0)
+				rule->type = RTE_SECURITY_SESS_NONE;
+			else {
+				APP_CHECK(0, status, "unrecognized "
+					"input \"%s\"", tokens[ti]);
+				return;
+			}
+
+			type_p = 1;
+			continue;
+		}
+
+		if (strcmp(tokens[ti], "port_id") == 0) {
+			APP_CHECK_PRESENCE(portid_p, tokens[ti], status);
+			if (status->status < 0)
+				return;
+			INCREMENT_TOKEN_INDEX(ti, n_tokens, status);
+			if (status->status < 0)
+				return;
+			rule->portid = atoi(tokens[ti]);
+			if (status->status < 0)
+				return;
+			portid_p = 1;
+			continue;
+		}
+
 		/* unrecognizeable input */
 		APP_CHECK(0, status, "unrecognized input \"%s\"",
 			tokens[ti]);
@@ -580,6 +626,14 @@ parse_sa_tokens(char **tokens, uint32_t n_tokens,
 	if (status->status < 0)
 		return;
 
+	if ((rule->type != RTE_SECURITY_SESS_NONE) && (portid_p == 0))
+		printf("Missing portid option, falling back to non-offload");
+
+	if (!type_p || !portid_p) {
+		rule->type = RTE_SECURITY_SESS_NONE;
+		rule->portid = -1;
+	}
+
 	*ri = *ri + 1;
 }
 
@@ -647,9 +701,12 @@ print_one_sa_rule(const struct ipsec_sa *sa, int inbound)
 
 struct sa_ctx {
 	struct ipsec_sa sa[IPSEC_SA_MAX_ENTRIES];
-	struct {
-		struct rte_crypto_sym_xform a;
-		struct rte_crypto_sym_xform b;
+	union {
+		struct {
+			struct rte_crypto_sym_xform a;
+			struct rte_crypto_sym_xform b;
+		};
+		struct rte_security_ipsec_xform c;
 	} xf[IPSEC_SA_MAX_ENTRIES];
 };
 
@@ -706,40 +763,57 @@ sa_add_rules(struct sa_ctx *sa_ctx, const struct ipsec_sa entries[],
 			sa->dst.ip.ip4 = rte_cpu_to_be_32(sa->dst.ip.ip4);
 		}
 
+		if (sa->type == RTE_SECURITY_SESS_CRYPTO_PROTO_OFFLOAD) {
+			sa_ctx->xf[idx].c.cipher_alg = sa->cipher_algo;
+			sa_ctx->xf[idx].c.auth_alg = sa->auth_algo;
+			sa_ctx->xf[idx].c.cipher_key.data = sa->cipher_key;
+			sa_ctx->xf[idx].c.auth_key.data = sa->auth_key;
+			sa_ctx->xf[idx].c.cipher_key.length =
+						sa->cipher_key_len;
+			sa_ctx->xf[idx].c.auth_key.length = sa->auth_key_len;
+			sa_ctx->xf[idx].c.op = (inbound == 1)?
+						RTE_SECURITY_IPSEC_OP_DECAP :
+						RTE_SECURITY_IPSEC_OP_ENCAP;
+			sa_ctx->xf[idx].c.salt = sa->salt;
+			sa_ctx->xf[idx].c.spi = sa->spi;
+			if (sa->flags == IP4_TUNNEL) {
+				sa_ctx->xf[idx].c.mode =
+					RTE_SECURITY_IPSEC_SA_MODE_TUNNEL;
+				sa_ctx->xf[idx].c.tunnel.ipv4.ttl = IPDEFTTL;
+				memcpy((uint8_t *)&sa_ctx->xf[idx].c.tunnel.ipv4.src_ip,
+						(uint8_t *)&sa->src.ip.ip4, 4);
+				memcpy((uint8_t *)&sa_ctx->xf[idx].c.tunnel.ipv4.dst_ip,
+						(uint8_t *)&sa->dst.ip.ip4, 4);
+//				sa_ctx->xf[idx].c.tunnel.ipv4.src_ip =
+//					(struct in_addr)sa->src.ip.ip4;
+//				sa_ctx->xf[idx].c.tunnel.ipv4.dst_ip =
+//					(struct in_addr)sa->dst.ip.ip4;
+			}
+			/* TODO support for Transport and IPV6 tunnel */
+			sa->sec_xform = &sa_ctx->xf[idx].c;
+
+			print_one_sa_rule(sa, inbound);
+			continue;
+		}
+
 		if (sa->aead_algo == RTE_CRYPTO_AEAD_AES_GCM) {
 			iv_length = 16;
 
-			if (inbound) {
-				sa_ctx->xf[idx].a.type = RTE_CRYPTO_SYM_XFORM_AEAD;
-				sa_ctx->xf[idx].a.aead.algo = sa->aead_algo;
-				sa_ctx->xf[idx].a.aead.key.data = sa->cipher_key;
-				sa_ctx->xf[idx].a.aead.key.length =
-					sa->cipher_key_len;
-				sa_ctx->xf[idx].a.aead.op =
-					RTE_CRYPTO_AEAD_OP_DECRYPT;
-				sa_ctx->xf[idx].a.next = NULL;
-				sa_ctx->xf[idx].a.aead.iv.offset = IV_OFFSET;
-				sa_ctx->xf[idx].a.aead.iv.length = iv_length;
-				sa_ctx->xf[idx].a.aead.aad_length =
-					sa->aad_len;
-				sa_ctx->xf[idx].a.aead.digest_length =
-					sa->digest_len;
-			} else { /* outbound */
-				sa_ctx->xf[idx].a.type = RTE_CRYPTO_SYM_XFORM_AEAD;
-				sa_ctx->xf[idx].a.aead.algo = sa->aead_algo;
-				sa_ctx->xf[idx].a.aead.key.data = sa->cipher_key;
-				sa_ctx->xf[idx].a.aead.key.length =
-					sa->cipher_key_len;
-				sa_ctx->xf[idx].a.aead.op =
-					RTE_CRYPTO_AEAD_OP_ENCRYPT;
-				sa_ctx->xf[idx].a.next = NULL;
-				sa_ctx->xf[idx].a.aead.iv.offset = IV_OFFSET;
-				sa_ctx->xf[idx].a.aead.iv.length = iv_length;
-				sa_ctx->xf[idx].a.aead.aad_length =
-					sa->aad_len;
-				sa_ctx->xf[idx].a.aead.digest_length =
-					sa->digest_len;
-			}
+			sa_ctx->xf[idx].a.type = RTE_CRYPTO_SYM_XFORM_AEAD;
+			sa_ctx->xf[idx].a.aead.algo = sa->aead_algo;
+			sa_ctx->xf[idx].a.aead.key.data = sa->cipher_key;
+			sa_ctx->xf[idx].a.aead.key.length =
+				sa->cipher_key_len;
+			sa_ctx->xf[idx].a.aead.op = (inbound == 1) ?
+				RTE_CRYPTO_AEAD_OP_DECRYPT :
+				RTE_CRYPTO_AEAD_OP_ENCRYPT;
+			sa_ctx->xf[idx].a.next = NULL;
+			sa_ctx->xf[idx].a.aead.iv.offset = IV_OFFSET;
+			sa_ctx->xf[idx].a.aead.iv.length = iv_length;
+			sa_ctx->xf[idx].a.aead.aad_length =
+				sa->aad_len;
+			sa_ctx->xf[idx].a.aead.digest_length =
+				sa->digest_len;
 
 			sa->xforms = &sa_ctx->xf[idx].a;
 
-- 
2.9.3

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

* Re: [dpdk-dev] [RFC PATCH 1/4] rte_security: API definitions
  2017-08-15  6:35         ` [dpdk-dev] [RFC PATCH 1/4] rte_security: API definitions Akhil Goyal
@ 2017-08-15 11:04           ` Radu Nicolau
  2017-08-16  7:39             ` Akhil Goyal
  0 siblings, 1 reply; 37+ messages in thread
From: Radu Nicolau @ 2017-08-15 11:04 UTC (permalink / raw)
  To: Akhil Goyal, dev, declan.doherty, thomas, aviadye, borisp,
	pablo.de.lara.guarch, sergio.gonzalez.monroy
  Cc: hemant.agrawal, sandeep.malik


On 8/15/2017 7:35 AM, Akhil Goyal wrote:
> Detailed description is added in the coverletter
>
> Signed-off-by: Akhil Goyal <akhil.goyal@nxp.com>
> ---
>   lib/librte_cryptodev/rte_security.c | 171 +++++++++++++++
>   lib/librte_cryptodev/rte_security.h | 409 ++++++++++++++++++++++++++++++++++++
>   2 files changed, 580 insertions(+)
>   create mode 100644 lib/librte_cryptodev/rte_security.c
>   create mode 100644 lib/librte_cryptodev/rte_security.h
>
> diff --git a/lib/librte_cryptodev/rte_security.c b/lib/librte_cryptodev/rte_security.c
> new file mode 100644
> index 0000000..7c73c93
> --- /dev/null
> +++ b/lib/librte_cryptodev/rte_security.c
> @@ -0,0 +1,171 @@
> +/*-
> + *   BSD LICENSE
> + *
> + *   Copyright 2017 NXP.
> + *
> + *   Redistribution and use in source and binary forms, with or without
> + *   modification, are permitted provided that the following conditions
> + *   are met:
> + *
> + *     * Redistributions of source code must retain the above copyright
> + *       notice, this list of conditions and the following disclaimer.
> + *     * Redistributions in binary form must reproduce the above copyright
> + *       notice, this list of conditions and the following disclaimer in
> + *       the documentation and/or other materials provided with the
> + *       distribution.
> + *     * Neither the name of NXP nor the names of its
> + *       contributors may be used to endorse or promote products derived
> + *       from this software without specific prior written permission.
> + *
> + *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
> + *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
> + *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
> + *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
> + *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
> + *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
> + *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
> + *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
> + *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
> + *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
> + *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
> + */
> +
> +#include <rte_log.h>
> +#include <rte_debug.h>
> +#include <rte_dev.h>
> +#include <rte_memory.h>
> +#include <rte_memcpy.h>
> +#include <rte_launch.h>
> +#include <rte_common.h>
> +#include <rte_mempool.h>
> +#include <rte_malloc.h>
> +#include <rte_errno.h>
> +
> +#include "rte_crypto.h"
> +#include "rte_cryptodev_pmd.h"
> +#include "rte_security.h"
> +#include "rte_ethdev.h"
> +#include "rte_cryptodev.h"
> +
> +
> +struct rte_security_session *
> +rte_security_session_create(struct rte_mempool *mp)
> +{
> +	struct rte_security_session *sess;
> +
> +	/* Allocate a session structure from the session pool */
> +	if (rte_mempool_get(mp, (void *)&sess)) {
> +		CDEV_LOG_ERR("couldn't get object from session mempool");
> +		return NULL;
> +	}
> +
> +	/* Clear device session pointer */
> +	memset(sess, 0, (sizeof(void *) *
> +		RTE_MAX(rte_eth_dev_count(), rte_cryptodev_count())));
> +
> +	return sess;
> +}
> +
> +int
> +rte_security_session_init(uint16_t dev_id,
> +			  struct rte_security_session *sess,
> +			  struct rte_security_sess_conf *conf,
> +			  struct rte_mempool *mp)
> +{
> +	struct rte_cryptodev *cdev = NULL;
> +	struct rte_eth_dev *dev = NULL;
> +	uint8_t index;
> +	int ret;
> +
> +	if (sess == NULL || conf == NULL)
> +		return -EINVAL;
> +
> +	switch (conf->action_type) {
> +	case RTE_SECURITY_SESS_CRYPTO_PROTO_OFFLOAD:
> +		if (!rte_cryptodev_pmd_is_valid_dev(dev_id))
> +			return -EINVAL;
> +		cdev = rte_cryptodev_pmd_get_dev(dev_id);
> +		index = cdev->driver_id;
> +		if (sess->sess_private_data[index] == NULL) {
> +			ret = cdev->sec_ops->session_configure(cdev, conf, sess, mp);
> +			if (ret < 0) {
> +				CDEV_LOG_ERR(
> +					"cdev_id %d failed to configure session details",
> +					dev_id);
> +				return ret;
> +			}
> +		}
> +		break;
> +	case RTE_SECURITY_SESS_ETH_INLINE_CRYPTO:
> +	case RTE_SECURITY_SESS_ETH_PROTO_OFFLOAD:
> +		dev = &rte_eth_devices[dev_id];
> +		index = dev->data->port_id;
> +		if (sess->sess_private_data[index] == NULL) {
> +//			ret = dev->sec_ops->session_configure(dev, conf, sess, mp);
> +//			if (ret < 0) {
> +//				CDEV_LOG_ERR(
> +//					"dev_id %d failed to configure session details",
> +//					dev_id);
> +//				return ret;
> +//			}
The commented lines above suggests that also eth devices will have a 
sec_ops field, (which makes sense). Is this correct?
Also, if the above is correct, session_configure and session_clear 
should accept both crypto and eth devices as first parameter.
> +		}
> +		break;
> +	default:
> +		return -EINVAL;
> +	}
> +
> +	return 0;
> +}
> +
> +int
> +rte_security_session_free(struct rte_security_session *sess)
> +{
> +	uint8_t i, nb_drivers = RTE_MAX(rte_eth_dev_count(),
> +					rte_cryptodev_count());
> +	void *sess_priv;
> +	struct rte_mempool *sess_mp;
> +
> +	if (sess == NULL)
> +		return -EINVAL;
> +
> +	/* Check that all device private data has been freed */
> +	for (i = 0; i < nb_drivers; i++) {
> +		sess_priv = get_sec_session_private_data(sess, i);
> +		if (sess_priv != NULL)
> +			return -EBUSY;
> +	}
> +
> +	/* Return session to mempool */
> +	sess_mp = rte_mempool_from_obj(sess);
> +	rte_mempool_put(sess_mp, sess);
> +
> +	return 0;
> +}
> +
> +int
> +rte_security_session_clear(uint8_t dev_id,
> +		enum rte_security_session_action_type action_type,
> +		struct rte_security_session *sess)
> +{
> +	struct rte_cryptodev *cdev = NULL;
> +	struct rte_eth_dev *dev = NULL;
> +	switch (action_type) {
> +	case RTE_SECURITY_SESS_CRYPTO_PROTO_OFFLOAD:
> +		cdev =  rte_cryptodev_pmd_get_dev(dev_id);
> +		if (cdev == NULL || sess == NULL)
> +			return -EINVAL;
> +		cdev->sec_ops->session_clear(cdev, sess);
> +		break;
> +	case RTE_SECURITY_SESS_ETH_INLINE_CRYPTO:
> +	case RTE_SECURITY_SESS_ETH_PROTO_OFFLOAD:
> +		dev = &rte_eth_devices[dev_id];
> +		if (dev == NULL || sess == NULL)
> +			return -EINVAL;
> +//		dev->dev_ops->session_clear(dev, sess);
> +		break;
> +	default:
> +		return -EINVAL;
> +	}
> +
> +	return 0;
> +}
> diff --git a/lib/librte_cryptodev/rte_security.h b/lib/librte_cryptodev/rte_security.h
> new file mode 100644
> index 0000000..9747d5e
> --- /dev/null
> +++ b/lib/librte_cryptodev/rte_security.h
> @@ -0,0 +1,409 @@
> +#ifndef _RTE_SECURITY_H_
> +#define _RTE_SECURITY_H_
> +
> +/**
> + * @file rte_security.h
> + *
> + * RTE Security Common Definitions
> + *
> + */
> +
> +#ifdef __cplusplus
> +extern "C" {
> +#endif
> +
> +#include <netinet/in.h>
> +#include <netinet/ip.h>
> +#include <netinet/ip6.h>
> +
> +#include <rte_mbuf.h>
> +#include <rte_memory.h>
> +#include <rte_mempool.h>
> +#include <rte_common.h>
> +#include <rte_crypto.h>
> +
> +/** IPSec protocol mode */
> +enum rte_security_conf_ipsec_sa_mode {
> +	RTE_SECURITY_IPSEC_SA_MODE_TRANSPORT,
> +	/**< IPSec Transport mode */
> +	RTE_SECURITY_IPSEC_SA_MODE_TUNNEL,
> +	/**< IPSec Tunnel mode */
> +};
> +
> +/** IPSec Protocol */
> +enum rte_security_conf_ipsec_sa_protocol {
> +	RTE_SECURITY_IPSEC_SA_PROTO_AH,
> +	/**< AH protocol */
> +	RTE_SECURITY_IPSEC_SA_PROTO_ESP,
> +	/**< ESP protocol */
> +};
> +
> +/** IPSEC tunnel type */
> +enum rte_security_ipsec_tunnel_type {
> +	RTE_SECURITY_IPSEC_TUNNEL_IPV4 = 0,
> +	/**< Outer header is IPv4 */
> +	RTE_SECURITY_IPSEC_TUNNEL_IPV6,
> +	/**< Outer header is IPv6 */
> +};
> +
> +/**
> + * IPSEC tunnel parameters
> + *
> + * These parameters are used to build outbound tunnel headers.
> + */
> +struct rte_security_ipsec_tunnel_param {
> +	enum rte_security_ipsec_tunnel_type type;
> +	/**< Tunnel type: IPv4 or IPv6 */
> +
> +	union {
> +		struct {
> +			struct in_addr src_ip;
> +			/**< IPv4 source address */
> +			struct in_addr dst_ip;
> +			/**< IPv4 destination address */
> +			uint8_t dscp;
> +			/**< IPv4 Differentiated Services Code Point */
> +			uint8_t df;
> +			/**< IPv4 Don't Fragment bit */
> +			uint8_t ttl;
> +			/**< IPv4 Time To Live */
> +		} ipv4; /**< IPv4 header parameters */
> +
> +		struct {
> +			struct in6_addr *src_addr;
> +			/**< IPv6 source address */
> +			struct in6_addr *dst_addr;
> +			/**< IPv6 destination address */
> +			uint8_t dscp;
> +			/**< IPv6 Differentiated Services Code Point */
> +			uint32_t flabel;
> +			/**< IPv6 flow label */
> +			uint8_t hlimit;
> +			/**< IPv6 hop limit */
> +		} ipv6; /**< IPv6 header parameters */
> +	}; /**< Various tunnel parameters */
> +};
> +
> +/**
> + * IPSEC SA option flags
> + */
> +struct rte_security_ipsec_sa_options {
> +	/** Extended Sequence Numbers (ESN)
> +	  *
> +	  * * 1: Use extended (64 bit) sequence numbers
> +	  * * 0: Use normal sequence numbers
> +	  */
> +	uint32_t esn : 1;
> +
> +	/** UDP encapsulation
> +	  *
> +	  * * 1: Do UDP encapsulation/decapsulation so that IPSEC packets can
> +	  *      traverse through NAT boxes.
> +	  * * 0: No UDP encapsulation
> +	  */
> +	uint32_t udp_encap : 1;
> +
> +	/** Copy DSCP bits
> +	  *
> +	  * * 1: Copy IPv4 or IPv6 DSCP bits from inner IP header to
> +	  *      the outer IP header in encapsulation, and vice versa in
> +	  *      decapsulation.
> +	  * * 0: Use values from odp_ipsec_tunnel_param_t in encapsulation and
> +	  *      do not change DSCP field in decapsulation.
> +	  */
> +	uint32_t copy_dscp : 1;
> +
> +	/** Copy IPv6 Flow Label
> +	  *
> +	  * * 1: Copy IPv6 flow label from inner IPv6 header to the
> +	  *      outer IPv6 header.
> +	  * * 0: Use value from odp_ipsec_tunnel_param_t
> +	  */
> +	uint32_t copy_flabel : 1;
> +
> +	/** Copy IPv4 Don't Fragment bit
> +	  *
> +	  * * 1: Copy the DF bit from the inner IPv4 header to the outer
> +	  *      IPv4 header.
> +	  * * 0: Use value from odp_ipsec_tunnel_param_t
> +	  */
> +	uint32_t copy_df : 1;
> +
> +	/** Decrement inner packet Time To Live (TTL) field
> +	  *
> +	  * * 1: In tunnel mode, decrement inner packet IPv4 TTL or
> +	  *      IPv6 Hop Limit after tunnel decapsulation, or before tunnel
> +	  *      encapsulation.
> +	  * * 0: Inner packet is not modified.
> +	  */
> +	uint32_t dec_ttl : 1;
> +
> +};
> +
> +/** IPSec Operations */
> +enum rte_security_ipsec_operation {
> +	RTE_SECURITY_IPSEC_OP_ENCAP,
> +	/**< Encrypt and generate digest */
> +	RTE_SECURITY_IPSEC_OP_DECAP,
> +	/**< Verify digest and decrypt */
> +};
> +
> +/**
> + * IPSec Setup Data.
> + *
> + * This structure contains data relating to IPSec
> + * used to create a session.
> + */
> +struct rte_security_ipsec_xform {
> +	enum rte_security_ipsec_operation op;
> +	/**< IPSec operation - Encap or Decap */
> +	unsigned int spi;
> +	/**< SA security parameter index */
> +	enum rte_crypto_cipher_algorithm cipher_alg;
> +	/**< Cipher Algorithm */
> +	struct {
> +		uint8_t *data;  /**< pointer to key data */
> +		size_t length;   /**< key length in bytes */
> +	} cipher_key;
> +	enum rte_crypto_auth_algorithm auth_alg;
> +	/**< Authentication Algorithm */
> +	struct {
> +		uint8_t *data;  /**< pointer to key data */
> +		size_t length;   /**< key length in bytes */
> +	} auth_key;
> +	uint32_t salt;	/**< salt for this SA */
> +	enum rte_security_conf_ipsec_sa_mode mode;
> +	/**< IPsec SA Mode - transport/tunnel */
> +	enum rte_security_conf_ipsec_sa_protocol proto;
> +	/**< IPsec SA Protocol - AH/ESP */
> +	struct rte_security_ipsec_tunnel_param tunnel;
> +	/**< Tunnel parameters, NULL for transport mode */
> +	struct rte_security_ipsec_sa_options options;
> +	/**< various SA options */
> +};
> +
> +/** IPsec Security Session Configuration */
> +struct rte_security_dtls_xform {
> +	/** To be Filled */
> +};
> +
> +/** IPsec Security Session Configuration */
> +struct rte_security_macsec_xform {
> +	/** To be Filled */
> +};
> +
> +/**< Security Session action type */
> +enum rte_security_session_action_type {
> +	RTE_SECURITY_SESS_NONE,
> +	/**< Non protocol offload. Application need to manage everything */
> +	RTE_SECURITY_SESS_ETH_INLINE_CRYPTO,
> +	/**< Crypto operations are performed by Network interface */
> +	RTE_SECURITY_SESS_ETH_PROTO_OFFLOAD,
> +	/**< Crypto operations with protocol support are performed
> +	 * by Network/ethernet device.
> +	 */
> +	RTE_SECURITY_SESS_CRYPTO_PROTO_OFFLOAD,
> +	/**< Crypto operations with protocol support are performed
> +	 * by Crypto device.
> +	 */
> +};
> +
> +/** Security Session Protocols */
> +enum rte_security_sess_protocol {
> +	RTE_SEC_CONF_DTLS,
> +	/**< DTLS Protocol */
> +	RTE_SEC_CONF_IPSEC,
> +	/**< IPSec Protocol */
> +	RTE_SEC_CONF_MACSEC,
> +	/**< MACSec Protocol */
> +};
> +
> +/**
> + * Security Session Configuration
> + */
> +struct rte_security_sess_conf {
> +	enum rte_security_session_action_type action_type;
> +	/**< Type of action to be performed on the session */
> +	enum rte_security_sess_protocol protocol;
> +	/**< Security protocol to be configured */
> +
> +	union {
> +		struct rte_security_ipsec_xform *ipsec_xform;
> +		struct rte_security_dtls_xform *dtls_xform;
> +		struct rte_security_macsec_xform *macsec_xform;
> +	};
> +	/**< Configuration parameters for security session */
> +};
> +
> +struct rte_security_session {
> +	__extension__ void *sess_private_data[0];
> +	/**< Private session material */
> +};
> +
> +/**
> + * Create Security session header (generic with no private data)
> + *
> + * @param   mempool    Session mempool to allocate session objects from
> + * @return
> + *  - On success, pointer to session
> + *  - On failure, NULL
> + */
> +struct rte_security_session *
> +rte_security_session_create(struct rte_mempool *mempool);
> +
> +/**
> + * Fill out private data for the device, based on its device id and name.
> + *
> + * @param   dev_id   Device id that we want the session to be used on
> + * @param   dev_name Device name for which session is to be used
> + * @param   sess     Session where the private data will be attached to
> + * @param   conf     Security config to apply on flow
> + *                   processed with this session
> + * @param   mempool  Mempool where the private data is allocated.
> + *
> + * @return
> + *  - On success, zero.
> + *  - On failure, a negative value.
> + */
> +int
> +rte_security_session_init(uint16_t dev_id,
> +			  struct rte_security_session *sess,
> +			  struct rte_security_sess_conf *conf,
> +			  struct rte_mempool *mempool);
> +
> +/**
> + * Frees Security session header, after checking that all
> + * the device private data has been freed, returning it
> + * to its original mempool.
> + *
> + * @param   sess     Session header to be freed.
> + *
> + * @return
> + *  - 0 if successful.
> + *  - -EINVAL if session is NULL.
> + *  - -EBUSY if not all device private data has been freed.
> + */
> +int
> +rte_security_session_free(struct rte_security_session *sess);
> +
> +/**
> + * Frees private data for the device id, based on its device name,
> + * returning it to its mempool.
> + *
> + * @param   dev_id	ID of device that uses the session.
> + * @param   action_type	Action type for Security operation.
> + * @param   sess	Session containing the reference to the private data
> + *
> + * @return
> + *  - 0 if successful.
> + *  - -EINVAL if device is invalid or session is NULL.
> + */
> +int
> +rte_security_session_clear(uint8_t dev_id,
> +			   enum rte_security_session_action_type action_type,
> +			   struct rte_security_session *sess);
> +
> +/**
> + * Attach a session to a symmetric crypto operation
> + *
> + * @param	sym_op	crypto operation
> + * @param	sess	security session
> + */
> +static inline int
> +__rte_security_attach_session(struct rte_crypto_sym_op *sym_op,
> +			      struct rte_security_session *sess)
> +{
> +	sym_op->sec_session = sess;
> +
> +	return 0;
> +}
> +
> +static inline void *
> +get_sec_session_private_data(const struct rte_security_session *sess,
> +		uint8_t driver_id) {
> +	return sess->sess_private_data[driver_id];
> +}
> +
> +static inline void
> +set_sec_session_private_data(struct rte_security_session *sess,
> +		uint8_t driver_id, void *private_data)
> +{
> +	sess->sess_private_data[driver_id] = private_data;
> +}
> +
> +/**
> + * Attach a session to a crypto operation.
> + * This API is needed only in case of RTE_SECURITY_SESS_CRYPTO_PROTO_OFFLOAD
> + * For other rte_security_session_action_type, ol_flags in rte_mbuf may be
> + * defined to perform security operations.
> + *
> + * @param	op	crypto operation
> + * @param	sess	security session
> + */
> +static inline int
> +rte_security_attach_session(struct rte_crypto_op *op,
> +			    struct rte_security_session *sess)
> +{
> +	if (unlikely(op->type != RTE_CRYPTO_OP_TYPE_SYMMETRIC))
> +		return -1;
> +
> +	op->sess_type = RTE_CRYPTO_OP_WITH_SESSION;
> +
> +	return __rte_security_attach_session(op->sym, sess);
> +}
> +
> +/**
> + * Security Capability
> + */
> +struct rte_security_capabilities {
> +	enum rte_security_sess_protocol protocol;
> +	RTE_STD_C11
> +	union {
> +		struct {
> +			enum rte_crypto_auth_algorithm a_algo;
> +			/**< authentication algorithm */
> +			enum rte_crypto_cipher_algorithm c_algo;
> +			/**< cipher algorithm */
> +			uint16_t block_size;
> +			/**< algorithm block size */
> +			struct rte_crypto_param_range c_key_size;
> +			/**< cipher key size range */
> +			struct rte_crypto_param_range a_key_size;
> +			/**< auth key size range */
> +			struct rte_crypto_param_range digest_size;
> +			/**< digest size range */
> +			struct rte_crypto_param_range iv_size;
> +			/**< Initialisation vector data size range */
> +		} ipsec;
> +		/**< IPSEC transform capabilities */
> +		struct {
> +			/* To be Filled */
> +		} dtls;
> +		/**< DTLS transform capabilities */
> +		struct {
> +			/* To be Filled */
> +		} macsec;
> +		/**< MACSEC transform capabilities */
> +	};
> +};
> +
> +/**
> + *  Provide capabilities available for defined device and algorithm
> + *
> + * @param	dev_id		The identifier of the device.
> + * @param	dev_name	Device name for which capability is needed
> + * @param	protocol	Protocol for which capability is required
> + *
> + * @return
> + *   - Return description of the security capability if exist.
> + *   - Return NULL if the capability not exist.
> + */
> +const struct rte_security_capabilities *
> +rte_security_capability_get(uint8_t dev_id, char *dev_name,
> +		enum rte_security_sess_protocol protocol);
> +
> +#ifdef __cplusplus
> +}
> +#endif
> +
> +#endif /* _RTE_SECURITY_H_ */

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

* Re: [dpdk-dev] [RFC PATCH 1/4] rte_security: API definitions
  2017-08-15 11:04           ` Radu Nicolau
@ 2017-08-16  7:39             ` Akhil Goyal
  2017-08-16 15:40               ` Hemant Agrawal
  0 siblings, 1 reply; 37+ messages in thread
From: Akhil Goyal @ 2017-08-16  7:39 UTC (permalink / raw)
  To: Radu Nicolau, dev, declan.doherty, thomas, aviadye, borisp,
	pablo.de.lara.guarch, sergio.gonzalez.monroy
  Cc: hemant.agrawal, sandeep.malik

On 8/15/2017 4:34 PM, Radu Nicolau wrote:
> 
> On 8/15/2017 7:35 AM, Akhil Goyal wrote:
>> Detailed description is added in the coverletter
>>
>> Signed-off-by: Akhil Goyal <akhil.goyal@nxp.com>
>> ---
>>   lib/librte_cryptodev/rte_security.c | 171 +++++++++++++++
>>   lib/librte_cryptodev/rte_security.h | 409 
>> ++++++++++++++++++++++++++++++++++++
>>   2 files changed, 580 insertions(+)
>>   create mode 100644 lib/librte_cryptodev/rte_security.c
>>   create mode 100644 lib/librte_cryptodev/rte_security.h
>>

>> +int
>> +rte_security_session_init(uint16_t dev_id,
>> +              struct rte_security_session *sess,
>> +              struct rte_security_sess_conf *conf,
>> +              struct rte_mempool *mp)
>> +{
>> +    struct rte_cryptodev *cdev = NULL;
>> +    struct rte_eth_dev *dev = NULL;
>> +    uint8_t index;
>> +    int ret;
>> +
>> +    if (sess == NULL || conf == NULL)
>> +        return -EINVAL;
>> +
>> +    switch (conf->action_type) {
>> +    case RTE_SECURITY_SESS_CRYPTO_PROTO_OFFLOAD:
>> +        if (!rte_cryptodev_pmd_is_valid_dev(dev_id))
>> +            return -EINVAL;
>> +        cdev = rte_cryptodev_pmd_get_dev(dev_id);
>> +        index = cdev->driver_id;
>> +        if (sess->sess_private_data[index] == NULL) {
>> +            ret = cdev->sec_ops->session_configure(cdev, conf, sess, 
>> mp);
>> +            if (ret < 0) {
>> +                CDEV_LOG_ERR(
>> +                    "cdev_id %d failed to configure session details",
>> +                    dev_id);
>> +                return ret;
>> +            }
>> +        }
>> +        break;
>> +    case RTE_SECURITY_SESS_ETH_INLINE_CRYPTO:
>> +    case RTE_SECURITY_SESS_ETH_PROTO_OFFLOAD:
>> +        dev = &rte_eth_devices[dev_id];
>> +        index = dev->data->port_id;
>> +        if (sess->sess_private_data[index] == NULL) {
>> +//            ret = dev->sec_ops->session_configure(dev, conf, sess, 
>> mp);
>> +//            if (ret < 0) {
>> +//                CDEV_LOG_ERR(
>> +//                    "dev_id %d failed to configure session details",
>> +//                    dev_id);
>> +//                return ret;
>> +//            }
> The commented lines above suggests that also eth devices will have a 
> sec_ops field, (which makes sense). Is this correct?
> Also, if the above is correct, session_configure and session_clear 
> should accept both crypto and eth devices as first parameter.

Yes you are correct both these ops should accept void *dev and 
internally in the driver should typecast to respective device.
Please consider the following diff over this patch


diff --git a/lib/librte_cryptodev/rte_cryptodev_pmd.h 
b/lib/librte_cryptodev/rte_cryptodev_pmd.h
index 219fba6..ab3ecf7 100644
--- a/lib/librte_cryptodev/rte_cryptodev_pmd.h
+++ b/lib/librte_cryptodev/rte_cryptodev_pmd.h
@@ -371,7 +371,7 @@ struct rte_cryptodev_ops {
   *  - Returns -ENOTSUP if crypto device does not support the crypto 
transform.
   *  - Returns -ENOMEM if the private session could not be allocated.
   */
-typedef int (*security_configure_session_t)(struct rte_cryptodev *dev,
+typedef int (*security_configure_session_t)(void *dev,
                 struct rte_security_sess_conf *conf,
                 struct rte_security_session *sess,
                 struct rte_mempool *mp);
@@ -382,7 +382,7 @@ typedef int (*security_configure_session_t)(struct 
rte_cryptodev *dev,
   * @param      dev             Crypto device pointer
   * @param      sess            Security session structure
   */
-typedef void (*security_free_session_t)(struct rte_cryptodev *dev,
+typedef void (*security_free_session_t)(void *dev,
                 struct rte_security_session *sess);

  /** Security operations function pointer table */
diff --git a/lib/librte_cryptodev/rte_security.c 
b/lib/librte_cryptodev/rte_security.c
index 7c73c93..a7558bb 100644
--- a/lib/librte_cryptodev/rte_security.c
+++ b/lib/librte_cryptodev/rte_security.c
@@ -87,7 +87,8 @@ rte_security_session_init(uint16_t dev_id,
                 cdev = rte_cryptodev_pmd_get_dev(dev_id);
                 index = cdev->driver_id;
                 if (sess->sess_private_data[index] == NULL) {
-                       ret = cdev->sec_ops->session_configure(cdev, 
conf, sess, mp);
+                       ret = cdev->sec_ops->session_configure((void *)cdev,
+                                                       conf, sess, mp);
                         if (ret < 0) {
                                 CDEV_LOG_ERR(
                                         "cdev_id %d failed to configure 
session details",
@@ -101,7 +102,8 @@ rte_security_session_init(uint16_t dev_id,
                 dev = &rte_eth_devices[dev_id];
                 index = dev->data->port_id;
                 if (sess->sess_private_data[index] == NULL) {
-//                     ret = dev->sec_ops->session_configure(dev, conf, 
sess, mp);
+//                     ret = dev->sec_ops->session_configure((void *)dev,
+//                                                     conf, sess, mp);

Thanks,
Akhil

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

* Re: [dpdk-dev] [RFC PATCH 1/4] rte_security: API definitions
  2017-08-16  7:39             ` Akhil Goyal
@ 2017-08-16 15:40               ` Hemant Agrawal
  2017-08-18  9:16                 ` Thomas Monjalon
  0 siblings, 1 reply; 37+ messages in thread
From: Hemant Agrawal @ 2017-08-16 15:40 UTC (permalink / raw)
  To: Akhil Goyal, Radu Nicolau, dev, declan.doherty, thomas, aviadye,
	borisp, pablo.de.lara.guarch, sergio.gonzalez.monroy
  Cc: Sandeep Malik, techboard

Hi Thomas,
	Can we get a next-security tree to do development around this proposal?

Also, we can discuss about this proposal in general in next techboard meeting.

Regards,
Hemant
	

> -----Original Message-----
> From: Akhil Goyal [mailto:akhil.goyal@nxp.com]
> Sent: Wednesday, August 16, 2017 1:10 PM
> To: Radu Nicolau <radu.nicolau@intel.com>; dev@dpdk.org;
> declan.doherty@intel.com; thomas@monjalon.net;
> aviadye@mellanox.com; borisp@mellanox.com;
> pablo.de.lara.guarch@intel.com; sergio.gonzalez.monroy@intel.com
> Cc: Hemant Agrawal <hemant.agrawal@nxp.com>; Sandeep Malik
> <sandeep.malik@nxp.com>
> Subject: Re: [RFC PATCH 1/4] rte_security: API definitions
> 
> On 8/15/2017 4:34 PM, Radu Nicolau wrote:
> >
> > On 8/15/2017 7:35 AM, Akhil Goyal wrote:
> >> Detailed description is added in the coverletter
> >>
> >> Signed-off-by: Akhil Goyal <akhil.goyal@nxp.com>
> >> ---
> >>   lib/librte_cryptodev/rte_security.c | 171 +++++++++++++++
> >>   lib/librte_cryptodev/rte_security.h | 409
> >> ++++++++++++++++++++++++++++++++++++
> >>   2 files changed, 580 insertions(+)
> >>   create mode 100644 lib/librte_cryptodev/rte_security.c
> >>   create mode 100644 lib/librte_cryptodev/rte_security.h
> >>
> 
> >> +int
> >> +rte_security_session_init(uint16_t dev_id,
> >> +              struct rte_security_session *sess,
> >> +              struct rte_security_sess_conf *conf,
> >> +              struct rte_mempool *mp) {
> >> +    struct rte_cryptodev *cdev = NULL;
> >> +    struct rte_eth_dev *dev = NULL;
> >> +    uint8_t index;
> >> +    int ret;
> >> +
> >> +    if (sess == NULL || conf == NULL)
> >> +        return -EINVAL;
> >> +
> >> +    switch (conf->action_type) {
> >> +    case RTE_SECURITY_SESS_CRYPTO_PROTO_OFFLOAD:
> >> +        if (!rte_cryptodev_pmd_is_valid_dev(dev_id))
> >> +            return -EINVAL;
> >> +        cdev = rte_cryptodev_pmd_get_dev(dev_id);
> >> +        index = cdev->driver_id;
> >> +        if (sess->sess_private_data[index] == NULL) {
> >> +            ret = cdev->sec_ops->session_configure(cdev, conf, sess,
> >> mp);
> >> +            if (ret < 0) {
> >> +                CDEV_LOG_ERR(
> >> +                    "cdev_id %d failed to configure session details",
> >> +                    dev_id);
> >> +                return ret;
> >> +            }
> >> +        }
> >> +        break;
> >> +    case RTE_SECURITY_SESS_ETH_INLINE_CRYPTO:
> >> +    case RTE_SECURITY_SESS_ETH_PROTO_OFFLOAD:
> >> +        dev = &rte_eth_devices[dev_id];
> >> +        index = dev->data->port_id;
> >> +        if (sess->sess_private_data[index] == NULL) {
> >> +//            ret = dev->sec_ops->session_configure(dev, conf, sess,
> >> mp);
> >> +//            if (ret < 0) {
> >> +//                CDEV_LOG_ERR(
> >> +//                    "dev_id %d failed to configure session details",
> >> +//                    dev_id);
> >> +//                return ret;
> >> +//            }
> > The commented lines above suggests that also eth devices will have a
> > sec_ops field, (which makes sense). Is this correct?
> > Also, if the above is correct, session_configure and session_clear
> > should accept both crypto and eth devices as first parameter.
> 
> Yes you are correct both these ops should accept void *dev and internally in
> the driver should typecast to respective device.
> Please consider the following diff over this patch
> 
> 
> diff --git a/lib/librte_cryptodev/rte_cryptodev_pmd.h
> b/lib/librte_cryptodev/rte_cryptodev_pmd.h
> index 219fba6..ab3ecf7 100644
> --- a/lib/librte_cryptodev/rte_cryptodev_pmd.h
> +++ b/lib/librte_cryptodev/rte_cryptodev_pmd.h
> @@ -371,7 +371,7 @@ struct rte_cryptodev_ops {
>    *  - Returns -ENOTSUP if crypto device does not support the crypto
> transform.
>    *  - Returns -ENOMEM if the private session could not be allocated.
>    */
> -typedef int (*security_configure_session_t)(struct rte_cryptodev *dev,
> +typedef int (*security_configure_session_t)(void *dev,
>                  struct rte_security_sess_conf *conf,
>                  struct rte_security_session *sess,
>                  struct rte_mempool *mp);
> @@ -382,7 +382,7 @@ typedef int (*security_configure_session_t)(struct
> rte_cryptodev *dev,
>    * @param      dev             Crypto device pointer
>    * @param      sess            Security session structure
>    */
> -typedef void (*security_free_session_t)(struct rte_cryptodev *dev,
> +typedef void (*security_free_session_t)(void *dev,
>                  struct rte_security_session *sess);
> 
>   /** Security operations function pointer table */
> diff --git a/lib/librte_cryptodev/rte_security.c
> b/lib/librte_cryptodev/rte_security.c
> index 7c73c93..a7558bb 100644
> --- a/lib/librte_cryptodev/rte_security.c
> +++ b/lib/librte_cryptodev/rte_security.c
> @@ -87,7 +87,8 @@ rte_security_session_init(uint16_t dev_id,
>                  cdev = rte_cryptodev_pmd_get_dev(dev_id);
>                  index = cdev->driver_id;
>                  if (sess->sess_private_data[index] == NULL) {
> -                       ret = cdev->sec_ops->session_configure(cdev,
> conf, sess, mp);
> +                       ret = cdev->sec_ops->session_configure((void *)cdev,
> +                                                       conf, sess, mp);
>                          if (ret < 0) {
>                                  CDEV_LOG_ERR(
>                                          "cdev_id %d failed to configure
> session details",
> @@ -101,7 +102,8 @@ rte_security_session_init(uint16_t dev_id,
>                  dev = &rte_eth_devices[dev_id];
>                  index = dev->data->port_id;
>                  if (sess->sess_private_data[index] == NULL) {
> -//                     ret = dev->sec_ops->session_configure(dev, conf,
> sess, mp);
> +//                     ret = dev->sec_ops->session_configure((void *)dev,
> +//                                                     conf, sess, mp);
> 
> Thanks,
> Akhil

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

* Re: [dpdk-dev] [RFC PATCH 1/4] rte_security: API definitions
  2017-08-16 15:40               ` Hemant Agrawal
@ 2017-08-18  9:16                 ` Thomas Monjalon
  2017-08-18 12:20                   ` Hemant Agrawal
  2017-08-21 10:32                   ` Boris Pismenny
  0 siblings, 2 replies; 37+ messages in thread
From: Thomas Monjalon @ 2017-08-18  9:16 UTC (permalink / raw)
  To: Hemant Agrawal
  Cc: Akhil Goyal, Radu Nicolau, dev, declan.doherty, aviadye, borisp,
	pablo.de.lara.guarch, sergio.gonzalez.monroy, Sandeep Malik,
	techboard

Hi,

16/08/2017 17:40, Hemant Agrawal:
> Hi Thomas,
> 	Can we get a next-security tree to do development around this proposal?
> 
> Also, we can discuss about this proposal in general in next techboard meeting.

First question to ask:
Why not create a repository elsewhere for your trials?

The benefit of creating a dpdk.org repo is to show it as an official feature.
So the idea behind this new library must be accepted by the technical board first.

The other use of official repos is prepare pull request for subsequent releases.
Do we want to have a -next tree for IPsec development and keep it for next releases?

I think it makes sense to have a -next tree for IPsec offloading in general.
Before the techboard approves it, we need to define the name (and the scope)
of the tree, and who will be the maintainer of the tree.

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

* Re: [dpdk-dev] [RFC PATCH 1/4] rte_security: API definitions
  2017-08-18  9:16                 ` Thomas Monjalon
@ 2017-08-18 12:20                   ` Hemant Agrawal
  2017-08-21 10:32                   ` Boris Pismenny
  1 sibling, 0 replies; 37+ messages in thread
From: Hemant Agrawal @ 2017-08-18 12:20 UTC (permalink / raw)
  To: Thomas Monjalon
  Cc: Akhil Goyal, Radu Nicolau, dev, declan.doherty, aviadye, borisp,
	pablo.de.lara.guarch, sergio.gonzalez.monroy, Sandeep Malik,
	techboard

On 8/18/2017 2:46 PM, Thomas Monjalon wrote:
> Hi,
>
> 16/08/2017 17:40, Hemant Agrawal:
>> Hi Thomas,
>> 	Can we get a next-security tree to do development around this proposal?
>>
>> Also, we can discuss about this proposal in general in next techboard meeting.
>
> First question to ask:
> Why not create a repository elsewhere for your trials?
>
github is a good place, but I heard some companies (e.g. Intel) may have 
concerns over posting the work to github.

> The benefit of creating a dpdk.org repo is to show it as an official feature.
> So the idea behind this new library must be accepted by the technical board first.
>
agree. we will discuss it in next tech board meeting.

> The other use of official repos is prepare pull request for subsequent releases.
> Do we want to have a -next tree for IPsec development and keep it for next releases?
>
I believe it will be required for few release. In future, this work can 
merge and maintained in next-crypto. However this may change as we develop.

> I think it makes sense to have a -next tree for IPsec offloading in general.
> Before the techboard approves it, we need to define the name (and the scope)
> of the tree, and who will be the maintainer of the tree.
>
I see following individual maintaining it :
1. Akhil Goyal (akhil.goyal@nxp.com)
2. Boris (borisp@mellanox.com)
3. Declan Doherty (declan.doherty@intel.com)

Regards,
Hemant

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

* Re: [dpdk-dev] [RFC PATCH 1/4] rte_security: API definitions
  2017-08-18  9:16                 ` Thomas Monjalon
  2017-08-18 12:20                   ` Hemant Agrawal
@ 2017-08-21 10:32                   ` Boris Pismenny
  2017-08-21 10:54                     ` Akhil Goyal
  1 sibling, 1 reply; 37+ messages in thread
From: Boris Pismenny @ 2017-08-21 10:32 UTC (permalink / raw)
  To: Thomas Monjalon, Hemant Agrawal
  Cc: Akhil Goyal, Radu Nicolau, dev, declan.doherty, Aviad Yehezkel,
	pablo.de.lara.guarch, sergio.gonzalez.monroy, Sandeep Malik,
	techboard

For drafting, we have opened this github repository:
https://github.com/Mellanox/dpdk-next-crypto

Akhil/Hemant could you please push your rte_security patches there?

> -----Original Message-----
> From: Thomas Monjalon [mailto:thomas@monjalon.net]
> Sent: Friday, August 18, 2017 12:17
> To: Hemant Agrawal <hemant.agrawal@nxp.com>
> Cc: Akhil Goyal <akhil.goyal@nxp.com>; Radu Nicolau
> <radu.nicolau@intel.com>; dev@dpdk.org; declan.doherty@intel.com; Aviad
> Yehezkel <aviadye@mellanox.com>; Boris Pismenny <borisp@mellanox.com>;
> pablo.de.lara.guarch@intel.com; sergio.gonzalez.monroy@intel.com; Sandeep
> Malik <sandeep.malik@nxp.com>; techboard@dpdk.org
> Subject: Re: [RFC PATCH 1/4] rte_security: API definitions
> 
> Hi,
> 
> 16/08/2017 17:40, Hemant Agrawal:
> > Hi Thomas,
> > 	Can we get a next-security tree to do development around this
> proposal?
> >
> > Also, we can discuss about this proposal in general in next techboard meeting.
> 
> First question to ask:
> Why not create a repository elsewhere for your trials?
> 
> The benefit of creating a dpdk.org repo is to show it as an official feature.
> So the idea behind this new library must be accepted by the technical board
> first.
> 
> The other use of official repos is prepare pull request for subsequent releases.
> Do we want to have a -next tree for IPsec development and keep it for next
> releases?
> 
> I think it makes sense to have a -next tree for IPsec offloading in general.
> Before the techboard approves it, we need to define the name (and the scope)
> of the tree, and who will be the maintainer of the tree.

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

* Re: [dpdk-dev] [RFC PATCH 1/4] rte_security: API definitions
  2017-08-21 10:32                   ` Boris Pismenny
@ 2017-08-21 10:54                     ` Akhil Goyal
  0 siblings, 0 replies; 37+ messages in thread
From: Akhil Goyal @ 2017-08-21 10:54 UTC (permalink / raw)
  To: Boris Pismenny, Thomas Monjalon, Hemant Agrawal
  Cc: Radu Nicolau, dev, declan.doherty, Aviad Yehezkel,
	pablo.de.lara.guarch, sergio.gonzalez.monroy, Sandeep Malik,
	techboard

Hi Boris,
On 8/21/2017 4:02 PM, Boris Pismenny wrote:
> For drafting, we have opened this github repository:
> https://github.com/Mellanox/dpdk-next-crypto
> 
> Akhil/Hemant could you please push your rte_security patches there?
> 

I have pushed the patches on this tree.

Regards,
Akhil

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

* Re: [dpdk-dev] [RFC PATCH 0/1] IPSec Inline and look aside crypto offload
  2017-07-25 11:21     ` [dpdk-dev] [RFC PATCH 0/1] IPSec Inline and look aside crypto offload Akhil Goyal
                         ` (2 preceding siblings ...)
  2017-08-15  6:35       ` [dpdk-dev] [RFC PATCH v2 0/4] " Akhil Goyal
@ 2017-08-29 14:49       ` Thomas Monjalon
  2017-08-31  9:37         ` Akhil Goyal
  3 siblings, 1 reply; 37+ messages in thread
From: Thomas Monjalon @ 2017-08-29 14:49 UTC (permalink / raw)
  To: Akhil Goyal
  Cc: dev, borisp, declan.doherty, radu.nicolau, aviadye,
	sandeep.malik, hemant.agrawal, pablo.de.lara.guarch

Hi,

I try to understand how things are connected,
but too many things are not clear for someone not involved in security.

25/07/2017 13:21, Akhil Goyal:
> struct rte_security_session *
> rte_security_session_create(struct rte_mempool *mempool);

What is the usage of this mempool?

[...]
> These are very similar to what Declan proposed with a few additions.
> This can be updated further for other security protocols like MACSec and DTLS

You should avoid referencing another proposal without
- link to the proposal
- summary of the proposal

[...]
> Now, after the application configures the session using above APIs, it needs to
> attach the  session with the crypto_op in case the session is configured for
> crypto look aside protocol offload. For IPSec inline/ full protocol offload
> using NIC, the mbuf ol_flags can be set as per the RFC suggested by Boris.

Again a missing reference (link + summary).

Even worst, the RFCv2 references this v1 without copying the explanations.
It is too hard to track, or maybe it is cryptic on purpose ;)

[...]
> Now the application(ipsec-secgw) have 4 paths to decide for the data path.
> 1. Non-protocol offload (currently implemented)
> 2. IPSec inline(only crypto operations using NIC)
> 3. full protocol offload(crypto operations along with all the IPsec header
>    and trailer processing using NIC)
> 4. look aside protocol offload(single-pass encryption and authentication with
>    additional levels of protocol processing offload using crypto device)

I feel these 4 paths are the most important to discuss.
Unfortunately there are not enough detailed.
Please explain the purpose and implementation of each one.

> The application can decide using the below action types
> enum rte_security_session_action_type {
>         RTE_SECURITY_SESS_ETH_INLINE_CRYPTO,
>         /**< Crypto operations are performed by Network interface */

In this mode, the ethdev port does the same thing as a crypto port?

>         RTE_SECURITY_SESS_ETH_PROTO_OFFLOAD,
>         /**< Crypto operations with protocol support are performed
>          * by Network/ethernet device.
>          */
>         RTE_SECURITY_SESS_CRYPTO_PROTO_OFFLOAD,
>         /**< Crypto operations with protocol support are performed
>          * by Crypto device.
>          */

I guess the difference between ETH_PROTO_OFFLOAD and CRYPTO_PROTO_OFFLOAD
is that we must re-inject packets from CRYPTO_PROTO_OFFLOAD to the NIC?

>         RTE_SECURITY_SESS_NONE
> 	/**< Non protocol offload. Application need to manage everything */
> };

What RTE_SECURITY_SESS_NONE does? It is said to be implemented above.

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

* Re: [dpdk-dev] [RFC PATCH 0/1] IPSec Inline and look aside crypto offload
  2017-08-29 14:49       ` [dpdk-dev] [RFC PATCH 0/1] IPSec Inline and look aside crypto offload Thomas Monjalon
@ 2017-08-31  9:37         ` Akhil Goyal
  2017-08-31 10:06           ` Thomas Monjalon
  0 siblings, 1 reply; 37+ messages in thread
From: Akhil Goyal @ 2017-08-31  9:37 UTC (permalink / raw)
  To: Thomas Monjalon
  Cc: dev, borisp, declan.doherty, radu.nicolau, aviadye,
	sandeep.malik, hemant.agrawal, pablo.de.lara.guarch

Hi Thomas,
On 8/29/2017 8:19 PM, Thomas Monjalon wrote:
> Hi,
> 
> I try to understand how things are connected,
> but too many things are not clear for someone not involved in security.
> 
> 25/07/2017 13:21, Akhil Goyal:
>> struct rte_security_session *
>> rte_security_session_create(struct rte_mempool *mempool);
> 
> What is the usage of this mempool?
this mempool is used to allocate memory for sessions. This API is 
similar to the rte_crypto_session_create API. The same session can be 
used by multiple devices(eth or crypto) and each device can store its 
own private date.
> 
> [...]
>> These are very similar to what Declan proposed with a few additions.
>> This can be updated further for other security protocols like MACSec and DTLS
> 
> You should avoid referencing another proposal without
> - link to the proposal
> - summary of the proposal
The link is not mentioned in the cover note but the patches are sent in 
reply to the same thread that I have mentioned. If we see the complete 
thread, then there should not be any gap.
> 
> [...]
>> Now, after the application configures the session using above APIs, it needs to
>> attach the  session with the crypto_op in case the session is configured for
>> crypto look aside protocol offload. For IPSec inline/ full protocol offload
>> using NIC, the mbuf ol_flags can be set as per the RFC suggested by Boris.
> 
> Again a missing reference (link + summary).
> 
> Even worst, the RFCv2 references this v1 without copying the explanations.
> It is too hard to track, or maybe it is cryptic on purpose ;)
Same comment, patches are sent within the same thread.
Please let me know what is not clear with the thread.

Also, I would take care about this comment, that I need to copy the 
content of previous versions, in my future patches.

As this was an RFC series of patches, the content may not 100% stable, 
and things may get finalized during the course of development across 
Intel/NXP/Mellanox and may be others.

As per my understanding all the information is there in the complete 
thread and nothing looks cryptic to me.

> 
> [...]
>> Now the application(ipsec-secgw) have 4 paths to decide for the data path.
>> 1. Non-protocol offload (currently implemented)
>> 2. IPSec inline(only crypto operations using NIC)
>> 3. full protocol offload(crypto operations along with all the IPsec header
>>     and trailer processing using NIC)
>> 4. look aside protocol offload(single-pass encryption and authentication with
>>     additional levels of protocol processing offload using crypto device)
> 
> I feel these 4 paths are the most important to discuss.
> Unfortunately there are not enough detailed.
> Please explain the purpose and implementation of each one.
Yes these are 4 paths which can be used for IPSEC.
1. Non protocol offload(RTE_SECURITY_SESS_NONE) - the existing 
application works on this path, the crypto devices perform the crypto 
operations without protocol knowledge.
2. Ipsec inline(RTE_SECURITY_SESS_ETH_INLINE_CRYPTO) - This is when the 
crypto operations are performed by ethernet device instead of crypto 
device. This is also without protocol knowledge inside the ethernet device
3. full protocol offload(RTE_SECURITY_SESS_ETH_PROTO_OFFLOAD) - This is 
same as 2 but with protocol support in the ethernet device.
4. look aside protocol offload(RTE_SECURITY_SESS_CRYPTO_PROTO_OFFLOAD) - 
This is same as 1 but with protocol support in crypto device.

The current application support only the first path. The patchset 
introduces how the other paths can be configured in the 
application/library/driver.

> 
>> The application can decide using the below action types
>> enum rte_security_session_action_type {
>>          RTE_SECURITY_SESS_ETH_INLINE_CRYPTO,
>>          /**< Crypto operations are performed by Network interface */
> 
> In this mode, the ethdev port does the same thing as a crypto port?
not exactly everything. In this mode, only cipher and auth operations 
are performed by the eth device. No intelligence about the protocol is 
done. This is similar to what the current implementation do with the 
crypto device(Non protocol offload).
> 
>>          RTE_SECURITY_SESS_ETH_PROTO_OFFLOAD,
>>          /**< Crypto operations with protocol support are performed
>>           * by Network/ethernet device.
>>           */
>>          RTE_SECURITY_SESS_CRYPTO_PROTO_OFFLOAD,
>>          /**< Crypto operations with protocol support are performed
>>           * by Crypto device.
>>           */
> 
> I guess the difference between ETH_PROTO_OFFLOAD and CRYPTO_PROTO_OFFLOAD
> is that we must re-inject packets from CRYPTO_PROTO_OFFLOAD to the NIC?
yes
> 
>>          RTE_SECURITY_SESS_NONE
>> 	/**< Non protocol offload. Application need to manage everything */
>> };
> 
> What RTE_SECURITY_SESS_NONE does? It is said to be implemented above.
It is non protocol offload mentioned above.
> 
> 

Thanks for reviewing the patch set. Please let me know if you have any 
more queries.

Regards,
Akhil

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

* Re: [dpdk-dev] [RFC PATCH 0/1] IPSec Inline and look aside crypto offload
  2017-08-31  9:37         ` Akhil Goyal
@ 2017-08-31 10:06           ` Thomas Monjalon
  2017-08-31 10:52             ` Akhil Goyal
  0 siblings, 1 reply; 37+ messages in thread
From: Thomas Monjalon @ 2017-08-31 10:06 UTC (permalink / raw)
  To: Akhil Goyal
  Cc: dev, borisp, declan.doherty, radu.nicolau, aviadye,
	sandeep.malik, hemant.agrawal, pablo.de.lara.guarch

31/08/2017 11:37, Akhil Goyal:
> On 8/29/2017 8:19 PM, Thomas Monjalon wrote:
> > 25/07/2017 13:21, Akhil Goyal:
> >> These are very similar to what Declan proposed with a few additions.
> >> This can be updated further for other security protocols like MACSec and DTLS
> > 
> > You should avoid referencing another proposal without
> > - link to the proposal
> > - summary of the proposal
> The link is not mentioned in the cover note but the patches are sent in 
> reply to the same thread that I have mentioned. If we see the complete 
> thread, then there should not be any gap.
> > 
> > [...]
> >> Now, after the application configures the session using above APIs, it needs to
> >> attach the  session with the crypto_op in case the session is configured for
> >> crypto look aside protocol offload. For IPSec inline/ full protocol offload
> >> using NIC, the mbuf ol_flags can be set as per the RFC suggested by Boris.
> > 
> > Again a missing reference (link + summary).
> > 
> > Even worst, the RFCv2 references this v1 without copying the explanations.
> > It is too hard to track, or maybe it is cryptic on purpose ;)
> Same comment, patches are sent within the same thread.
> Please let me know what is not clear with the thread.
> 
> Also, I would take care about this comment, that I need to copy the 
> content of previous versions, in my future patches.
> 
> As this was an RFC series of patches, the content may not 100% stable, 
> and things may get finalized during the course of development across 
> Intel/NXP/Mellanox and may be others.
> 
> As per my understanding all the information is there in the complete 
> thread and nothing looks cryptic to me.

I am sure nothing looks cryptic to you :)
But you are not writing it for yourself. My feedback is that it would be
easier to read if you summarize the whole status in the same cover letter.
You are free to consider my feedback or not.

> > [...]
> >> Now the application(ipsec-secgw) have 4 paths to decide for the data path.
> >> 1. Non-protocol offload (currently implemented)
> >> 2. IPSec inline(only crypto operations using NIC)
> >> 3. full protocol offload(crypto operations along with all the IPsec header
> >>     and trailer processing using NIC)
> >> 4. look aside protocol offload(single-pass encryption and authentication with
> >>     additional levels of protocol processing offload using crypto device)
> > 
> > I feel these 4 paths are the most important to discuss.
> > Unfortunately there are not enough detailed.
> > Please explain the purpose and implementation of each one.
> Yes these are 4 paths which can be used for IPSEC.
> 1. Non protocol offload(RTE_SECURITY_SESS_NONE) - the existing 
> application works on this path, the crypto devices perform the crypto 
> operations without protocol knowledge.

This mode is when using cryptodev API, right?
Are you proposing to use rte_security as a simple wrapper of cryptodev
in the mode RTE_SECURITY_SESS_NONE?

> 2. Ipsec inline(RTE_SECURITY_SESS_ETH_INLINE_CRYPTO) - This is when the 
> crypto operations are performed by ethernet device instead of crypto 
> device. This is also without protocol knowledge inside the ethernet device

If the ethernet device can act as a crypto device, this function
should be offered via the cryptodev interface.
How is it different from mode RTE_SECURITY_SESS_NONE?
Is there direct Rx/Tx involved in this mode?

> 3. full protocol offload(RTE_SECURITY_SESS_ETH_PROTO_OFFLOAD) - This is 
> same as 2 but with protocol support in the ethernet device.

Is there direct Rx/Tx in RTE_SECURITY_SESS_ETH_PROTO_OFFLOAD?

> 4. look aside protocol offload(RTE_SECURITY_SESS_CRYPTO_PROTO_OFFLOAD) - 
> This is same as 1 but with protocol support in crypto device.

Who is responsible for Rx/Tx in RTE_SECURITY_SESS_CRYPTO_PROTO_OFFLOAD?

[...]
> >> The application can decide using the below action types
> >> enum rte_security_session_action_type {
> >>          RTE_SECURITY_SESS_ETH_INLINE_CRYPTO,
> >>          /**< Crypto operations are performed by Network interface */
> > 
> > In this mode, the ethdev port does the same thing as a crypto port?
> 
> not exactly everything. In this mode, only cipher and auth operations 
> are performed by the eth device. No intelligence about the protocol is 
> done. This is similar to what the current implementation do with the 
> crypto device(Non protocol offload).

Are you saying no but yes?
I say "ethdev port does the same thing as a crypto port"
You say "similar to what the current implementation do with the crypto device"

> >>          RTE_SECURITY_SESS_ETH_PROTO_OFFLOAD,
> >>          /**< Crypto operations with protocol support are performed
> >>           * by Network/ethernet device.
> >>           */
> >>          RTE_SECURITY_SESS_CRYPTO_PROTO_OFFLOAD,
> >>          /**< Crypto operations with protocol support are performed
> >>           * by Crypto device.
> >>           */
> > 
> > I guess the difference between ETH_PROTO_OFFLOAD and CRYPTO_PROTO_OFFLOAD
> > is that we must re-inject packets from CRYPTO_PROTO_OFFLOAD to the NIC?
> 
> yes

OK
Who is responsible to re-inject packets from CRYPTO_PROTO_OFFLOAD to the NIC?

> >>          RTE_SECURITY_SESS_NONE
> >> 	/**< Non protocol offload. Application need to manage everything */
> >> };
> > 
> > What RTE_SECURITY_SESS_NONE does? It is said to be implemented above.
> 
> It is non protocol offload mentioned above.

How is it different from using cryptodev?

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

* Re: [dpdk-dev] [RFC PATCH 0/1] IPSec Inline and look aside crypto offload
  2017-08-31 10:06           ` Thomas Monjalon
@ 2017-08-31 10:52             ` Akhil Goyal
  2017-08-31 13:14               ` Thomas Monjalon
  0 siblings, 1 reply; 37+ messages in thread
From: Akhil Goyal @ 2017-08-31 10:52 UTC (permalink / raw)
  To: Thomas Monjalon
  Cc: dev, borisp, declan.doherty, radu.nicolau, aviadye,
	sandeep.malik, hemant.agrawal, pablo.de.lara.guarch

On 8/31/2017 3:36 PM, Thomas Monjalon wrote:
> 31/08/2017 11:37, Akhil Goyal:
>> On 8/29/2017 8:19 PM, Thomas Monjalon wrote:
>>> 25/07/2017 13:21, Akhil Goyal:
>>>> These are very similar to what Declan proposed with a few additions.
>>>> This can be updated further for other security protocols like MACSec and DTLS
>>>
>>> You should avoid referencing another proposal without
>>> - link to the proposal
>>> - summary of the proposal
>> The link is not mentioned in the cover note but the patches are sent in
>> reply to the same thread that I have mentioned. If we see the complete
>> thread, then there should not be any gap.
>>>
>>> [...]
>>>> Now, after the application configures the session using above APIs, it needs to
>>>> attach the  session with the crypto_op in case the session is configured for
>>>> crypto look aside protocol offload. For IPSec inline/ full protocol offload
>>>> using NIC, the mbuf ol_flags can be set as per the RFC suggested by Boris.
>>>
>>> Again a missing reference (link + summary).
>>>
>>> Even worst, the RFCv2 references this v1 without copying the explanations.
>>> It is too hard to track, or maybe it is cryptic on purpose ;)
>> Same comment, patches are sent within the same thread.
>> Please let me know what is not clear with the thread.
>>
>> Also, I would take care about this comment, that I need to copy the
>> content of previous versions, in my future patches.
>>
>> As this was an RFC series of patches, the content may not 100% stable,
>> and things may get finalized during the course of development across
>> Intel/NXP/Mellanox and may be others.
>>
>> As per my understanding all the information is there in the complete
>> thread and nothing looks cryptic to me.
> 
> I am sure nothing looks cryptic to you :)
> But you are not writing it for yourself. My feedback is that it would be
> easier to read if you summarize the whole status in the same cover letter.
> You are free to consider my feedback or not.
> 
>>> [...]
>>>> Now the application(ipsec-secgw) have 4 paths to decide for the data path.
>>>> 1. Non-protocol offload (currently implemented)
>>>> 2. IPSec inline(only crypto operations using NIC)
>>>> 3. full protocol offload(crypto operations along with all the IPsec header
>>>>      and trailer processing using NIC)
>>>> 4. look aside protocol offload(single-pass encryption and authentication with
>>>>      additional levels of protocol processing offload using crypto device)
>>>
>>> I feel these 4 paths are the most important to discuss.
>>> Unfortunately there are not enough detailed.
>>> Please explain the purpose and implementation of each one.
>> Yes these are 4 paths which can be used for IPSEC.
>> 1. Non protocol offload(RTE_SECURITY_SESS_NONE) - the existing
>> application works on this path, the crypto devices perform the crypto
>> operations without protocol knowledge.
> 
> This mode is when using cryptodev API, right?
> Are you proposing to use rte_security as a simple wrapper of cryptodev
> in the mode RTE_SECURITY_SESS_NONE?
No, rte_security is not a wrapper over cryptodev. It stands parallel to 
cryptodev APIs.
RTE_SECURITY_SESS_NONE denotes that there is no security session 
involved and user will be using the existing functionality i.e. 
non-protocol offload and use crypto devices for crypto operations.

> 
>> 2. Ipsec inline(RTE_SECURITY_SESS_ETH_INLINE_CRYPTO) - This is when the
>> crypto operations are performed by ethernet device instead of crypto
>> device. This is also without protocol knowledge inside the ethernet device
> 
> If the ethernet device can act as a crypto device, this function
> should be offered via the cryptodev interface.
yes this could be thought of but the intent was to keep cryptodev and 
ethdev separate, as this would create confusion and will become 
difficult to manage.
> How is it different from mode RTE_SECURITY_SESS_NONE?
In RTE_SECURITY_SESS_NONE - crypto device is used for crypto operations.
In RTE_SECURITY_SESS_ETH_INLINE_CRYPTO - ethernet device is used for 
crypto operations.
For details of the data path of this mode, refer to the covernote of RFC 
patch from Boris.
http://dpdk.org/ml/archives/dev/2017-July/070793.html

For implementation of this mode, see patches from Radu,
http://dpdk.org/ml/archives/dev/2017-August/073587.html


> Is there direct Rx/Tx involved in this mode?
No the packet will come to the application and will add/remove relevant 
headers and then send the packet to the appropriate eth dev after route 
lookup.

> 
>> 3. full protocol offload(RTE_SECURITY_SESS_ETH_PROTO_OFFLOAD) - This is
>> same as 2 but with protocol support in the ethernet device.
> 
> Is there direct Rx/Tx in RTE_SECURITY_SESS_ETH_PROTO_OFFLOAD?
No, there should not be direct rx/tx as the application will do route 
lookup and send the packet to relevant ethernet interface.
> 
>> 4. look aside protocol offload(RTE_SECURITY_SESS_CRYPTO_PROTO_OFFLOAD) -
>> This is same as 1 but with protocol support in crypto device.
> 
> Who is responsible for Rx/Tx in RTE_SECURITY_SESS_CRYPTO_PROTO_OFFLOAD?
The packet is returned back to the application as in the case of non 
protocol offload. But the application doesnt need to take care of the 
headers and other protocol specifics. It just need to forward the packet 
to the relevent eth dev after route lookup.
Please refer to RFC v2 of the proposal it has more details in the header 
file rte_security.h and the implementation using the ipsec-secgw 
application.
http://dpdk.org/ml/archives/dev/2017-August/072900.html

> 
> [...]
>>>> The application can decide using the below action types
>>>> enum rte_security_session_action_type {
>>>>           RTE_SECURITY_SESS_ETH_INLINE_CRYPTO,
>>>>           /**< Crypto operations are performed by Network interface */
>>>
>>> In this mode, the ethdev port does the same thing as a crypto port?
>>
>> not exactly everything. In this mode, only cipher and auth operations
>> are performed by the eth device. No intelligence about the protocol is
>> done. This is similar to what the current implementation do with the
>> crypto device(Non protocol offload).
> 
> Are you saying no but yes?
> I say "ethdev port does the same thing as a crypto port"
> You say "similar to what the current implementation do with the crypto device"
This is said so because the crypto device may also support protocol offload.
> 
>>>>           RTE_SECURITY_SESS_ETH_PROTO_OFFLOAD,
>>>>           /**< Crypto operations with protocol support are performed
>>>>            * by Network/ethernet device.
>>>>            */
>>>>           RTE_SECURITY_SESS_CRYPTO_PROTO_OFFLOAD,
>>>>           /**< Crypto operations with protocol support are performed
>>>>            * by Crypto device.
>>>>            */
>>>
>>> I guess the difference between ETH_PROTO_OFFLOAD and CRYPTO_PROTO_OFFLOAD
>>> is that we must re-inject packets from CRYPTO_PROTO_OFFLOAD to the NIC?
>>
>> yes
> 
> OK
> Who is responsible to re-inject packets from CRYPTO_PROTO_OFFLOAD to the NIC?
Application will do the forwarding after route lookup
> 
>>>>           RTE_SECURITY_SESS_NONE
>>>> 	/**< Non protocol offload. Application need to manage everything */
>>>> };
>>>
>>> What RTE_SECURITY_SESS_NONE does? It is said to be implemented above.
>>
>> It is non protocol offload mentioned above.
> 
> How is it different from using cryptodev?
No it is not different. It is just to mention that there is no security 
session involved and the application will use the cryptodev.
> 

-Akhil

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

* Re: [dpdk-dev] [RFC PATCH 0/1] IPSec Inline and look aside crypto offload
  2017-08-31 10:52             ` Akhil Goyal
@ 2017-08-31 13:14               ` Thomas Monjalon
  2017-08-31 14:09                 ` Radu Nicolau
  0 siblings, 1 reply; 37+ messages in thread
From: Thomas Monjalon @ 2017-08-31 13:14 UTC (permalink / raw)
  To: Akhil Goyal
  Cc: dev, borisp, declan.doherty, radu.nicolau, aviadye,
	sandeep.malik, hemant.agrawal, pablo.de.lara.guarch

31/08/2017 12:52, Akhil Goyal:
> On 8/31/2017 3:36 PM, Thomas Monjalon wrote:
> > 31/08/2017 11:37, Akhil Goyal:
> >> On 8/29/2017 8:19 PM, Thomas Monjalon wrote:
> >>> 25/07/2017 13:21, Akhil Goyal:
> >> 2. Ipsec inline(RTE_SECURITY_SESS_ETH_INLINE_CRYPTO) - This is when the
> >> crypto operations are performed by ethernet device instead of crypto
> >> device. This is also without protocol knowledge inside the ethernet device
> > 
> > If the ethernet device can act as a crypto device, this function
> > should be offered via the cryptodev interface.
> 
> yes this could be thought of but the intent was to keep cryptodev and 
> ethdev separate, as this would create confusion and will become 
> difficult to manage.

I think the reverse: it is confusing to do crypto operations through
ethdev interface.
If a device can do "standalone crypto" and networking, it should appear as
2 different ports in my opinion.

> > How is it different from mode RTE_SECURITY_SESS_NONE?
> 
> In RTE_SECURITY_SESS_NONE - crypto device is used for crypto operations.
> In RTE_SECURITY_SESS_ETH_INLINE_CRYPTO - ethernet device is used for 
> crypto operations.
> For details of the data path of this mode, refer to the covernote of RFC 
> patch from Boris.
> http://dpdk.org/ml/archives/dev/2017-July/070793.html
> 
> For implementation of this mode, see patches from Radu,
> http://dpdk.org/ml/archives/dev/2017-August/073587.html

Boris RFC uses rte_flow.
Radu implementation does not use rte_flow.
So I still don't understand the big picture.
Boris asked the question and had no answer.

> > Is there direct Rx/Tx involved in this mode?
> 
> No the packet will come to the application and will add/remove relevant 
> headers and then send the packet to the appropriate eth dev after route 
> lookup.
> 
> >> 3. full protocol offload(RTE_SECURITY_SESS_ETH_PROTO_OFFLOAD) - This is
> >> same as 2 but with protocol support in the ethernet device.
> > 
> > Is there direct Rx/Tx in RTE_SECURITY_SESS_ETH_PROTO_OFFLOAD?
> 
> No, there should not be direct rx/tx as the application will do route 
> lookup and send the packet to relevant ethernet interface.
> > 
> >> 4. look aside protocol offload(RTE_SECURITY_SESS_CRYPTO_PROTO_OFFLOAD) -
> >> This is same as 1 but with protocol support in crypto device.
> > 
> > Who is responsible for Rx/Tx in RTE_SECURITY_SESS_CRYPTO_PROTO_OFFLOAD?
> 
> The packet is returned back to the application as in the case of non 
> protocol offload. But the application doesnt need to take care of the 
> headers and other protocol specifics. It just need to forward the packet 
> to the relevent eth dev after route lookup.
> Please refer to RFC v2 of the proposal it has more details in the header 
> file rte_security.h and the implementation using the ipsec-secgw 
> application.
> http://dpdk.org/ml/archives/dev/2017-August/072900.html

So there is no direct Rx/Tx in any mode?
What is the point of using an ethdev port if there is no Rx/Tx?

> > [...]
> >>>> The application can decide using the below action types
> >>>> enum rte_security_session_action_type {
> >>>>           RTE_SECURITY_SESS_ETH_INLINE_CRYPTO,
> >>>>           /**< Crypto operations are performed by Network interface */
> >>>
> >>> In this mode, the ethdev port does the same thing as a crypto port?
> >>
> >> not exactly everything. In this mode, only cipher and auth operations
> >> are performed by the eth device. No intelligence about the protocol is
> >> done. This is similar to what the current implementation do with the
> >> crypto device(Non protocol offload).
> > 
> > Are you saying no but yes?
> > I say "ethdev port does the same thing as a crypto port"
> > You say "similar to what the current implementation do with the crypto device"
> 
> This is said so because the crypto device may also support protocol offload.
> > 
> >>>>           RTE_SECURITY_SESS_ETH_PROTO_OFFLOAD,
> >>>>           /**< Crypto operations with protocol support are performed
> >>>>            * by Network/ethernet device.
> >>>>            */
> >>>>           RTE_SECURITY_SESS_CRYPTO_PROTO_OFFLOAD,
> >>>>           /**< Crypto operations with protocol support are performed
> >>>>            * by Crypto device.
> >>>>            */
> >>>
> >>> I guess the difference between ETH_PROTO_OFFLOAD and CRYPTO_PROTO_OFFLOAD
> >>> is that we must re-inject packets from CRYPTO_PROTO_OFFLOAD to the NIC?
> >>
> >> yes
> > 
> > OK
> > Who is responsible to re-inject packets from CRYPTO_PROTO_OFFLOAD to the NIC?
> 
> Application will do the forwarding after route lookup
> > 
> >>>>           RTE_SECURITY_SESS_NONE
> >>>> 	/**< Non protocol offload. Application need to manage everything */
> >>>> };
> >>>
> >>> What RTE_SECURITY_SESS_NONE does? It is said to be implemented above.
> >>
> >> It is non protocol offload mentioned above.
> > 
> > How is it different from using cryptodev?
> 
> No it is not different. It is just to mention that there is no security 
> session involved and the application will use the cryptodev.

As far as I understand, my vote is a NACK for the current proposal.

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

* Re: [dpdk-dev] [RFC PATCH 0/1] IPSec Inline and look aside crypto offload
  2017-08-31 13:14               ` Thomas Monjalon
@ 2017-08-31 14:09                 ` Radu Nicolau
  2017-09-06 15:53                   ` Jerin Jacob
  0 siblings, 1 reply; 37+ messages in thread
From: Radu Nicolau @ 2017-08-31 14:09 UTC (permalink / raw)
  To: Thomas Monjalon, Akhil Goyal
  Cc: dev, borisp, declan.doherty, aviadye, sandeep.malik,
	hemant.agrawal, pablo.de.lara.guarch


On 8/31/2017 2:14 PM, Thomas Monjalon wrote:
> 31/08/2017 12:52, Akhil Goyal:
>> On 8/31/2017 3:36 PM, Thomas Monjalon wrote:
>>> 31/08/2017 11:37, Akhil Goyal:
>>>> On 8/29/2017 8:19 PM, Thomas Monjalon wrote:
>>>>> 25/07/2017 13:21, Akhil Goyal:
>>>> 2. Ipsec inline(RTE_SECURITY_SESS_ETH_INLINE_CRYPTO) - This is when the
>>>> crypto operations are performed by ethernet device instead of crypto
>>>> device. This is also without protocol knowledge inside the ethernet device
>>> If the ethernet device can act as a crypto device, this function
>>> should be offered via the cryptodev interface.
>> yes this could be thought of but the intent was to keep cryptodev and
>> ethdev separate, as this would create confusion and will become
>> difficult to manage.
> I think the reverse: it is confusing to do crypto operations through
> ethdev interface.
> If a device can do "standalone crypto" and networking, it should appear as
> 2 different ports in my opinion.
>
>>> How is it different from mode RTE_SECURITY_SESS_NONE?
>> In RTE_SECURITY_SESS_NONE - crypto device is used for crypto operations.
>> In RTE_SECURITY_SESS_ETH_INLINE_CRYPTO - ethernet device is used for
>> crypto operations.
>> For details of the data path of this mode, refer to the covernote of RFC
>> patch from Boris.
>> http://dpdk.org/ml/archives/dev/2017-July/070793.html
>>
>> For implementation of this mode, see patches from Radu,
>> http://dpdk.org/ml/archives/dev/2017-August/073587.html
> Boris RFC uses rte_flow.
> Radu implementation does not use rte_flow.
> So I still don't understand the big picture.
> Boris asked the question and had no answer.
I'll answer here: it was an omission from my side; v2 of the will 
include rte_flow usage, derived from Boris RFC.
>
>>> Is there direct Rx/Tx involved in this mode?
>> No the packet will come to the application and will add/remove relevant
>> headers and then send the packet to the appropriate eth dev after route
>> lookup.
>>
>>>> 3. full protocol offload(RTE_SECURITY_SESS_ETH_PROTO_OFFLOAD) - This is
>>>> same as 2 but with protocol support in the ethernet device.
>>> Is there direct Rx/Tx in RTE_SECURITY_SESS_ETH_PROTO_OFFLOAD?
>> No, there should not be direct rx/tx as the application will do route
>> lookup and send the packet to relevant ethernet interface.
>>>> 4. look aside protocol offload(RTE_SECURITY_SESS_CRYPTO_PROTO_OFFLOAD) -
>>>> This is same as 1 but with protocol support in crypto device.
>>> Who is responsible for Rx/Tx in RTE_SECURITY_SESS_CRYPTO_PROTO_OFFLOAD?
>> The packet is returned back to the application as in the case of non
>> protocol offload. But the application doesnt need to take care of the
>> headers and other protocol specifics. It just need to forward the packet
>> to the relevent eth dev after route lookup.
>> Please refer to RFC v2 of the proposal it has more details in the header
>> file rte_security.h and the implementation using the ipsec-secgw
>> application.
>> http://dpdk.org/ml/archives/dev/2017-August/072900.html
> So there is no direct Rx/Tx in any mode?
> What is the point of using an ethdev port if there is no Rx/Tx?
>
>>> [...]
>>>>>> The application can decide using the below action types
>>>>>> enum rte_security_session_action_type {
>>>>>>            RTE_SECURITY_SESS_ETH_INLINE_CRYPTO,
>>>>>>            /**< Crypto operations are performed by Network interface */
>>>>> In this mode, the ethdev port does the same thing as a crypto port?
>>>> not exactly everything. In this mode, only cipher and auth operations
>>>> are performed by the eth device. No intelligence about the protocol is
>>>> done. This is similar to what the current implementation do with the
>>>> crypto device(Non protocol offload).
>>> Are you saying no but yes?
>>> I say "ethdev port does the same thing as a crypto port"
>>> You say "similar to what the current implementation do with the crypto device"
>> This is said so because the crypto device may also support protocol offload.
>>>>>>            RTE_SECURITY_SESS_ETH_PROTO_OFFLOAD,
>>>>>>            /**< Crypto operations with protocol support are performed
>>>>>>             * by Network/ethernet device.
>>>>>>             */
>>>>>>            RTE_SECURITY_SESS_CRYPTO_PROTO_OFFLOAD,
>>>>>>            /**< Crypto operations with protocol support are performed
>>>>>>             * by Crypto device.
>>>>>>             */
>>>>> I guess the difference between ETH_PROTO_OFFLOAD and CRYPTO_PROTO_OFFLOAD
>>>>> is that we must re-inject packets from CRYPTO_PROTO_OFFLOAD to the NIC?
>>>> yes
>>> OK
>>> Who is responsible to re-inject packets from CRYPTO_PROTO_OFFLOAD to the NIC?
>> Application will do the forwarding after route lookup
>>>>>>            RTE_SECURITY_SESS_NONE
>>>>>> 	/**< Non protocol offload. Application need to manage everything */
>>>>>> };
>>>>> What RTE_SECURITY_SESS_NONE does? It is said to be implemented above.
>>>> It is non protocol offload mentioned above.
>>> How is it different from using cryptodev?
>> No it is not different. It is just to mention that there is no security
>> session involved and the application will use the cryptodev.
> As far as I understand, my vote is a NACK for the current proposal.

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

* Re: [dpdk-dev] [RFC PATCH 0/1] IPSec Inline and look aside crypto offload
  2017-08-31 14:09                 ` Radu Nicolau
@ 2017-09-06 15:53                   ` Jerin Jacob
  2017-09-08 11:12                     ` Akhil Goyal
  0 siblings, 1 reply; 37+ messages in thread
From: Jerin Jacob @ 2017-09-06 15:53 UTC (permalink / raw)
  To: Radu Nicolau
  Cc: Thomas Monjalon, Akhil Goyal, dev, borisp, declan.doherty,
	aviadye, sandeep.malik, hemant.agrawal, pablo.de.lara.guarch,
	pathreya, andriy.berestovskyy, sunil.kulkarni,
	balasubramanian.manoharan, suheil.chandran

-----Original Message-----
> Date: Thu, 31 Aug 2017 15:09:45 +0100
> From: Radu Nicolau <radu.nicolau@intel.com>
> To: Thomas Monjalon <thomas@monjalon.net>, Akhil Goyal <akhil.goyal@nxp.com>
> CC: dev@dpdk.org, borisp@mellanox.com, declan.doherty@intel.com,
>  aviadye@mellanox.com, sandeep.malik@nxp.com, hemant.agrawal@nxp.com,
>  pablo.de.lara.guarch@intel.com
> Subject: Re: [dpdk-dev] [RFC PATCH 0/1] IPSec Inline and look aside crypto
>  offload
> User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:52.0) Gecko/20100101
>  Thunderbird/52.1.0
> 
> 
> On 8/31/2017 2:14 PM, Thomas Monjalon wrote:
> > 31/08/2017 12:52, Akhil Goyal:
> > > On 8/31/2017 3:36 PM, Thomas Monjalon wrote:
> > > > 31/08/2017 11:37, Akhil Goyal:
> > > > > On 8/29/2017 8:19 PM, Thomas Monjalon wrote:
> > > > > > 25/07/2017 13:21, Akhil Goyal:
> > > > > 2. Ipsec inline(RTE_SECURITY_SESS_ETH_INLINE_CRYPTO) - This is when the
> > > > > crypto operations are performed by ethernet device instead of crypto
> > > > > device. This is also without protocol knowledge inside the ethernet device
> > > > If the ethernet device can act as a crypto device, this function
> > > > should be offered via the cryptodev interface.
> > > yes this could be thought of but the intent was to keep cryptodev and
> > > ethdev separate, as this would create confusion and will become
> > > difficult to manage.
> > I think the reverse: it is confusing to do crypto operations through
> > ethdev interface.
> > If a device can do "standalone crypto" and networking, it should appear as
> > 2 different ports in my opinion.
> > 
> > > > How is it different from mode RTE_SECURITY_SESS_NONE?
> > > In RTE_SECURITY_SESS_NONE - crypto device is used for crypto operations.
> > > In RTE_SECURITY_SESS_ETH_INLINE_CRYPTO - ethernet device is used for
> > > crypto operations.
> > > For details of the data path of this mode, refer to the covernote of RFC
> > > patch from Boris.
> > > http://dpdk.org/ml/archives/dev/2017-July/070793.html
> > > 
> > > For implementation of this mode, see patches from Radu,
> > > http://dpdk.org/ml/archives/dev/2017-August/073587.html
> > Boris RFC uses rte_flow.
> > Radu implementation does not use rte_flow.
> > So I still don't understand the big picture.
> > Boris asked the question and had no answer.
> I'll answer here: it was an omission from my side; v2 of the will include
> rte_flow usage, derived from Boris RFC.


Cavium would like to contribute to the definition of this specification
as our HW supports the IPSec offload.

I was trying to review the latest patch. But it looks like there are
multiple versions of the header file floating around. like,

http://dpdk.org/ml/archives/dev/2017-August/073587.html
http://dpdk.org/ml/archives/dev/2017-August/073738.html

Can some one tell which one is latest one to review?

Previously for rte_flow, rte_eventdev specification, etc we had some
header file sign off before jumping to the RFC implementation. IMO, That
model was useful where all the vendors could make inline comments on the
proposal instead of maintaining in the draft repo.  So it possible for
sending the latest revision of the header file patch on the mailing list
for the inline comments.

Akhil,

Based on your v2 version, we could map a lot with our HW. However, there
are three top level quires for the further review.

1) Some HW cannot offload all types of packets(like IP fragmented
packets) and/or there may have back pressure momentarily from IPSec offload
engine (like Queue is full) etc. So in that case what is the expected behavior
a) Is it an offload driver responsibility to take care of that or
b) Is it passed to application as encrypted packets(in case of inbound)
and the application has to take or of them.

2) In case of inbound traffic, What is the packet format from offload
driver. i.e
a) Will ESP header will be removed from the packet area after the
decryption.

3) We have a few feature like, anti-replay check, SA expiry((byte/time)
notification, etc from HW/FW. So it is not clear from the specification
on the contract between between offload driver vs application
responsibility? Can you give some insight on that? Especially
the error notification scheme if it is an offload driver responsibility.

This questions will help us to review your proposal and make forward
progress.

Thanks,
/Jerin

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

* Re: [dpdk-dev] [RFC PATCH 0/1] IPSec Inline and look aside crypto offload
  2017-09-06 15:53                   ` Jerin Jacob
@ 2017-09-08 11:12                     ` Akhil Goyal
  2017-09-11 18:10                       ` Jerin Jacob
  0 siblings, 1 reply; 37+ messages in thread
From: Akhil Goyal @ 2017-09-08 11:12 UTC (permalink / raw)
  To: Jerin Jacob, Radu Nicolau
  Cc: Thomas Monjalon, dev, borisp, declan.doherty, aviadye,
	sandeep.malik, hemant.agrawal, pablo.de.lara.guarch, pathreya,
	andriy.berestovskyy, sunil.kulkarni, balasubramanian.manoharan,
	suheil.chandran

Hi  Jerin,

On 9/6/2017 9:23 PM, Jerin Jacob wrote:
> -----Original Message-----
>> Date: Thu, 31 Aug 2017 15:09:45 +0100
>> From: Radu Nicolau <radu.nicolau@intel.com>
>> To: Thomas Monjalon <thomas@monjalon.net>, Akhil Goyal <akhil.goyal@nxp.com>
>> CC: dev@dpdk.org, borisp@mellanox.com, declan.doherty@intel.com,
>>   aviadye@mellanox.com, sandeep.malik@nxp.com, hemant.agrawal@nxp.com,
>>   pablo.de.lara.guarch@intel.com
>> Subject: Re: [dpdk-dev] [RFC PATCH 0/1] IPSec Inline and look aside crypto
>>   offload
>> User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:52.0) Gecko/20100101
>>   Thunderbird/52.1.0
>>
>>
>> On 8/31/2017 2:14 PM, Thomas Monjalon wrote:
>>> 31/08/2017 12:52, Akhil Goyal:
>>>> On 8/31/2017 3:36 PM, Thomas Monjalon wrote:
>>>>> 31/08/2017 11:37, Akhil Goyal:
>>>>>> On 8/29/2017 8:19 PM, Thomas Monjalon wrote:
>>>>>>> 25/07/2017 13:21, Akhil Goyal:
>>>>>> 2. Ipsec inline(RTE_SECURITY_SESS_ETH_INLINE_CRYPTO) - This is when the
>>>>>> crypto operations are performed by ethernet device instead of crypto
>>>>>> device. This is also without protocol knowledge inside the ethernet device
>>>>> If the ethernet device can act as a crypto device, this function
>>>>> should be offered via the cryptodev interface.
>>>> yes this could be thought of but the intent was to keep cryptodev and
>>>> ethdev separate, as this would create confusion and will become
>>>> difficult to manage.
>>> I think the reverse: it is confusing to do crypto operations through
>>> ethdev interface.
>>> If a device can do "standalone crypto" and networking, it should appear as
>>> 2 different ports in my opinion.
>>>
>>>>> How is it different from mode RTE_SECURITY_SESS_NONE?
>>>> In RTE_SECURITY_SESS_NONE - crypto device is used for crypto operations.
>>>> In RTE_SECURITY_SESS_ETH_INLINE_CRYPTO - ethernet device is used for
>>>> crypto operations.
>>>> For details of the data path of this mode, refer to the covernote of RFC
>>>> patch from Boris.
>>>> http://dpdk.org/ml/archives/dev/2017-July/070793.html
>>>>
>>>> For implementation of this mode, see patches from Radu,
>>>> http://dpdk.org/ml/archives/dev/2017-August/073587.html
>>> Boris RFC uses rte_flow.
>>> Radu implementation does not use rte_flow.
>>> So I still don't understand the big picture.
>>> Boris asked the question and had no answer.
>> I'll answer here: it was an omission from my side; v2 of the will include
>> rte_flow usage, derived from Boris RFC.
> 
> 
> Cavium would like to contribute to the definition of this specification
> as our HW supports the IPSec offload.
> 
> I was trying to review the latest patch. But it looks like there are
> multiple versions of the header file floating around. like,
> 
> http://dpdk.org/ml/archives/dev/2017-August/073587.html
> http://dpdk.org/ml/archives/dev/2017-August/073738.html
> 
> Can some one tell which one is latest one to review?
> 
> Previously for rte_flow, rte_eventdev specification, etc we had some
> header file sign off before jumping to the RFC implementation. IMO, That
> model was useful where all the vendors could make inline comments on the
> proposal instead of maintaining in the draft repo.  So it possible for
> sending the latest revision of the header file patch on the mailing list
> for the inline comments.
> 

The RFC remained for some time, there were not many comments. so we all 
agreed moved to implementation. That is the point we requested for the 
repo.

The Cavium comments came bit late.

Currently I have just consolidated the patches in the draft repo and I 
am going rebase it and post to mailing list as well in next 1-2 days.

Since, the implementation is started, we will request any subsequent 
comments as an incremental patches.

> Akhil,
> 
> Based on your v2 version, we could map a lot with our HW. However, there
> are three top level quires for the further review.
> 
> 1) Some HW cannot offload all types of packets(like IP fragmented
> packets) and/or there may have back pressure momentarily from IPSec offload
> engine (like Queue is full) etc. So in that case what is the expected behavior
> a) Is it an offload driver responsibility to take care of that or
> b) Is it passed to application as encrypted packets(in case of inbound)
> and the application has to take or of them.
> 

It will depend on the HW capability. If the HW is not supporting the 
fragmented etc packets, they will come as an encrypted packed to the 
application and application need to take care of them.

> 2) In case of inbound traffic, What is the packet format from offload
> driver. i.e
> a) Will ESP header will be removed from the packet area after the
> decryption.
> 
It depend on the session action type. e.g. for inline crypto, the header 
will be intact. for inline proto, the headers will be removed.
In any case, we need to improve the documentation.

> 3) We have a few feature like, anti-replay check, SA expiry((byte/time)
> notification, etc from HW/FW. So it is not clear from the specification
> on the contract between between offload driver vs application
> responsibility? Can you give some insight on that? Especially
> the error notification scheme if it is an offload driver responsibility.
> 

Anti-replay, SA expiry management is still in my todo  list.
The responsibilities will depend on the amount of offloading the HW/FW 
is offering. The current intent is that SA management and expiry is 
being managed by the applicaiton. However, SA expiry event for byte 
based SA will be passed by the HW/FW to application.

In short, the current focus is covering the basic support  only. Rest 
will be incremental.

> This questions will help us to review your proposal and make forward
> progress.
> 
> Thanks,
> /Jerin
> 

Regards,
Akhil

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

* Re: [dpdk-dev] [RFC PATCH 0/1] IPSec Inline and look aside crypto offload
  2017-09-08 11:12                     ` Akhil Goyal
@ 2017-09-11 18:10                       ` Jerin Jacob
  0 siblings, 0 replies; 37+ messages in thread
From: Jerin Jacob @ 2017-09-11 18:10 UTC (permalink / raw)
  To: Akhil Goyal
  Cc: Radu Nicolau, Thomas Monjalon, dev, borisp, declan.doherty,
	aviadye, sandeep.malik, hemant.agrawal, pablo.de.lara.guarch,
	pathreya, andriy.berestovskyy, sunil.kulkarni,
	balasubramanian.manoharan, suheil.chandran

-----Original Message-----
> Date: Fri, 8 Sep 2017 16:42:56 +0530
> From: Akhil Goyal <akhil.goyal@nxp.com>
> To: Jerin Jacob <jerin.jacob@caviumnetworks.com>, Radu Nicolau
>  <radu.nicolau@intel.com>
> CC: Thomas Monjalon <thomas@monjalon.net>, dev@dpdk.org,
>  borisp@mellanox.com, declan.doherty@intel.com, aviadye@mellanox.com,
>  sandeep.malik@nxp.com, hemant.agrawal@nxp.com,
>  pablo.de.lara.guarch@intel.com, pathreya@caviumnetworks.com,
>  andriy.berestovskyy@cavium.com, sunil.kulkarni@cavium.com,
>  balasubramanian.manoharan@cavium.com, suheil.chandran@cavium.com
> Subject: Re: [RFC PATCH 0/1] IPSec Inline and look aside crypto offload
> User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:52.0) Gecko/20100101
>  Thunderbird/52.3.0
> 
> Hi  Jerin,

Hi Akhil,

> 
> On 9/6/2017 9:23 PM, Jerin Jacob wrote:
> > -----Original Message-----
> > > Date: Thu, 31 Aug 2017 15:09:45 +0100
> > > From: Radu Nicolau <radu.nicolau@intel.com>
> > > To: Thomas Monjalon <thomas@monjalon.net>, Akhil Goyal <akhil.goyal@nxp.com>
> > > CC: dev@dpdk.org, borisp@mellanox.com, declan.doherty@intel.com,
> > >   aviadye@mellanox.com, sandeep.malik@nxp.com, hemant.agrawal@nxp.com,
> > >   pablo.de.lara.guarch@intel.com
> > > Subject: Re: [dpdk-dev] [RFC PATCH 0/1] IPSec Inline and look aside crypto
> > >   offload
> > > User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:52.0) Gecko/20100101
> > >   Thunderbird/52.1.0
> > > 
> > > 
> > > On 8/31/2017 2:14 PM, Thomas Monjalon wrote:
> > > > 31/08/2017 12:52, Akhil Goyal:
> > > > > On 8/31/2017 3:36 PM, Thomas Monjalon wrote:
> > > > > > 31/08/2017 11:37, Akhil Goyal:
> > > > > > > On 8/29/2017 8:19 PM, Thomas Monjalon wrote:
> > > > > > > > 25/07/2017 13:21, Akhil Goyal:
> > > > > > > 2. Ipsec inline(RTE_SECURITY_SESS_ETH_INLINE_CRYPTO) - This is when the
> > > > > > > crypto operations are performed by ethernet device instead of crypto
> > > > > > > device. This is also without protocol knowledge inside the ethernet device
> > > > > > If the ethernet device can act as a crypto device, this function
> > > > > > should be offered via the cryptodev interface.
> > > > > yes this could be thought of but the intent was to keep cryptodev and
> > > > > ethdev separate, as this would create confusion and will become
> > > > > difficult to manage.
> > > > I think the reverse: it is confusing to do crypto operations through
> > > > ethdev interface.
> > > > If a device can do "standalone crypto" and networking, it should appear as
> > > > 2 different ports in my opinion.
> > > > 
> > > > > > How is it different from mode RTE_SECURITY_SESS_NONE?
> > > > > In RTE_SECURITY_SESS_NONE - crypto device is used for crypto operations.
> > > > > In RTE_SECURITY_SESS_ETH_INLINE_CRYPTO - ethernet device is used for
> > > > > crypto operations.
> > > > > For details of the data path of this mode, refer to the covernote of RFC
> > > > > patch from Boris.
> > > > > http://dpdk.org/ml/archives/dev/2017-July/070793.html
> > > > > 
> > > > > For implementation of this mode, see patches from Radu,
> > > > > http://dpdk.org/ml/archives/dev/2017-August/073587.html
> > > > Boris RFC uses rte_flow.
> > > > Radu implementation does not use rte_flow.
> > > > So I still don't understand the big picture.
> > > > Boris asked the question and had no answer.
> > > I'll answer here: it was an omission from my side; v2 of the will include
> > > rte_flow usage, derived from Boris RFC.
> > 
> > 
> > Cavium would like to contribute to the definition of this specification
> > as our HW supports the IPSec offload.
> > 
> > I was trying to review the latest patch. But it looks like there are
> > multiple versions of the header file floating around. like,
> > 
> > http://dpdk.org/ml/archives/dev/2017-August/073587.html
> > http://dpdk.org/ml/archives/dev/2017-August/073738.html
> > 
> > Can some one tell which one is latest one to review?
> > 
> > Previously for rte_flow, rte_eventdev specification, etc we had some
> > header file sign off before jumping to the RFC implementation. IMO, That
> > model was useful where all the vendors could make inline comments on the
> > proposal instead of maintaining in the draft repo.  So it possible for
> > sending the latest revision of the header file patch on the mailing list
> > for the inline comments.
> > 
> 
> The RFC remained for some time, there were not many comments. so we all
> agreed moved to implementation. That is the point we requested for the repo.

Yes. Nothing much happened on mailing list, All we saw a few comments
from Thomas and which ended up as NACK.

> 
> The Cavium comments came bit late.
> 
> Currently I have just consolidated the patches in the draft repo and I am
> going rebase it and post to mailing list as well in next 1-2 days.

OK. We will review it.

> 
> Since, the implementation is started, we will request any subsequent
> comments as an incremental patches.
> 
> > Akhil,
> > 
> > Based on your v2 version, we could map a lot with our HW. However, there
> > are three top level quires for the further review.
> > 
> > 1) Some HW cannot offload all types of packets(like IP fragmented
> > packets) and/or there may have back pressure momentarily from IPSec offload
> > engine (like Queue is full) etc. So in that case what is the expected behavior
> > a) Is it an offload driver responsibility to take care of that or
> > b) Is it passed to application as encrypted packets(in case of inbound)
> > and the application has to take or of them.
> > 
> 
> It will depend on the HW capability. If the HW is not supporting the
> fragmented etc packets, they will come as an encrypted packed to the
> application and application need to take care of them.

OK

> 
> > 2) In case of inbound traffic, What is the packet format from offload
> > driver. i.e
> > a) Will ESP header will be removed from the packet area after the
> > decryption.
> > 
> It depend on the session action type. e.g. for inline crypto, the header
> will be intact. for inline proto, the headers will be removed.
> In any case, we need to improve the documentation.

I thought, we need to keep the header in both cases otherwise the
application may not able to check anti-replay if ESP header removed.

> 
> > 3) We have a few feature like, anti-replay check, SA expiry((byte/time)
> > notification, etc from HW/FW. So it is not clear from the specification
> > on the contract between between offload driver vs application
> > responsibility? Can you give some insight on that? Especially
> > the error notification scheme if it is an offload driver responsibility.
> > 
> 
> Anti-replay, SA expiry management is still in my todo  list.
> The responsibilities will depend on the amount of offloading the HW/FW is
> offering. The current intent is that SA management and expiry is being
> managed by the applicaiton. However, SA expiry event for byte based SA will
> be passed by the HW/FW to application.
> 
> In short, the current focus is covering the basic support  only. Rest will
> be incremental.


Makes sense. This is the hard part to solve in inline HW IPSec implementation.
I suggest to keep API experimental till we solve this hard problems which are
tightly coupled with HW capabilities.

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

end of thread, other threads:[~2017-09-11 18:10 UTC | newest]

Thread overview: 37+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-07-10  7:35 [dpdk-dev] [RFC 0/7] ipsec inline Boris Pismenny
2017-07-10  7:35 ` [dpdk-dev] [RFC 1/7] ethdev: add device ipsec encrypt/decrypt capability flags Boris Pismenny
2017-07-10  7:35 ` [dpdk-dev] [RFC 2/7] ethdev: Add ESP header to generic flow steering Boris Pismenny
2017-07-10  7:35 ` [dpdk-dev] [RFC 3/7] ethdev: add rte flow action for crypto Boris Pismenny
2017-07-10  7:35 ` [dpdk-dev] [RFC 4/7] cryptodev: add ipsec xform Boris Pismenny
2017-07-10  7:35 ` [dpdk-dev] [RFC 5/7] mbuf: Add IPsec crypto flags Boris Pismenny
2017-07-10  7:35 ` [dpdk-dev] [RFC 6/7] mbuf: Added next_esp_proto field Boris Pismenny
2017-07-10  7:35 ` [dpdk-dev] [RFC 7/7] example/ipsec_gw: Support SA offload in datapath Boris Pismenny
2017-07-11 17:06 ` [dpdk-dev] [RFC 0/7] ipsec inline Declan Doherty
2017-07-12 14:08   ` Boris Pismenny
2017-07-14 11:12   ` Akhil Goyal
2017-07-25 11:21     ` [dpdk-dev] [RFC PATCH 0/1] IPSec Inline and look aside crypto offload Akhil Goyal
2017-07-25 11:21       ` [dpdk-dev] [RFC PATCH 1/1] rte_security: proposal Akhil Goyal
2017-07-26 13:46       ` [dpdk-dev] [RFC PATCH 0/1] IPSec Inline and look aside crypto offload Declan Doherty
2017-08-02 13:16         ` Hemant Agrawal
2017-08-03 11:25           ` Akhil Goyal
2017-08-15  6:35       ` [dpdk-dev] [RFC PATCH v2 0/4] " Akhil Goyal
2017-08-15  6:35         ` [dpdk-dev] [RFC PATCH 1/4] rte_security: API definitions Akhil Goyal
2017-08-15 11:04           ` Radu Nicolau
2017-08-16  7:39             ` Akhil Goyal
2017-08-16 15:40               ` Hemant Agrawal
2017-08-18  9:16                 ` Thomas Monjalon
2017-08-18 12:20                   ` Hemant Agrawal
2017-08-21 10:32                   ` Boris Pismenny
2017-08-21 10:54                     ` Akhil Goyal
2017-08-15  6:35         ` [dpdk-dev] [RFC PATCH 2/4] cryptodev: entend cryptodev to support security APIs Akhil Goyal
2017-08-15  6:35         ` [dpdk-dev] [RFC PATCH 3/4] crypto/dpaa2_sec: add support for protocol offload ipsec Akhil Goyal
2017-08-15  6:35         ` [dpdk-dev] [RFC PATCH 4/4] example/ipsec-secgw: add support for offloading crypto op Akhil Goyal
2017-08-29 14:49       ` [dpdk-dev] [RFC PATCH 0/1] IPSec Inline and look aside crypto offload Thomas Monjalon
2017-08-31  9:37         ` Akhil Goyal
2017-08-31 10:06           ` Thomas Monjalon
2017-08-31 10:52             ` Akhil Goyal
2017-08-31 13:14               ` Thomas Monjalon
2017-08-31 14:09                 ` Radu Nicolau
2017-09-06 15:53                   ` Jerin Jacob
2017-09-08 11:12                     ` Akhil Goyal
2017-09-11 18:10                       ` Jerin Jacob

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).