mirror of
git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-09-18 22:14:16 +00:00
nfp: flower-ct: add a table to map flow cookies to ct flows
Add a hashtable which contains entries to map flow cookies to ct flow entries. Currently the entries are added and not used, but follow-up patches will use this for stats updates and flow deletes. Signed-off-by: Louis Peens <louis.peens@corigine.com> Signed-off-by: Yinjun Zhang <yinjun.zhang@corigine.com> Signed-off-by: Simon Horman <simon.horman@corigine.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
072c089ca5
commit
fa81d6d214
4 changed files with 89 additions and 7 deletions
|
@ -107,9 +107,11 @@ err_zone_insert:
|
|||
static struct
|
||||
nfp_fl_ct_flow_entry *nfp_fl_ct_add_flow(struct nfp_fl_ct_zone_entry *zt,
|
||||
struct net_device *netdev,
|
||||
struct flow_cls_offload *flow)
|
||||
struct flow_cls_offload *flow,
|
||||
struct netlink_ext_ack *extack)
|
||||
{
|
||||
struct nfp_fl_ct_flow_entry *entry;
|
||||
struct nfp_fl_ct_map_entry *map;
|
||||
struct flow_action_entry *act;
|
||||
int err, i;
|
||||
|
||||
|
@ -160,12 +162,33 @@ nfp_fl_ct_flow_entry *nfp_fl_ct_add_flow(struct nfp_fl_ct_zone_entry *zt,
|
|||
|
||||
INIT_LIST_HEAD(&entry->children);
|
||||
|
||||
/* Creation of a ct_map_entry and adding it to a hashtable
|
||||
* will happen here in follow up patches.
|
||||
*/
|
||||
/* Now add a ct map entry to flower-priv */
|
||||
map = get_hashentry(&zt->priv->ct_map_table, &flow->cookie,
|
||||
nfp_ct_map_params, sizeof(*map));
|
||||
if (IS_ERR(map)) {
|
||||
NL_SET_ERR_MSG_MOD(extack,
|
||||
"offload error: ct map entry creation failed");
|
||||
err = -ENOMEM;
|
||||
goto err_ct_flow_insert;
|
||||
}
|
||||
map->cookie = flow->cookie;
|
||||
map->ct_entry = entry;
|
||||
err = rhashtable_insert_fast(&zt->priv->ct_map_table,
|
||||
&map->hash_node,
|
||||
nfp_ct_map_params);
|
||||
if (err) {
|
||||
NL_SET_ERR_MSG_MOD(extack,
|
||||
"offload error: ct map entry table add failed");
|
||||
goto err_map_insert;
|
||||
}
|
||||
|
||||
return entry;
|
||||
|
||||
err_map_insert:
|
||||
kfree(map);
|
||||
err_ct_flow_insert:
|
||||
if (entry->tun_offset != NFP_FL_CT_NO_TUN)
|
||||
kfree(entry->rule->action.entries[entry->tun_offset].tunnel);
|
||||
err_pre_ct_tun_cp:
|
||||
kfree(entry->rule);
|
||||
err_pre_ct_act:
|
||||
|
@ -245,7 +268,7 @@ int nfp_fl_ct_handle_pre_ct(struct nfp_flower_priv *priv,
|
|||
zt->nft = ct_act->ct.flow_table;
|
||||
|
||||
/* Add entry to pre_ct_list */
|
||||
ct_entry = nfp_fl_ct_add_flow(zt, netdev, flow);
|
||||
ct_entry = nfp_fl_ct_add_flow(zt, netdev, flow, extack);
|
||||
if (IS_ERR(ct_entry))
|
||||
return PTR_ERR(ct_entry);
|
||||
ct_entry->type = CT_TYPE_PRE_CT;
|
||||
|
@ -286,7 +309,7 @@ int nfp_fl_ct_handle_post_ct(struct nfp_flower_priv *priv,
|
|||
}
|
||||
|
||||
/* Add entry to post_ct_list */
|
||||
ct_entry = nfp_fl_ct_add_flow(zt, netdev, flow);
|
||||
ct_entry = nfp_fl_ct_add_flow(zt, netdev, flow, extack);
|
||||
if (IS_ERR(ct_entry))
|
||||
return PTR_ERR(ct_entry);
|
||||
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
#define NFP_FL_CT_NO_TUN 0xff
|
||||
|
||||
extern const struct rhashtable_params nfp_zone_table_params;
|
||||
extern const struct rhashtable_params nfp_ct_map_params;
|
||||
|
||||
/**
|
||||
* struct nfp_fl_ct_zone_entry - Zone entry containing conntrack flow information
|
||||
|
@ -69,6 +70,18 @@ struct nfp_fl_ct_flow_entry {
|
|||
u8 tun_offset; // Set to NFP_FL_CT_NO_TUN if no tun
|
||||
};
|
||||
|
||||
/**
|
||||
* struct nfp_fl_ct_map_entry - Map between flow cookie and specific ct_flow
|
||||
* @cookie: Flow cookie, same as original TC flow, used as key
|
||||
* @hash_node: Used by the hashtable
|
||||
* @ct_entry: Pointer to corresponding ct_entry
|
||||
*/
|
||||
struct nfp_fl_ct_map_entry {
|
||||
unsigned long cookie;
|
||||
struct rhash_head hash_node;
|
||||
struct nfp_fl_ct_flow_entry *ct_entry;
|
||||
};
|
||||
|
||||
bool is_pre_ct_flow(struct flow_cls_offload *flow);
|
||||
bool is_post_ct_flow(struct flow_cls_offload *flow);
|
||||
|
||||
|
|
|
@ -195,6 +195,7 @@ struct nfp_fl_internal_ports {
|
|||
* @merge_table: Hash table to store merged flows
|
||||
* @ct_zone_table: Hash table used to store the different zones
|
||||
* @ct_zone_wc: Special zone entry for wildcarded zone matches
|
||||
* @ct_map_table: Hash table used to referennce ct flows
|
||||
*/
|
||||
struct nfp_flower_priv {
|
||||
struct nfp_app *app;
|
||||
|
@ -231,6 +232,7 @@ struct nfp_flower_priv {
|
|||
struct rhashtable merge_table;
|
||||
struct rhashtable ct_zone_table;
|
||||
struct nfp_fl_ct_zone_entry *ct_zone_wc;
|
||||
struct rhashtable ct_map_table;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -504,6 +504,13 @@ const struct rhashtable_params nfp_zone_table_params = {
|
|||
.automatic_shrinking = false,
|
||||
};
|
||||
|
||||
const struct rhashtable_params nfp_ct_map_params = {
|
||||
.head_offset = offsetof(struct nfp_fl_ct_map_entry, hash_node),
|
||||
.key_len = sizeof(unsigned long),
|
||||
.key_offset = offsetof(struct nfp_fl_ct_map_entry, cookie),
|
||||
.automatic_shrinking = true,
|
||||
};
|
||||
|
||||
int nfp_flower_metadata_init(struct nfp_app *app, u64 host_ctx_count,
|
||||
unsigned int host_num_mems)
|
||||
{
|
||||
|
@ -528,6 +535,10 @@ int nfp_flower_metadata_init(struct nfp_app *app, u64 host_ctx_count,
|
|||
if (err)
|
||||
goto err_free_merge_table;
|
||||
|
||||
err = rhashtable_init(&priv->ct_map_table, &nfp_ct_map_params);
|
||||
if (err)
|
||||
goto err_free_ct_zone_table;
|
||||
|
||||
get_random_bytes(&priv->mask_id_seed, sizeof(priv->mask_id_seed));
|
||||
|
||||
/* Init ring buffer and unallocated mask_ids. */
|
||||
|
@ -535,7 +546,7 @@ int nfp_flower_metadata_init(struct nfp_app *app, u64 host_ctx_count,
|
|||
kmalloc_array(NFP_FLOWER_MASK_ENTRY_RS,
|
||||
NFP_FLOWER_MASK_ELEMENT_RS, GFP_KERNEL);
|
||||
if (!priv->mask_ids.mask_id_free_list.buf)
|
||||
goto err_free_ct_zone_table;
|
||||
goto err_free_ct_map_table;
|
||||
|
||||
priv->mask_ids.init_unallocated = NFP_FLOWER_MASK_ENTRY_RS - 1;
|
||||
|
||||
|
@ -572,6 +583,8 @@ err_free_last_used:
|
|||
kfree(priv->mask_ids.last_used);
|
||||
err_free_mask_id:
|
||||
kfree(priv->mask_ids.mask_id_free_list.buf);
|
||||
err_free_ct_map_table:
|
||||
rhashtable_destroy(&priv->ct_map_table);
|
||||
err_free_ct_zone_table:
|
||||
rhashtable_destroy(&priv->ct_zone_table);
|
||||
err_free_merge_table:
|
||||
|
@ -589,22 +602,40 @@ static void nfp_zone_table_entry_destroy(struct nfp_fl_ct_zone_entry *zt)
|
|||
return;
|
||||
|
||||
if (!list_empty(&zt->pre_ct_list)) {
|
||||
struct rhashtable *m_table = &zt->priv->ct_map_table;
|
||||
struct nfp_fl_ct_flow_entry *entry, *tmp;
|
||||
struct nfp_fl_ct_map_entry *map;
|
||||
|
||||
WARN_ONCE(1, "pre_ct_list not empty as expected, cleaning up\n");
|
||||
list_for_each_entry_safe(entry, tmp, &zt->pre_ct_list,
|
||||
list_node) {
|
||||
map = rhashtable_lookup_fast(m_table,
|
||||
&entry->cookie,
|
||||
nfp_ct_map_params);
|
||||
WARN_ON_ONCE(rhashtable_remove_fast(m_table,
|
||||
&map->hash_node,
|
||||
nfp_ct_map_params));
|
||||
nfp_fl_ct_clean_flow_entry(entry);
|
||||
kfree(map);
|
||||
}
|
||||
}
|
||||
|
||||
if (!list_empty(&zt->post_ct_list)) {
|
||||
struct rhashtable *m_table = &zt->priv->ct_map_table;
|
||||
struct nfp_fl_ct_flow_entry *entry, *tmp;
|
||||
struct nfp_fl_ct_map_entry *map;
|
||||
|
||||
WARN_ONCE(1, "post_ct_list not empty as expected, cleaning up\n");
|
||||
list_for_each_entry_safe(entry, tmp, &zt->post_ct_list,
|
||||
list_node) {
|
||||
map = rhashtable_lookup_fast(m_table,
|
||||
&entry->cookie,
|
||||
nfp_ct_map_params);
|
||||
WARN_ON_ONCE(rhashtable_remove_fast(m_table,
|
||||
&map->hash_node,
|
||||
nfp_ct_map_params));
|
||||
nfp_fl_ct_clean_flow_entry(entry);
|
||||
kfree(map);
|
||||
}
|
||||
}
|
||||
kfree(zt);
|
||||
|
@ -617,6 +648,16 @@ static void nfp_free_zone_table_entry(void *ptr, void *arg)
|
|||
nfp_zone_table_entry_destroy(zt);
|
||||
}
|
||||
|
||||
static void nfp_free_map_table_entry(void *ptr, void *arg)
|
||||
{
|
||||
struct nfp_fl_ct_map_entry *map = ptr;
|
||||
|
||||
if (!map)
|
||||
return;
|
||||
|
||||
kfree(map);
|
||||
}
|
||||
|
||||
void nfp_flower_metadata_cleanup(struct nfp_app *app)
|
||||
{
|
||||
struct nfp_flower_priv *priv = app->priv;
|
||||
|
@ -633,6 +674,9 @@ void nfp_flower_metadata_cleanup(struct nfp_app *app)
|
|||
rhashtable_free_and_destroy(&priv->ct_zone_table,
|
||||
nfp_free_zone_table_entry, NULL);
|
||||
nfp_zone_table_entry_destroy(priv->ct_zone_wc);
|
||||
|
||||
rhashtable_free_and_destroy(&priv->ct_map_table,
|
||||
nfp_free_map_table_entry, NULL);
|
||||
kvfree(priv->stats);
|
||||
kfree(priv->mask_ids.mask_id_free_list.buf);
|
||||
kfree(priv->mask_ids.last_used);
|
||||
|
|
Loading…
Add table
Reference in a new issue