net/softnic: add meter profile

Implement meter profile add function.

Signed-off-by: Jasvinder Singh <jasvinder.singh@intel.com>
This commit is contained in:
Jasvinder Singh 2018-09-26 14:08:46 +01:00 committed by Cristian Dumitrescu
parent 9e800b9082
commit 0d73ddf25f
3 changed files with 155 additions and 1 deletions

View File

@ -190,6 +190,7 @@ pmd_dev_stop(struct rte_eth_dev *dev)
softnic_mempool_free(p);
tm_hierarchy_free(p);
softnic_mtr_free(p);
}
static void
@ -290,6 +291,7 @@ pmd_init(struct pmd_params *params)
/* Resources */
tm_hierarchy_init(p);
softnic_mtr_init(p);
softnic_mempool_init(p);
softnic_swq_init(p);
@ -344,6 +346,7 @@ pmd_free(struct pmd_internals *p)
softnic_mempool_free(p);
tm_hierarchy_free(p);
softnic_mtr_free(p);
rte_free(p);
}

View File

@ -22,6 +22,7 @@
#include <rte_ethdev_driver.h>
#include <rte_tm_driver.h>
#include <rte_flow_driver.h>
#include <rte_mtr_driver.h>
#include "rte_eth_softnic.h"
#include "conn.h"
@ -67,6 +68,24 @@ struct flow_internals {
struct flow_attr_map egress_map[SOFTNIC_FLOW_MAX_GROUPS];
};
/**
* Meter
*/
/* MTR meter profile */
struct softnic_mtr_meter_profile {
TAILQ_ENTRY(softnic_mtr_meter_profile) node;
uint32_t meter_profile_id;
struct rte_mtr_meter_profile params;
uint32_t n_users;
};
TAILQ_HEAD(softnic_mtr_meter_profile_list, softnic_mtr_meter_profile);
struct mtr_internals {
struct softnic_mtr_meter_profile_list meter_profiles;
};
/**
* MEMPOOL
*/
@ -525,6 +544,8 @@ struct pmd_internals {
} soft;
struct flow_internals flow;
struct mtr_internals mtr;
struct softnic_conn *conn;
struct softnic_mempool_list mempool_list;
struct softnic_swq_list swq_list;
@ -574,6 +595,16 @@ extern const struct rte_flow_ops pmd_flow_ops;
/**
* Meter
*/
int
softnic_mtr_init(struct pmd_internals *p);
void
softnic_mtr_free(struct pmd_internals *p);
struct softnic_mtr_meter_profile *
softnic_mtr_meter_profile_find(struct pmd_internals *p,
uint32_t meter_profile_id);
extern const struct rte_mtr_ops pmd_mtr_ops;
/**

View File

@ -11,10 +11,130 @@
#include "rte_eth_softnic_internals.h"
int
softnic_mtr_init(struct pmd_internals *p)
{
/* Initialize meter profiles list */
TAILQ_INIT(&p->mtr.meter_profiles);
return 0;
}
void
softnic_mtr_free(struct pmd_internals *p)
{
/* Remove meter profiles */
for ( ; ; ) {
struct softnic_mtr_meter_profile *mp;
mp = TAILQ_FIRST(&p->mtr.meter_profiles);
if (mp == NULL)
break;
TAILQ_REMOVE(&p->mtr.meter_profiles, mp, node);
free(mp);
}
}
struct softnic_mtr_meter_profile *
softnic_mtr_meter_profile_find(struct pmd_internals *p,
uint32_t meter_profile_id)
{
struct softnic_mtr_meter_profile_list *mpl = &p->mtr.meter_profiles;
struct softnic_mtr_meter_profile *mp;
TAILQ_FOREACH(mp, mpl, node)
if (meter_profile_id == mp->meter_profile_id)
return mp;
return NULL;
}
static int
meter_profile_check(struct rte_eth_dev *dev,
uint32_t meter_profile_id,
struct rte_mtr_meter_profile *profile,
struct rte_mtr_error *error)
{
struct pmd_internals *p = dev->data->dev_private;
struct softnic_mtr_meter_profile *mp;
/* Meter profile ID must be valid. */
if (meter_profile_id == UINT32_MAX)
return -rte_mtr_error_set(error,
EINVAL,
RTE_MTR_ERROR_TYPE_METER_PROFILE_ID,
NULL,
"Meter profile id not valid");
/* Meter profile must not exist. */
mp = softnic_mtr_meter_profile_find(p, meter_profile_id);
if (mp)
return -rte_mtr_error_set(error,
EEXIST,
RTE_MTR_ERROR_TYPE_METER_PROFILE_ID,
NULL,
"Meter prfile already exists");
/* Profile must not be NULL. */
if (profile == NULL)
return -rte_mtr_error_set(error,
EINVAL,
RTE_MTR_ERROR_TYPE_METER_PROFILE,
NULL,
"profile null");
/* Traffic metering algorithm : TRTCM_RFC2698 */
if (profile->alg != RTE_MTR_TRTCM_RFC2698)
return -rte_mtr_error_set(error,
EINVAL,
RTE_MTR_ERROR_TYPE_METER_PROFILE,
NULL,
"Metering alg not supported");
return 0;
}
/* MTR meter profile add */
static int
pmd_mtr_meter_profile_add(struct rte_eth_dev *dev,
uint32_t meter_profile_id,
struct rte_mtr_meter_profile *profile,
struct rte_mtr_error *error)
{
struct pmd_internals *p = dev->data->dev_private;
struct softnic_mtr_meter_profile_list *mpl = &p->mtr.meter_profiles;
struct softnic_mtr_meter_profile *mp;
int status;
/* Check input params */
status = meter_profile_check(dev, meter_profile_id, profile, error);
if (status)
return status;
/* Memory allocation */
mp = calloc(1, sizeof(struct softnic_mtr_meter_profile));
if (mp == NULL)
return -rte_mtr_error_set(error,
ENOMEM,
RTE_MTR_ERROR_TYPE_UNSPECIFIED,
NULL,
"Memory alloc failed");
/* Fill in */
mp->meter_profile_id = meter_profile_id;
memcpy(&mp->params, profile, sizeof(mp->params));
/* Add to list */
TAILQ_INSERT_TAIL(mpl, mp, node);
return 0;
}
const struct rte_mtr_ops pmd_mtr_ops = {
.capabilities_get = NULL,
.meter_profile_add = NULL,
.meter_profile_add = pmd_mtr_meter_profile_add,
.meter_profile_delete = NULL,
.create = NULL,