d08dcd28c3
Currently rte_security_set_pkt_metadata() and rte_security_get_userdata() methods to set pkt metadata on Inline outbound and get userdata after Inline inbound processing is always driver specific callbacks. For drivers that do not have much to do in the callbacks but just to update metadata in rte_security dynamic field and get userdata from rte_security dynamic field, having to just to PMD specific callback is costly per packet operation. This patch provides a mechanism to do the same in inline function and avoid function pointer jump if a driver supports the same. Signed-off-by: Nithin Dabilpuram <ndabilpuram@marvell.com> Acked-by: Konstantin Ananyev <konstantin.ananyev@intel.com> Acked-by: Akhil Goyal <gakhil@marvell.com>
206 lines
5.5 KiB
C
206 lines
5.5 KiB
C
/* SPDX-License-Identifier: BSD-3-Clause
|
|
* Copyright 2017 NXP.
|
|
* Copyright(c) 2017 Intel Corporation.
|
|
* Copyright (c) 2020 Samsung Electronics Co., Ltd All Rights Reserved
|
|
*/
|
|
|
|
#include <rte_malloc.h>
|
|
#include <rte_dev.h>
|
|
#include "rte_compat.h"
|
|
#include "rte_security.h"
|
|
#include "rte_security_driver.h"
|
|
|
|
/* Macro to check for invalid pointers */
|
|
#define RTE_PTR_OR_ERR_RET(ptr, retval) do { \
|
|
if ((ptr) == NULL) \
|
|
return retval; \
|
|
} while (0)
|
|
|
|
/* Macro to check for invalid pointers chains */
|
|
#define RTE_PTR_CHAIN3_OR_ERR_RET(p1, p2, p3, retval, last_retval) do { \
|
|
RTE_PTR_OR_ERR_RET(p1, retval); \
|
|
RTE_PTR_OR_ERR_RET(p1->p2, retval); \
|
|
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_t),
|
|
.align = __alignof__(rte_security_dynfield_t),
|
|
};
|
|
rte_security_dynfield_offset =
|
|
rte_mbuf_dynfield_register(&dynfield_desc);
|
|
return rte_security_dynfield_offset;
|
|
}
|
|
|
|
struct rte_security_session *
|
|
rte_security_session_create(struct rte_security_ctx *instance,
|
|
struct rte_security_session_conf *conf,
|
|
struct rte_mempool *mp,
|
|
struct rte_mempool *priv_mp)
|
|
{
|
|
struct rte_security_session *sess = NULL;
|
|
|
|
RTE_PTR_CHAIN3_OR_ERR_RET(instance, ops, session_create, NULL, NULL);
|
|
RTE_PTR_OR_ERR_RET(conf, NULL);
|
|
RTE_PTR_OR_ERR_RET(mp, NULL);
|
|
RTE_PTR_OR_ERR_RET(priv_mp, NULL);
|
|
|
|
if (rte_mempool_get(mp, (void **)&sess))
|
|
return NULL;
|
|
|
|
if (instance->ops->session_create(instance->device, conf,
|
|
sess, priv_mp)) {
|
|
rte_mempool_put(mp, (void *)sess);
|
|
return NULL;
|
|
}
|
|
instance->sess_cnt++;
|
|
|
|
return sess;
|
|
}
|
|
|
|
int
|
|
rte_security_session_update(struct rte_security_ctx *instance,
|
|
struct rte_security_session *sess,
|
|
struct rte_security_session_conf *conf)
|
|
{
|
|
RTE_PTR_CHAIN3_OR_ERR_RET(instance, ops, session_update, -EINVAL,
|
|
-ENOTSUP);
|
|
RTE_PTR_OR_ERR_RET(sess, -EINVAL);
|
|
RTE_PTR_OR_ERR_RET(conf, -EINVAL);
|
|
|
|
return instance->ops->session_update(instance->device, sess, conf);
|
|
}
|
|
|
|
unsigned int
|
|
rte_security_session_get_size(struct rte_security_ctx *instance)
|
|
{
|
|
RTE_PTR_CHAIN3_OR_ERR_RET(instance, ops, session_get_size, 0, 0);
|
|
|
|
return instance->ops->session_get_size(instance->device);
|
|
}
|
|
|
|
int
|
|
rte_security_session_stats_get(struct rte_security_ctx *instance,
|
|
struct rte_security_session *sess,
|
|
struct rte_security_stats *stats)
|
|
{
|
|
RTE_PTR_CHAIN3_OR_ERR_RET(instance, ops, session_stats_get, -EINVAL,
|
|
-ENOTSUP);
|
|
/* Parameter sess can be NULL in case of getting global statistics. */
|
|
RTE_PTR_OR_ERR_RET(stats, -EINVAL);
|
|
|
|
return instance->ops->session_stats_get(instance->device, sess, stats);
|
|
}
|
|
|
|
int
|
|
rte_security_session_destroy(struct rte_security_ctx *instance,
|
|
struct rte_security_session *sess)
|
|
{
|
|
int ret;
|
|
|
|
RTE_PTR_CHAIN3_OR_ERR_RET(instance, ops, session_destroy, -EINVAL,
|
|
-ENOTSUP);
|
|
RTE_PTR_OR_ERR_RET(sess, -EINVAL);
|
|
|
|
ret = instance->ops->session_destroy(instance->device, sess);
|
|
if (ret != 0)
|
|
return ret;
|
|
|
|
rte_mempool_put(rte_mempool_from_obj(sess), (void *)sess);
|
|
|
|
if (instance->sess_cnt)
|
|
instance->sess_cnt--;
|
|
|
|
return 0;
|
|
}
|
|
|
|
int
|
|
__rte_security_set_pkt_metadata(struct rte_security_ctx *instance,
|
|
struct rte_security_session *sess,
|
|
struct rte_mbuf *m, void *params)
|
|
{
|
|
#ifdef RTE_DEBUG
|
|
RTE_PTR_OR_ERR_RET(sess, -EINVAL);
|
|
RTE_PTR_OR_ERR_RET(instance, -EINVAL);
|
|
RTE_PTR_OR_ERR_RET(instance->ops, -EINVAL);
|
|
#endif
|
|
RTE_FUNC_PTR_OR_ERR_RET(*instance->ops->set_pkt_metadata, -ENOTSUP);
|
|
return instance->ops->set_pkt_metadata(instance->device,
|
|
sess, m, params);
|
|
}
|
|
|
|
void *
|
|
__rte_security_get_userdata(struct rte_security_ctx *instance, uint64_t md)
|
|
{
|
|
void *userdata = NULL;
|
|
|
|
#ifdef RTE_DEBUG
|
|
RTE_PTR_OR_ERR_RET(instance, NULL);
|
|
RTE_PTR_OR_ERR_RET(instance->ops, NULL);
|
|
#endif
|
|
RTE_FUNC_PTR_OR_ERR_RET(*instance->ops->get_userdata, NULL);
|
|
if (instance->ops->get_userdata(instance->device, md, &userdata))
|
|
return NULL;
|
|
|
|
return userdata;
|
|
}
|
|
|
|
const struct rte_security_capability *
|
|
rte_security_capabilities_get(struct rte_security_ctx *instance)
|
|
{
|
|
RTE_PTR_CHAIN3_OR_ERR_RET(instance, ops, capabilities_get, NULL, NULL);
|
|
|
|
return instance->ops->capabilities_get(instance->device);
|
|
}
|
|
|
|
const struct rte_security_capability *
|
|
rte_security_capability_get(struct rte_security_ctx *instance,
|
|
struct rte_security_capability_idx *idx)
|
|
{
|
|
const struct rte_security_capability *capabilities;
|
|
const struct rte_security_capability *capability;
|
|
uint16_t i = 0;
|
|
|
|
RTE_PTR_CHAIN3_OR_ERR_RET(instance, ops, capabilities_get, NULL, NULL);
|
|
RTE_PTR_OR_ERR_RET(idx, NULL);
|
|
|
|
capabilities = instance->ops->capabilities_get(instance->device);
|
|
|
|
if (capabilities == NULL)
|
|
return NULL;
|
|
|
|
while ((capability = &capabilities[i++])->action
|
|
!= RTE_SECURITY_ACTION_TYPE_NONE) {
|
|
if (capability->action == idx->action &&
|
|
capability->protocol == idx->protocol) {
|
|
if (idx->protocol == RTE_SECURITY_PROTOCOL_IPSEC) {
|
|
if (capability->ipsec.proto ==
|
|
idx->ipsec.proto &&
|
|
capability->ipsec.mode ==
|
|
idx->ipsec.mode &&
|
|
capability->ipsec.direction ==
|
|
idx->ipsec.direction)
|
|
return capability;
|
|
} else if (idx->protocol == RTE_SECURITY_PROTOCOL_PDCP) {
|
|
if (capability->pdcp.domain ==
|
|
idx->pdcp.domain)
|
|
return capability;
|
|
} else if (idx->protocol ==
|
|
RTE_SECURITY_PROTOCOL_DOCSIS) {
|
|
if (capability->docsis.direction ==
|
|
idx->docsis.direction)
|
|
return capability;
|
|
}
|
|
}
|
|
}
|
|
|
|
return NULL;
|
|
}
|