Skip to content

Commit

Permalink
net/nfp: support merged flows and conntrack stats
Browse files Browse the repository at this point in the history
Adjust the original logic to make it valid for both normal flow
and merged flow.
Add the logic to update conntrack flow stats.
Add the support of conntrack action.

Signed-off-by: Chaoyong He <[email protected]>
  • Loading branch information
hechaoyong authored and ferruhy committed Oct 4, 2023
1 parent b4ae16e commit 7d18af7
Show file tree
Hide file tree
Showing 4 changed files with 126 additions and 17 deletions.
54 changes: 49 additions & 5 deletions drivers/net/nfp/flower/nfp_conntrack.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ struct nfp_ct_flow_entry {
struct nfp_flower_representor *repr;
struct nfp_ct_zone_entry *ze;
struct nfp_initial_flow rule;
struct nfp_fl_stats stats;
};

struct nfp_ct_map_entry {
Expand All @@ -56,6 +57,7 @@ struct nfp_ct_zone_entry {

struct nfp_ct_merge_entry {
uint64_t cookie[2];
uint32_t ctx_id;
LIST_ENTRY(nfp_ct_merge_entry) pre_ct_list;
LIST_ENTRY(nfp_ct_merge_entry) post_ct_list;
struct nfp_initial_flow rule;
Expand Down Expand Up @@ -990,12 +992,14 @@ nfp_ct_offload_add(struct nfp_flower_representor *repr,
cookie = rte_rand();
items = merge_entry->rule.items;
actions = merge_entry->rule.actions;
nfp_flow = nfp_flow_process(repr, items, actions, false, cookie, true);
nfp_flow = nfp_flow_process(repr, items, actions, false, cookie, true, true);
if (nfp_flow == NULL) {
PMD_DRV_LOG(ERR, "Process the merged flow rule failed.");
return -EINVAL;
}

merge_entry->ctx_id = rte_be_to_cpu_32(nfp_flow->payload.meta->host_ctx_id);

/* Add the flow to hardware */
priv = repr->app_fw_flower->flow_priv;
ret = nfp_flower_cmsg_flow_add(repr->app_fw_flower, nfp_flow);
Expand All @@ -1005,7 +1009,7 @@ nfp_ct_offload_add(struct nfp_flower_representor *repr,
}

/* Add the flow to flow hash table */
ret = nfp_flow_table_add(priv, nfp_flow);
ret = nfp_flow_table_add_merge(priv, nfp_flow);
if (ret != 0) {
PMD_DRV_LOG(ERR, "Add the merged flow to flow table failed.");
goto flow_teardown;
Expand Down Expand Up @@ -1693,14 +1697,14 @@ nfp_ct_flow_setup(struct nfp_flower_representor *representor,

if (is_ct_commit_flow(ct)) {
return nfp_flow_process(representor, &items[1], actions,
validate_flag, cookie, false);
validate_flag, cookie, false, false);
}

if (is_post_ct_flow(ct)) {
if (nfp_flow_handle_post_ct(ct_item, representor, &items[1],
actions, cookie)) {
return nfp_flow_process(representor, &items[1], actions,
validate_flag, cookie, false);
validate_flag, cookie, false, false);
}

PMD_DRV_LOG(ERR, "Handle nfp post ct flow failed.");
Expand All @@ -1711,7 +1715,7 @@ nfp_ct_flow_setup(struct nfp_flower_representor *representor,
if (nfp_flow_handle_pre_ct(ct_item, representor, &items[1],
actions, cookie)) {
return nfp_flow_process(representor, &items[1], actions,
validate_flag, cookie, false);
validate_flag, cookie, false, false);
}

PMD_DRV_LOG(ERR, "Handle nfp pre ct flow failed.");
Expand All @@ -1721,3 +1725,43 @@ nfp_ct_flow_setup(struct nfp_flower_representor *representor,
PMD_DRV_LOG(ERR, "Unsupported ct flow type.");
return NULL;
}

static inline void
nfp_ct_flow_stats_update(struct nfp_flow_priv *priv,
struct nfp_ct_merge_entry *m_ent)
{
uint32_t ctx_id;
struct nfp_fl_stats *merge_stats;

ctx_id = m_ent->ctx_id;
merge_stats = &priv->stats[ctx_id];

m_ent->pre_ct_parent->stats.bytes += merge_stats->bytes;
m_ent->pre_ct_parent->stats.pkts += merge_stats->pkts;
m_ent->post_ct_parent->stats.bytes += merge_stats->bytes;
m_ent->post_ct_parent->stats.pkts += merge_stats->pkts;

merge_stats->bytes = 0;
merge_stats->pkts = 0;
}

struct nfp_fl_stats *
nfp_ct_flow_stats_get(struct nfp_flow_priv *priv,
struct nfp_ct_map_entry *me)
{
struct nfp_ct_merge_entry *m_ent;

rte_spinlock_lock(&priv->stats_lock);

if (me->fe->type == CT_TYPE_PRE_CT) {
LIST_FOREACH(m_ent, &me->fe->children, pre_ct_list)
nfp_ct_flow_stats_update(priv, m_ent);
} else {
LIST_FOREACH(m_ent, &me->fe->children, post_ct_list)
nfp_ct_flow_stats_update(priv, m_ent);
}

rte_spinlock_unlock(&priv->stats_lock);

return &me->fe->stats;
}
3 changes: 3 additions & 0 deletions drivers/net/nfp/flower/nfp_conntrack.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,4 +34,7 @@ struct rte_flow *nfp_ct_flow_setup(struct nfp_flower_representor *representor,
bool validate_flag,
uint64_t cookie);

struct nfp_fl_stats *nfp_ct_flow_stats_get(struct nfp_flow_priv *priv,
struct nfp_ct_map_entry *me);

#endif /* __NFP_CONNTRACK_H__ */
79 changes: 69 additions & 10 deletions drivers/net/nfp/nfp_flow.c
Original file line number Diff line number Diff line change
Expand Up @@ -310,14 +310,14 @@ nfp_check_mask_add(struct nfp_flow_priv *priv,
ret = nfp_mask_table_add(priv, mask_data, mask_len, mask_id);
if (ret != 0)
return false;

*meta_flags |= NFP_FL_META_FLAG_MANAGE_MASK;
} else {
/* mask entry already exist */
mask_entry->ref_cnt++;
*mask_id = mask_entry->mask_id;
}

*meta_flags |= NFP_FL_META_FLAG_MANAGE_MASK;

return true;
}

Expand Down Expand Up @@ -349,7 +349,7 @@ nfp_check_mask_remove(struct nfp_flow_priv *priv,
return true;
}

int
static int
nfp_flow_table_add(struct nfp_flow_priv *priv,
struct rte_flow *nfp_flow)
{
Expand Down Expand Up @@ -396,6 +396,48 @@ nfp_flow_table_search(struct nfp_flow_priv *priv,
return flow_find;
}

int
nfp_flow_table_add_merge(struct nfp_flow_priv *priv,
struct rte_flow *nfp_flow)
{
struct rte_flow *flow_find;

flow_find = nfp_flow_table_search(priv, nfp_flow);
if (flow_find != NULL) {
if (nfp_flow->merge_flag || flow_find->merge_flag) {
flow_find->merge_flag = true;
flow_find->ref_cnt++;
return 0;
}

PMD_DRV_LOG(ERR, "Add to flow table failed.");
return -EINVAL;
}

return nfp_flow_table_add(priv, nfp_flow);
}

static int
nfp_flow_table_delete_merge(struct nfp_flow_priv *priv,
struct rte_flow *nfp_flow)
{
struct rte_flow *flow_find;

flow_find = nfp_flow_table_search(priv, nfp_flow);
if (flow_find == NULL) {
PMD_DRV_LOG(ERR, "Can't delete a non-existing flow.");
return -EINVAL;
}

if (nfp_flow->merge_flag || flow_find->merge_flag) {
flow_find->ref_cnt--;
if (flow_find->ref_cnt > 0)
return 0;
}

return nfp_flow_table_delete(priv, nfp_flow);
}

static struct rte_flow *
nfp_flow_alloc(struct nfp_fl_key_ls *key_layer, uint32_t port_id)
{
Expand Down Expand Up @@ -1082,6 +1124,9 @@ nfp_flow_key_layers_calculate_actions(const struct rte_flow_action actions[],
return -ENOTSUP;
}
break;
case RTE_FLOW_ACTION_TYPE_CONNTRACK:
PMD_DRV_LOG(DEBUG, "RTE_FLOW_ACTION_TYPE_CONNTRACK detected");
break;
default:
PMD_DRV_LOG(ERR, "Action type %d not supported.", action->type);
return -ENOTSUP;
Expand Down Expand Up @@ -3626,6 +3671,9 @@ nfp_flow_compile_action(struct nfp_flower_representor *representor,
return -EINVAL;
position += sizeof(struct nfp_fl_act_meter);
break;
case RTE_FLOW_ACTION_TYPE_CONNTRACK:
PMD_DRV_LOG(DEBUG, "Process RTE_FLOW_ACTION_TYPE_CONNTRACK");
break;
default:
PMD_DRV_LOG(ERR, "Unsupported action type: %d", action->type);
return -ENOTSUP;
Expand All @@ -3647,7 +3695,8 @@ nfp_flow_process(struct nfp_flower_representor *representor,
const struct rte_flow_action actions[],
bool validate_flag,
uint64_t cookie,
bool install_flag)
bool install_flag,
bool merge_flag)
{
int ret;
char *hash_data;
Expand Down Expand Up @@ -3684,6 +3733,7 @@ nfp_flow_process(struct nfp_flower_representor *representor,
}

nfp_flow->install_flag = install_flag;
nfp_flow->merge_flag = merge_flag;

nfp_flow_compile_metadata(priv, nfp_flow, &key_layer, stats_ctx, cookie);

Expand Down Expand Up @@ -3717,7 +3767,7 @@ nfp_flow_process(struct nfp_flower_representor *representor,

/* Find the flow in hash table */
flow_find = nfp_flow_table_search(priv, nfp_flow);
if (flow_find != NULL) {
if (flow_find != NULL && !nfp_flow->merge_flag && !flow_find->merge_flag) {
PMD_DRV_LOG(ERR, "This flow is already exist.");
if (!nfp_check_mask_remove(priv, mask_data, mask_len,
&nfp_flow_meta->flags)) {
Expand Down Expand Up @@ -3774,7 +3824,7 @@ nfp_flow_setup(struct nfp_flower_representor *representor,
return nfp_ct_flow_setup(representor, items, actions,
ct_item, validate_flag, cookie);

return nfp_flow_process(representor, items, actions, validate_flag, cookie, true);
return nfp_flow_process(representor, items, actions, validate_flag, cookie, true, false);
}

int
Expand Down Expand Up @@ -3877,7 +3927,7 @@ nfp_flow_create(struct rte_eth_dev *dev,
}

/* Add the flow to flow hash table */
ret = nfp_flow_table_add(priv, nfp_flow);
ret = nfp_flow_table_add_merge(priv, nfp_flow);
if (ret != 0) {
rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
NULL, "Add flow to the flow table failed.");
Expand Down Expand Up @@ -3988,7 +4038,7 @@ nfp_flow_destroy(struct rte_eth_dev *dev,
}

/* Delete the flow from flow hash table */
ret = nfp_flow_table_delete(priv, nfp_flow);
ret = nfp_flow_table_delete_merge(priv, nfp_flow);
if (ret != 0) {
rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
NULL, "Delete flow from the flow table failed.");
Expand Down Expand Up @@ -4047,10 +4097,12 @@ nfp_flow_stats_get(struct rte_eth_dev *dev,
void *data)
{
bool reset;
uint64_t cookie;
uint32_t ctx_id;
struct rte_flow *flow;
struct nfp_flow_priv *priv;
struct nfp_fl_stats *stats;
struct nfp_ct_map_entry *me;
struct rte_flow_query_count *query;

priv = nfp_flow_dev_to_priv(dev);
Expand All @@ -4064,8 +4116,15 @@ nfp_flow_stats_get(struct rte_eth_dev *dev,
reset = query->reset;
memset(query, 0, sizeof(*query));

ctx_id = rte_be_to_cpu_32(nfp_flow->payload.meta->host_ctx_id);
stats = &priv->stats[ctx_id];
/* Find the flow in ct_map_table */
cookie = rte_be_to_cpu_64(nfp_flow->payload.meta->host_cookie);
me = nfp_ct_map_table_search(priv, (char *)&cookie, sizeof(uint64_t));
if (me != NULL) {
stats = nfp_ct_flow_stats_get(priv, me);
} else {
ctx_id = rte_be_to_cpu_32(nfp_flow->payload.meta->host_ctx_id);
stats = &priv->stats[ctx_id];
}

rte_spinlock_lock(&priv->stats_lock);
if (stats->pkts != 0 && stats->bytes != 0) {
Expand Down
7 changes: 5 additions & 2 deletions drivers/net/nfp/nfp_flow.h
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,9 @@ struct rte_flow {
uint32_t port_id;
bool install_flag;
bool tcp_flag; /**< Used in the SET_TP_* action */
bool merge_flag;
enum nfp_flow_type type;
uint16_t ref_cnt;
};

/* Forward declaration */
Expand All @@ -181,8 +183,9 @@ struct rte_flow *nfp_flow_process(struct nfp_flower_representor *representor,
const struct rte_flow_action actions[],
bool validate_flag,
uint64_t cookie,
bool install_flag);
int nfp_flow_table_add(struct nfp_flow_priv *priv,
bool install_flag,
bool merge_flag);
int nfp_flow_table_add_merge(struct nfp_flow_priv *priv,
struct rte_flow *nfp_flow);
int nfp_flow_teardown(struct nfp_flow_priv *priv,
struct rte_flow *nfp_flow,
Expand Down

0 comments on commit 7d18af7

Please sign in to comment.