numam-dpdk/lib/librte_security/rte_security.c
Lukasz Wojciechowski e36b5a87d6 security: fix session counter
Fix session counter to be decreased in rte_security_session_destroy
only when session was successfully destroyed.

Formerly session counter was decreased prior session destroying
and returning session object to mempool. It remained decreased even
if session was not destroyed and mempool object released making counter
invalid.

Fixes: c261d1431bd8 ("security: introduce security API and framework")
Cc: stable@dpdk.org

Signed-off-by: Lukasz Wojciechowski <l.wojciechow@partner.samsung.com>
Acked-by: Anoob Joseph <anoobj@marvell.com>
Acked-by: Akhil Goyal <akhil.goyal@nxp.com>
2020-04-19 17:15:14 +02:00

179 lines
4.7 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)
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_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);
if (rte_mempool_get(mp, (void **)&sess))
return NULL;
if (instance->ops->session_create(instance->device, conf, sess, 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_CHAIN3_OR_ERR_RET(instance, ops, set_pkt_metadata, -EINVAL,
-ENOTSUP);
RTE_PTR_OR_ERR_RET(sess, -EINVAL);
#endif
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_CHAIN3_OR_ERR_RET(instance, ops, get_userdata, NULL, NULL);
#endif
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;
}
}
}
return NULL;
}