From 43f84b72c50d40c3eb2f59070e40ef51bfd483cc Mon Sep 17 00:00:00 2001 From: Pieter Jansen van Vuuren Date: Thu, 29 Jun 2017 22:08:17 +0200 Subject: 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 Signed-off-by: Simon Horman Signed-off-by: David S. Miller --- .../net/ethernet/netronome/nfp/flower/offload.c | 31 +++++++++++++++++++--- 1 file changed, 28 insertions(+), 3 deletions(-) (limited to 'drivers/net/ethernet/netronome/nfp/flower/offload.c') 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; } /** -- cgit v1.2.3