[v2,05/15] security: switch metadata to dynamic mbuf field
Checks
Commit Message
The device-specific metadata was stored in the deprecated field udata64.
It is moved to a dynamic mbuf field in order to allow removal of udata64.
Signed-off-by: Thomas Monjalon <thomas@monjalon.net>
---
doc/guides/prog_guide/rte_security.rst | 9 +++---
drivers/crypto/octeontx2/otx2_cryptodev_sec.c | 5 ++-
drivers/net/ixgbe/ixgbe_ipsec.c | 5 ++-
drivers/net/ixgbe/ixgbe_rxtx.c | 6 ++--
drivers/net/octeontx2/otx2_ethdev.h | 1 +
drivers/net/octeontx2/otx2_ethdev_sec.c | 5 ++-
drivers/net/octeontx2/otx2_ethdev_sec_tx.h | 2 +-
drivers/net/octeontx2/otx2_rx.h | 2 +-
examples/ipsec-secgw/ipsec-secgw.c | 9 +++---
examples/ipsec-secgw/ipsec_worker.c | 12 ++++---
lib/librte_security/rte_security.c | 22 +++++++++++++
lib/librte_security/rte_security.h | 32 +++++++++++++++++++
lib/librte_security/rte_security_driver.h | 3 ++
lib/librte_security/version.map | 3 ++
14 files changed, 96 insertions(+), 20 deletions(-)
Comments
> -----Original Message-----
> From: Thomas Monjalon <thomas@monjalon.net>
> Sent: Tuesday, October 27, 2020 06:20
> To: dev@dpdk.org
> Cc: Yigit, Ferruh <ferruh.yigit@intel.com>; david.marchand@redhat.com; Richardson, Bruce
> <bruce.richardson@intel.com>; olivier.matz@6wind.com; andrew.rybchenko@oktetlabs.ru;
> akhil.goyal@nxp.com; Doherty, Declan <declan.doherty@intel.com>; Ankur Dwivedi <adwivedi@marvell.com>;
> Anoob Joseph <anoobj@marvell.com>; Guo, Jia <jia.guo@intel.com>; Wang, Haiyue <haiyue.wang@intel.com>;
> Jerin Jacob <jerinj@marvell.com>; Nithin Dabilpuram <ndabilpuram@marvell.com>; Kiran Kumar K
> <kirankumark@marvell.com>; Nicolau, Radu <radu.nicolau@intel.com>; Ray Kinsella <mdr@ashroe.eu>; Neil
> Horman <nhorman@tuxdriver.com>
> Subject: [PATCH v2 05/15] security: switch metadata to dynamic mbuf field
>
> The device-specific metadata was stored in the deprecated field udata64.
> It is moved to a dynamic mbuf field in order to allow removal of udata64.
>
> Signed-off-by: Thomas Monjalon <thomas@monjalon.net>
> ---
> doc/guides/prog_guide/rte_security.rst | 9 +++---
> drivers/crypto/octeontx2/otx2_cryptodev_sec.c | 5 ++-
> drivers/net/ixgbe/ixgbe_ipsec.c | 5 ++-
> drivers/net/ixgbe/ixgbe_rxtx.c | 6 ++--
> drivers/net/octeontx2/otx2_ethdev.h | 1 +
> drivers/net/octeontx2/otx2_ethdev_sec.c | 5 ++-
> drivers/net/octeontx2/otx2_ethdev_sec_tx.h | 2 +-
> drivers/net/octeontx2/otx2_rx.h | 2 +-
> examples/ipsec-secgw/ipsec-secgw.c | 9 +++---
> examples/ipsec-secgw/ipsec_worker.c | 12 ++++---
> lib/librte_security/rte_security.c | 22 +++++++++++++
> lib/librte_security/rte_security.h | 32 +++++++++++++++++++
> lib/librte_security/rte_security_driver.h | 3 ++
> lib/librte_security/version.map | 3 ++
> 14 files changed, 96 insertions(+), 20 deletions(-)
>
For ixgbe PMD,
Acked-by: Haiyue Wang <haiyue.wang@intel.com>
But I feel that 'rte_security_dynfield' name is too generic, can it be
more specific about what the field is used for ?
Like below ;-)
#define RTE_SECURITY_DEV_METADATA(m) \
RTE_MBUF_DYNFIELD((m), \
rte_security_dev_metadata_offset, \
RTE_SECURITY_DEV_METADATA_TYPE *)
> +/**
> + * Get pointer to mbuf field for device-specific metadata.
> + *
> + * For performance reason, no check is done,
> + * the dynamic field may not be registered.
> + * @see rte_security_dynfield_is_registered
> + *
> + * @param mbuf packet to access
> + * @return pointer to mbuf field
> + */
> +static inline RTE_SECURITY_DYNFIELD_TYPE *
> +rte_security_dynfield(struct rte_mbuf *mbuf)
> +{
> + return RTE_MBUF_DYNFIELD(mbuf,
> + rte_security_dynfield_offset,
> + RTE_SECURITY_DYNFIELD_TYPE *);
> +}
> --
> 2.28.0
27/10/2020 03:01, Wang, Haiyue:
> From: Thomas Monjalon <thomas@monjalon.net>
> For ixgbe PMD,
>
> Acked-by: Haiyue Wang <haiyue.wang@intel.com>
>
> But I feel that 'rte_security_dynfield' name is too generic, can it be
> more specific about what the field is used for ?
>
> Like below ;-)
>
> #define RTE_SECURITY_DEV_METADATA(m) \
> RTE_MBUF_DYNFIELD((m), \
> rte_security_dev_metadata_offset, \
> RTE_SECURITY_DEV_METADATA_TYPE *)
Yes rte_security_dynfield is too much generic,
as well as RTE_SECURITY_DEV_METADATA.
It seems there are different data stored in this field.
We should have different fields for different data.
But such cleanup is another step for someone else.
On Mon, Oct 26, 2020 at 11:20:03PM +0100, Thomas Monjalon wrote:
> The device-specific metadata was stored in the deprecated field udata64.
> It is moved to a dynamic mbuf field in order to allow removal of udata64.
>
> Signed-off-by: Thomas Monjalon <thomas@monjalon.net>
> ---
> doc/guides/prog_guide/rte_security.rst | 9 +++---
> drivers/crypto/octeontx2/otx2_cryptodev_sec.c | 5 ++-
> drivers/net/ixgbe/ixgbe_ipsec.c | 5 ++-
> drivers/net/ixgbe/ixgbe_rxtx.c | 6 ++--
> drivers/net/octeontx2/otx2_ethdev.h | 1 +
> drivers/net/octeontx2/otx2_ethdev_sec.c | 5 ++-
> drivers/net/octeontx2/otx2_ethdev_sec_tx.h | 2 +-
> drivers/net/octeontx2/otx2_rx.h | 2 +-
> examples/ipsec-secgw/ipsec-secgw.c | 9 +++---
> examples/ipsec-secgw/ipsec_worker.c | 12 ++++---
> lib/librte_security/rte_security.c | 22 +++++++++++++
> lib/librte_security/rte_security.h | 32 +++++++++++++++++++
> lib/librte_security/rte_security_driver.h | 3 ++
> lib/librte_security/version.map | 3 ++
> 14 files changed, 96 insertions(+), 20 deletions(-)
>
<...>
> --- a/examples/ipsec-secgw/ipsec_worker.c
> +++ b/examples/ipsec-secgw/ipsec_worker.c
> @@ -208,7 +208,7 @@ process_ipsec_ev_inbound(struct ipsec_ctx *ctx, struct route_table *rt,
> "Inbound security offload failed\n");
> goto drop_pkt_and_exit;
> }
> - sa = pkt->userdata;
> + sa = *(struct ipsec_sa **)rte_security_dynfield(pkt);
> }
>
> /* Check if we have a match */
> @@ -226,7 +226,7 @@ process_ipsec_ev_inbound(struct ipsec_ctx *ctx, struct route_table *rt,
> "Inbound security offload failed\n");
> goto drop_pkt_and_exit;
> }
> - sa = pkt->userdata;
> + sa = *(struct ipsec_sa **)rte_security_dynfield(pkt);
> }
>
> /* Check if we have a match */
> @@ -357,7 +357,8 @@ process_ipsec_ev_outbound(struct ipsec_ctx *ctx, struct route_table *rt,
> }
>
> if (sess->security.ol_flags & RTE_SECURITY_TX_OLOAD_NEED_MDATA)
> - pkt->userdata = sess->security.ses;
> + *(struct rte_security_session **)rte_security_dynfield(pkt) =
> + sess->security.ses;
>
> /* Mark the packet for Tx security offload */
> pkt->ol_flags |= PKT_TX_SEC_OFFLOAD;
> @@ -465,7 +466,10 @@ ipsec_wrkr_non_burst_int_port_drv_mode(struct eh_event_link_info *links,
> }
>
> /* Save security session */
> - pkt->userdata = sess_tbl[port_id];
> + if (rte_security_dynfield_is_registered())
> + *(struct rte_security_session **)
> + rte_security_dynfield(pkt) =
> + sess_tbl[port_id];
>
Maybe the last 2 lines can be on the same line (a bit more than 80,
but less than 100 chars).
This is not clear to me why you need to call
rte_security_dynfield_is_registered() here, and not in other places.
Would it make sense instead to always register the dynfield at some
place in rte_security, so that we are sure that as soon as we use
rte_security, the dynfield is registered. A good place would be an init
function, but I don't see one.
> /* Mark the packet for Tx security offload */
> pkt->ol_flags |= PKT_TX_SEC_OFFLOAD;
> diff --git a/lib/librte_security/rte_security.c b/lib/librte_security/rte_security.c
> index ee4666026a..4fb0b797e9 100644
> --- a/lib/librte_security/rte_security.c
> +++ b/lib/librte_security/rte_security.c
> @@ -23,6 +23,28 @@
> RTE_PTR_OR_ERR_RET(p1->p2->p3, last_retval); \
> } while (0)
>
> +#define RTE_SECURITY_DYNFIELD_NAME "rte_security_dynfield_metadata"
> +int rte_security_dynfield_offset = -1;
> +
> +int
> +rte_security_dynfield_register(void)
> +{
> + static const struct rte_mbuf_dynfield dynfield_desc = {
> + .name = RTE_SECURITY_DYNFIELD_NAME,
> + .size = sizeof(RTE_SECURITY_DYNFIELD_TYPE),
> + .align = __alignof__(RTE_SECURITY_DYNFIELD_TYPE),
> + };
> + rte_security_dynfield_offset =
> + rte_mbuf_dynfield_register(&dynfield_desc);
> + return rte_security_dynfield_offset;
> +}
> +
> +bool
> +rte_security_dynfield_is_registered(void)
> +{
> + return rte_security_dynfield_offset >= 0;
> +}
> +
Wouldn't it be better to have it in a static inline function?
The point is just to check that offset is >= 0, and it is used
in data path.
> struct rte_security_session *
> rte_security_session_create(struct rte_security_ctx *instance,
> struct rte_security_session_conf *conf,
> diff --git a/lib/librte_security/rte_security.h b/lib/librte_security/rte_security.h
> index 271531af12..7fbdee99cc 100644
> --- a/lib/librte_security/rte_security.h
> +++ b/lib/librte_security/rte_security.h
> @@ -27,6 +27,7 @@ extern "C" {
> #include <rte_common.h>
> #include <rte_crypto.h>
> #include <rte_mbuf.h>
> +#include <rte_mbuf_dyn.h>
> #include <rte_memory.h>
> #include <rte_mempool.h>
>
> @@ -451,6 +452,37 @@ int
> rte_security_session_destroy(struct rte_security_ctx *instance,
> struct rte_security_session *sess);
>
> +/** Device-specific metadata field type */
> +#define RTE_SECURITY_DYNFIELD_TYPE uint64_t
What about using a typedef instead of a #define?
It could be in lowercase: rte_security_dynfield_t
> -----Original Message-----
> From: Thomas Monjalon <thomas@monjalon.net>
> Sent: Tuesday, October 27, 2020 16:52
> To: Wang, Haiyue <haiyue.wang@intel.com>
> Cc: dev@dpdk.org; Yigit, Ferruh <ferruh.yigit@intel.com>; david.marchand@redhat.com; Richardson, Bruce
> <bruce.richardson@intel.com>; olivier.matz@6wind.com; andrew.rybchenko@oktetlabs.ru;
> akhil.goyal@nxp.com; Doherty, Declan <declan.doherty@intel.com>; Ankur Dwivedi <adwivedi@marvell.com>;
> Anoob Joseph <anoobj@marvell.com>; Guo, Jia <jia.guo@intel.com>; Jerin Jacob <jerinj@marvell.com>;
> Nithin Dabilpuram <ndabilpuram@marvell.com>; Kiran Kumar K <kirankumark@marvell.com>; Nicolau, Radu
> <radu.nicolau@intel.com>; Ray Kinsella <mdr@ashroe.eu>; Neil Horman <nhorman@tuxdriver.com>
> Subject: Re: [PATCH v2 05/15] security: switch metadata to dynamic mbuf field
>
> 27/10/2020 03:01, Wang, Haiyue:
> > From: Thomas Monjalon <thomas@monjalon.net>
> > For ixgbe PMD,
> >
> > Acked-by: Haiyue Wang <haiyue.wang@intel.com>
> >
> > But I feel that 'rte_security_dynfield' name is too generic, can it be
> > more specific about what the field is used for ?
> >
> > Like below ;-)
> >
> > #define RTE_SECURITY_DEV_METADATA(m) \
> > RTE_MBUF_DYNFIELD((m), \
> > rte_security_dev_metadata_offset, \
> > RTE_SECURITY_DEV_METADATA_TYPE *)
>
> Yes rte_security_dynfield is too much generic,
> as well as RTE_SECURITY_DEV_METADATA.
> It seems there are different data stored in this field.
> We should have different fields for different data.
> But such cleanup is another step for someone else.
Understood, thanks, then 'DEV_METADATA' is also generic.
>
>
27/10/2020 11:05, Olivier Matz:
> On Mon, Oct 26, 2020 at 11:20:03PM +0100, Thomas Monjalon wrote:
> > The device-specific metadata was stored in the deprecated field udata64.
> > It is moved to a dynamic mbuf field in order to allow removal of udata64.
> >
> > Signed-off-by: Thomas Monjalon <thomas@monjalon.net>
> <...>
> > /* Save security session */
> > - pkt->userdata = sess_tbl[port_id];
> > + if (rte_security_dynfield_is_registered())
> > + *(struct rte_security_session **)
> > + rte_security_dynfield(pkt) =
> > + sess_tbl[port_id];
> >
>
> Maybe the last 2 lines can be on the same line (a bit more than 80,
> but less than 100 chars).
I prefer limiting to 80 if possible.
> This is not clear to me why you need to call
> rte_security_dynfield_is_registered() here, and not in other places.
I think other places are paths for rte_security only.
> Would it make sense instead to always register the dynfield at some
> place in rte_security, so that we are sure that as soon as we use
> rte_security, the dynfield is registered. A good place would be an init
> function, but I don't see one.
Indeed there is no such place in rte_security.
I keep thinking this is not a real library.
> > +bool
> > +rte_security_dynfield_is_registered(void)
> > +{
> > + return rte_security_dynfield_offset >= 0;
> > +}
> > +
>
> Wouldn't it be better to have it in a static inline function?
> The point is just to check that offset is >= 0, and it is used
> in data path.
Yes I'll make it inline
> > +/** Device-specific metadata field type */
> > +#define RTE_SECURITY_DYNFIELD_TYPE uint64_t
>
> What about using a typedef instead of a #define?
> It could be in lowercase: rte_security_dynfield_t
Yes
@@ -125,8 +125,9 @@ ESP/AH headers will be removed from the packet and the received packet
will contains the decrypted packet only. The driver Rx path checks the
descriptors and based on the crypto status sets additional flags in
``rte_mbuf.ol_flags`` field. The driver would also set device-specific
-metadata in ``rte_mbuf.udata64`` field. This will allow the application
-to identify the security processing done on the packet.
+metadata in ``RTE_SECURITY_DYNFIELD_NAME`` field.
+This will allow the application to identify the security processing
+done on the packet.
.. note::
@@ -568,8 +569,8 @@ security session which processed the packet.
.. note::
- In case of inline processed packets, ``rte_mbuf.udata64`` field would be
- used by the driver to relay information on the security processing
+ In case of inline processed packets, ``RTE_SECURITY_DYNFIELD_NAME`` field
+ would be used by the driver to relay information on the security processing
associated with the packet. In ingress, the driver would set this in Rx
path while in egress, ``rte_security_set_pkt_metadata()`` would perform a
similar operation. The application is expected not to modify the field
@@ -455,6 +455,9 @@ otx2_crypto_sec_session_create(void *device,
if (conf->action_type != RTE_SECURITY_ACTION_TYPE_LOOKASIDE_PROTOCOL)
return -ENOTSUP;
+ if (rte_security_dynfield_register() < 0)
+ return -rte_errno;
+
if (rte_mempool_get(mempool, (void **)&priv)) {
otx2_err("Could not allocate security session private data");
return -ENOMEM;
@@ -514,7 +517,7 @@ otx2_crypto_sec_set_pkt_mdata(void *device __rte_unused,
struct rte_mbuf *m, void *params __rte_unused)
{
/* Set security session as the pkt metadata */
- m->udata64 = (uint64_t)session;
+ *rte_security_dynfield(m) = (RTE_SECURITY_DYNFIELD_TYPE)session;
return 0;
}
@@ -484,7 +484,8 @@ ixgbe_crypto_update_mb(void *device __rte_unused,
get_sec_session_private_data(session);
if (ic_session->op == IXGBE_OP_AUTHENTICATED_ENCRYPTION) {
union ixgbe_crypto_tx_desc_md *mdata =
- (union ixgbe_crypto_tx_desc_md *)&m->udata64;
+ (union ixgbe_crypto_tx_desc_md *)
+ rte_security_dynfield(m);
mdata->enc = 1;
mdata->sa_idx = ic_session->sa_index;
mdata->pad_len = ixgbe_crypto_compute_pad_len(m);
@@ -751,5 +752,7 @@ ixgbe_ipsec_ctx_create(struct rte_eth_dev *dev)
return -ENOMEM;
}
}
+ if (rte_security_dynfield_register() < 0)
+ return -rte_errno;
return 0;
}
@@ -34,6 +34,7 @@
#include <rte_mbuf.h>
#include <rte_ether.h>
#include <rte_ethdev_driver.h>
+#include <rte_security_driver.h>
#include <rte_prefetch.h>
#include <rte_udp.h>
#include <rte_tcp.h>
@@ -694,7 +695,7 @@ ixgbe_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts,
if (use_ipsec) {
union ixgbe_crypto_tx_desc_md *ipsec_mdata =
(union ixgbe_crypto_tx_desc_md *)
- &tx_pkt->udata64;
+ rte_security_dynfield(tx_pkt);
tx_offload.sa_idx = ipsec_mdata->sa_idx;
tx_offload.sec_pad_len = ipsec_mdata->pad_len;
}
@@ -859,7 +860,8 @@ ixgbe_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts,
}
ixgbe_set_xmit_ctx(txq, ctx_txd, tx_ol_req,
- tx_offload, &tx_pkt->udata64);
+ tx_offload,
+ rte_security_dynfield(tx_pkt));
txe->last_id = tx_last;
tx_id = txe->next_id;
@@ -13,6 +13,7 @@
#include <rte_kvargs.h>
#include <rte_mbuf.h>
#include <rte_mempool.h>
+#include <rte_security_driver.h>
#include <rte_string_fns.h>
#include <rte_time.h>
@@ -684,7 +684,7 @@ otx2_eth_sec_set_pkt_mdata(void *device __rte_unused,
struct rte_mbuf *m, void *params __rte_unused)
{
/* Set security session as the pkt metadata */
- m->udata64 = (uint64_t)session;
+ *rte_security_dynfield(m) = (RTE_SECURITY_DYNFIELD_TYPE)session;
return 0;
}
@@ -831,6 +831,9 @@ otx2_eth_sec_init(struct rte_eth_dev *eth_dev)
!(dev->rx_offloads & DEV_RX_OFFLOAD_SECURITY))
return 0;
+ if (rte_security_dynfield_register() < 0)
+ return -rte_errno;
+
nb_sa = dev->ipsec_in_max_spi;
mz_sz = nb_sa * sa_width;
in_sa_mz_name_get(name, RTE_MEMZONE_NAMESIZE, port);
@@ -55,7 +55,7 @@ otx2_sec_event_tx(struct otx2_ssogws *ws, struct rte_event *ev,
struct nix_iova_s nix_iova;
} *sd;
- priv = get_sec_session_private_data((void *)(m->udata64));
+ priv = get_sec_session_private_data((void *)(*rte_security_dynfield(m)));
sess = &priv->ipsec.ip;
sa = &sess->out_sa;
@@ -241,7 +241,7 @@ nix_rx_sec_mbuf_update(const struct nix_cqe_hdr_s *cq, struct rte_mbuf *m,
spi = cq->tag & 0xFFFFF;
sa = nix_rx_sec_sa_get(lookup_mem, spi, m->port);
- m->udata64 = (uint64_t)sa->userdata;
+ *rte_security_dynfield(m) = sa->udata64;
data = rte_pktmbuf_mtod(m, char *);
@@ -426,7 +426,8 @@ prepare_one_packet(struct rte_mbuf *pkt, struct ipsec_traffic *t)
* with the security session.
*/
- if (pkt->ol_flags & PKT_RX_SEC_OFFLOAD) {
+ if (pkt->ol_flags & PKT_RX_SEC_OFFLOAD &&
+ rte_security_dynfield_is_registered()) {
struct ipsec_sa *sa;
struct ipsec_mbuf_metadata *priv;
struct rte_security_ctx *ctx = (struct rte_security_ctx *)
@@ -436,10 +437,8 @@ prepare_one_packet(struct rte_mbuf *pkt, struct ipsec_traffic *t)
/* Retrieve the userdata registered. Here, the userdata
* registered is the SA pointer.
*/
-
- sa = (struct ipsec_sa *)
- rte_security_get_userdata(ctx, pkt->udata64);
-
+ sa = (struct ipsec_sa *)rte_security_get_userdata(ctx,
+ *rte_security_dynfield(pkt));
if (sa == NULL) {
/* userdata could not be retrieved */
return;
@@ -208,7 +208,7 @@ process_ipsec_ev_inbound(struct ipsec_ctx *ctx, struct route_table *rt,
"Inbound security offload failed\n");
goto drop_pkt_and_exit;
}
- sa = pkt->userdata;
+ sa = *(struct ipsec_sa **)rte_security_dynfield(pkt);
}
/* Check if we have a match */
@@ -226,7 +226,7 @@ process_ipsec_ev_inbound(struct ipsec_ctx *ctx, struct route_table *rt,
"Inbound security offload failed\n");
goto drop_pkt_and_exit;
}
- sa = pkt->userdata;
+ sa = *(struct ipsec_sa **)rte_security_dynfield(pkt);
}
/* Check if we have a match */
@@ -357,7 +357,8 @@ process_ipsec_ev_outbound(struct ipsec_ctx *ctx, struct route_table *rt,
}
if (sess->security.ol_flags & RTE_SECURITY_TX_OLOAD_NEED_MDATA)
- pkt->userdata = sess->security.ses;
+ *(struct rte_security_session **)rte_security_dynfield(pkt) =
+ sess->security.ses;
/* Mark the packet for Tx security offload */
pkt->ol_flags |= PKT_TX_SEC_OFFLOAD;
@@ -465,7 +466,10 @@ ipsec_wrkr_non_burst_int_port_drv_mode(struct eh_event_link_info *links,
}
/* Save security session */
- pkt->userdata = sess_tbl[port_id];
+ if (rte_security_dynfield_is_registered())
+ *(struct rte_security_session **)
+ rte_security_dynfield(pkt) =
+ sess_tbl[port_id];
/* Mark the packet for Tx security offload */
pkt->ol_flags |= PKT_TX_SEC_OFFLOAD;
@@ -23,6 +23,28 @@
RTE_PTR_OR_ERR_RET(p1->p2->p3, last_retval); \
} while (0)
+#define RTE_SECURITY_DYNFIELD_NAME "rte_security_dynfield_metadata"
+int rte_security_dynfield_offset = -1;
+
+int
+rte_security_dynfield_register(void)
+{
+ static const struct rte_mbuf_dynfield dynfield_desc = {
+ .name = RTE_SECURITY_DYNFIELD_NAME,
+ .size = sizeof(RTE_SECURITY_DYNFIELD_TYPE),
+ .align = __alignof__(RTE_SECURITY_DYNFIELD_TYPE),
+ };
+ rte_security_dynfield_offset =
+ rte_mbuf_dynfield_register(&dynfield_desc);
+ return rte_security_dynfield_offset;
+}
+
+bool
+rte_security_dynfield_is_registered(void)
+{
+ return rte_security_dynfield_offset >= 0;
+}
+
struct rte_security_session *
rte_security_session_create(struct rte_security_ctx *instance,
struct rte_security_session_conf *conf,
@@ -27,6 +27,7 @@ extern "C" {
#include <rte_common.h>
#include <rte_crypto.h>
#include <rte_mbuf.h>
+#include <rte_mbuf_dyn.h>
#include <rte_memory.h>
#include <rte_mempool.h>
@@ -451,6 +452,37 @@ int
rte_security_session_destroy(struct rte_security_ctx *instance,
struct rte_security_session *sess);
+/** Device-specific metadata field type */
+#define RTE_SECURITY_DYNFIELD_TYPE uint64_t
+/** Dynamic mbuf field for device-specific metadata */
+extern int rte_security_dynfield_offset;
+
+/**
+ * Get pointer to mbuf field for device-specific metadata.
+ *
+ * For performance reason, no check is done,
+ * the dynamic field may not be registered.
+ * @see rte_security_dynfield_is_registered
+ *
+ * @param mbuf packet to access
+ * @return pointer to mbuf field
+ */
+static inline RTE_SECURITY_DYNFIELD_TYPE *
+rte_security_dynfield(struct rte_mbuf *mbuf)
+{
+ return RTE_MBUF_DYNFIELD(mbuf,
+ rte_security_dynfield_offset,
+ RTE_SECURITY_DYNFIELD_TYPE *);
+}
+
+/**
+ * Check whether the dynamic field is registered.
+ *
+ * @return true if rte_security_dynfield_register() has been called.
+ */
+__rte_experimental
+bool rte_security_dynfield_is_registered(void);
+
/**
* Updates the buffer with device-specific defined metadata
*
@@ -89,6 +89,9 @@ typedef int (*security_session_stats_get_t)(void *device,
struct rte_security_session *sess,
struct rte_security_stats *stats);
+__rte_experimental
+int rte_security_dynfield_register(void);
+
/**
* Update the mbuf with provided metadata.
*
@@ -15,6 +15,9 @@ DPDK_21 {
EXPERIMENTAL {
global:
+ rte_security_dynfield_is_registered;
+ rte_security_dynfield_offset;
+ rte_security_dynfield_register;
rte_security_get_userdata;
rte_security_session_stats_get;
rte_security_session_update;