Commit 1d24b6b4 authored by David S. Miller's avatar David S. Miller

Merge branch 'nfp-ct-part-two'

Simon Horman says:

====================
Next set of conntrack patches for the nfp driver

Louis Peens says:

This follows on from the previous series of a similar nature.
Looking at the diagram as explained in the previous series
this implements changes up to the point where the merged
nft entries are saved. There are still bits of stubbed
out code where offloading of the flows will be implemented.

	+-------------+                      +----------+
	| pre_ct flow +--------+             | nft flow |
	+-------------+        v             +------+---+
	                  +----------+              |
	                  | tc_merge +--------+     |
	                  +----------+        v     v
	+--------------+       ^           +-------------+
	| post_ct flow +-------+       +---+nft_tc merge |
	+--------------+               |   +-------------+
	                               |
	                               |
	                               |
	                               v
	                        Offload to nfp
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 63e96bc4 30c4a9f4
......@@ -4,13 +4,35 @@
#ifndef __NFP_FLOWER_CONNTRACK_H__
#define __NFP_FLOWER_CONNTRACK_H__ 1
#include <net/netfilter/nf_flow_table.h>
#include "main.h"
#define NFP_FL_CT_NO_TUN 0xff
#define COMPARE_UNMASKED_FIELDS(__match1, __match2, __out) \
do { \
typeof(__match1) _match1 = (__match1); \
typeof(__match2) _match2 = (__match2); \
bool *_out = (__out); \
int i, size = sizeof(*(_match1).key); \
char *k1, *m1, *k2, *m2; \
*_out = false; \
k1 = (char *)_match1.key; \
m1 = (char *)_match1.mask; \
k2 = (char *)_match2.key; \
m2 = (char *)_match2.mask; \
for (i = 0; i < size; i++) \
if ((k1[i] & m1[i] & m2[i]) ^ \
(k2[i] & m1[i] & m2[i])) { \
*_out = true; \
break; \
} \
} while (0) \
extern const struct rhashtable_params nfp_zone_table_params;
extern const struct rhashtable_params nfp_ct_map_params;
extern const struct rhashtable_params nfp_tc_ct_merge_params;
extern const struct rhashtable_params nfp_nft_ct_merge_params;
/**
* struct nfp_fl_ct_zone_entry - Zone entry containing conntrack flow information
......@@ -27,6 +49,12 @@ extern const struct rhashtable_params nfp_tc_ct_merge_params;
*
* @tc_merge_tb: The table of merged tc flows
* @tc_merge_count: Keep count of the number of merged tc entries
*
* @nft_flows_list: The list of nft relatednfp_fl_ct_flow_entry entries
* @nft_flows_count: Keep count of the number of nft_flow entries
*
* @nft_merge_tb: The table of merged tc+nft flows
* @nft_merge_count: Keep count of the number of merged tc+nft entries
*/
struct nfp_fl_ct_zone_entry {
u16 zone;
......@@ -43,6 +71,12 @@ struct nfp_fl_ct_zone_entry {
struct rhashtable tc_merge_tb;
unsigned int tc_merge_count;
struct list_head nft_flows_list;
unsigned int nft_flows_count;
struct rhashtable nft_merge_tb;
unsigned int nft_merge_count;
};
enum ct_entry_type {
......@@ -99,6 +133,32 @@ struct nfp_fl_ct_tc_merge {
struct list_head children;
};
/**
* struct nfp_fl_nft_tc_merge - Merge of tc_merge flows with nft flow
* @netdev: Ingress netdev name
* @cookie: Flow cookie, combination of tc_merge and nft cookies
* @hash_node: Used by the hashtable
* @zt: Reference to the zone table this belongs to
* @nft_flow_list: This entry is part of a nft_flows_list
* @tc_merge_list: This entry is part of a ct_merge_list
* @tc_m_parent: The tc_merge parent
* @nft_parent: The nft_entry parent
* @tc_flower_cookie: The cookie of the flow offloaded to the nfp
* @flow_pay: Reference to the offloaded flow struct
*/
struct nfp_fl_nft_tc_merge {
struct net_device *netdev;
unsigned long cookie[3];
struct rhash_head hash_node;
struct nfp_fl_ct_zone_entry *zt;
struct list_head nft_flow_list;
struct list_head tc_merge_list;
struct nfp_fl_ct_tc_merge *tc_m_parent;
struct nfp_fl_ct_flow_entry *nft_parent;
unsigned long tc_flower_cookie;
struct nfp_fl_payload *flow_pay;
};
/**
* 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
......@@ -152,4 +212,20 @@ int nfp_fl_ct_handle_post_ct(struct nfp_flower_priv *priv,
* @entry: Flow entry to cleanup
*/
void nfp_fl_ct_clean_flow_entry(struct nfp_fl_ct_flow_entry *entry);
/**
* nfp_fl_ct_del_flow() - Handle flow_del callbacks for conntrack
* @ct_map_ent: ct map entry for the flow that needs deleting
*/
int nfp_fl_ct_del_flow(struct nfp_fl_ct_map_entry *ct_map_ent);
/**
* nfp_fl_ct_handle_nft_flow() - Handle flower flow callbacks for nft table
* @type: Type provided by callback
* @type_data: Callback data
* @cb_priv: Pointer to data provided when registering the callback, in this
* case it's the zone table.
*/
int nfp_fl_ct_handle_nft_flow(enum tc_setup_type type, void *type_data,
void *cb_priv);
#endif
......@@ -639,8 +639,36 @@ static void nfp_zone_table_entry_destroy(struct nfp_fl_ct_zone_entry *zt)
}
}
if (zt->nft) {
nf_flow_table_offload_del_cb(zt->nft,
nfp_fl_ct_handle_nft_flow,
zt);
zt->nft = NULL;
}
if (!list_empty(&zt->nft_flows_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, "nft_flows_list not empty as expected, cleaning up\n");
list_for_each_entry_safe(entry, tmp, &zt->nft_flows_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);
}
}
rhashtable_free_and_destroy(&zt->tc_merge_tb,
nfp_check_rhashtable_empty, NULL);
rhashtable_free_and_destroy(&zt->nft_merge_tb,
nfp_check_rhashtable_empty, NULL);
kfree(zt);
}
......
......@@ -1505,6 +1505,7 @@ nfp_flower_del_offload(struct nfp_app *app, struct net_device *netdev,
struct flow_cls_offload *flow)
{
struct nfp_flower_priv *priv = app->priv;
struct nfp_fl_ct_map_entry *ct_map_ent;
struct netlink_ext_ack *extack = NULL;
struct nfp_fl_payload *nfp_flow;
struct nfp_port *port = NULL;
......@@ -1514,6 +1515,14 @@ nfp_flower_del_offload(struct nfp_app *app, struct net_device *netdev,
if (nfp_netdev_is_nfp_repr(netdev))
port = nfp_port_from_netdev(netdev);
/* Check ct_map_table */
ct_map_ent = rhashtable_lookup_fast(&priv->ct_map_table, &flow->cookie,
nfp_ct_map_params);
if (ct_map_ent) {
err = nfp_fl_ct_del_flow(ct_map_ent);
return err;
}
nfp_flow = nfp_flower_search_fl_table(app, flow->cookie, netdev);
if (!nfp_flow) {
NL_SET_ERR_MSG_MOD(extack, "invalid entry: cannot remove flow that does not exist");
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment