aboutsummaryrefslogtreecommitdiff
path: root/drivers/net/ethernet/netronome/nfp/flower/offload.c
diff options
context:
space:
mode:
authorPieter Jansen van Vuuren <pieter.jansenvanvuuren@netronome.com>2017-06-29 22:08:17 +0200
committerDavid S. Miller <davem@davemloft.net>2017-07-01 08:51:32 -0700
commit43f84b72c50d40c3eb2f59070e40ef51bfd483cc (patch)
treeabcc230d86867c1739904a08df399a04e950e09c /drivers/net/ethernet/netronome/nfp/flower/offload.c
parent1a1e586f54bfe54a0ba7ea0ac9b8c7b1d3e655f6 (diff)
nfp: add metadata to each flow offload
Adds metadata describing the mask id of each flow and keeps track of flows installed in hardware. Previously a flow could not be removed from hardware as there was no way of knowing if that a specific flow was installed. This is solved by storing the offloaded flows in a hash table. Signed-off-by: Pieter Jansen van Vuuren <pieter.jansenvanvuuren@netronome.com> Signed-off-by: Simon Horman <simon.horman@netronome.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ethernet/netronome/nfp/flower/offload.c')
-rw-r--r--drivers/net/ethernet/netronome/nfp/flower/offload.c31
1 files changed, 28 insertions, 3 deletions
diff --git a/drivers/net/ethernet/netronome/nfp/flower/offload.c b/drivers/net/ethernet/netronome/nfp/flower/offload.c
index de687a9e4759..04603d832adf 100644
--- a/drivers/net/ethernet/netronome/nfp/flower/offload.c
+++ b/drivers/net/ethernet/netronome/nfp/flower/offload.c
@@ -196,6 +196,7 @@ static int
nfp_flower_add_offload(struct nfp_app *app, struct net_device *netdev,
struct tc_cls_flower_offload *flow)
{
+ struct nfp_flower_priv *priv = app->priv;
struct nfp_fl_payload *flow_pay;
struct nfp_fl_key_ls *key_layer;
int err;
@@ -222,8 +223,18 @@ nfp_flower_add_offload(struct nfp_app *app, struct net_device *netdev,
if (err)
goto err_destroy_flow;
- /* TODO: Complete flower_add_offload. */
- err = -EOPNOTSUPP;
+ err = nfp_compile_flow_metadata(app, flow, flow_pay);
+ if (err)
+ goto err_destroy_flow;
+
+ INIT_HLIST_NODE(&flow_pay->link);
+ flow_pay->tc_flower_cookie = flow->cookie;
+ hash_add_rcu(priv->flow_table, &flow_pay->link, flow->cookie);
+
+ /* Deallocate flow payload when flower rule has been destroyed. */
+ kfree(key_layer);
+
+ return 0;
err_destroy_flow:
kfree(flow_pay->action_data);
@@ -250,7 +261,21 @@ static int
nfp_flower_del_offload(struct nfp_app *app, struct net_device *netdev,
struct tc_cls_flower_offload *flow)
{
- return -EOPNOTSUPP;
+ struct nfp_fl_payload *nfp_flow;
+ int err;
+
+ nfp_flow = nfp_flower_search_fl_table(app, flow->cookie);
+ if (!nfp_flow)
+ return -ENOENT;
+
+ err = nfp_modify_flow_metadata(app, nfp_flow);
+
+ hash_del_rcu(&nfp_flow->link);
+ kfree(nfp_flow->action_data);
+ kfree(nfp_flow->mask_data);
+ kfree(nfp_flow->unmasked_data);
+ kfree_rcu(nfp_flow, rcu);
+ return err;
}
/**