nfp: flower-ct: add delete flow handling for ct
authorLouis Peens <louis.peens@corigine.com>
Wed, 16 Jun 2021 10:01:59 +0000 (12:01 +0200)
committerDavid S. Miller <davem@davemloft.net>
Wed, 16 Jun 2021 19:42:52 +0000 (12:42 -0700)
Add functions to handle delete flow callbacks for ct flows. Also
accept the flows for offloading by returning 0 instead of -EOPNOTSUPP.
Flows will still not actually be offloaded to hw, but at this point
it's difficult to not accept the flows and also exercise the cleanup
paths properly. Traffic will still be handled safely through the
fallback path.

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>
drivers/net/ethernet/netronome/nfp/flower/conntrack.c
drivers/net/ethernet/netronome/nfp/flower/conntrack.h
drivers/net/ethernet/netronome/nfp/flower/offload.c

index b1709affb52deb8fb576e9a374a1a013600c2829..ea70e02d170e4536b6abc065a9182bea7ae665b1 100644 (file)
@@ -424,8 +424,7 @@ int nfp_fl_ct_handle_pre_ct(struct nfp_flower_priv *priv,
        if (priv->ct_zone_wc)
                nfp_ct_merge_tc_entries(ct_entry, priv->ct_zone_wc, zt);
 
-       NL_SET_ERR_MSG_MOD(extack, "unsupported offload: Conntrack action not supported");
-       return -EOPNOTSUPP;
+       return 0;
 }
 
 int nfp_fl_ct_handle_post_ct(struct nfp_flower_priv *priv,
@@ -487,6 +486,37 @@ int nfp_fl_ct_handle_post_ct(struct nfp_flower_priv *priv,
                nfp_ct_merge_tc_entries(ct_entry, zt, zt);
        }
 
-       NL_SET_ERR_MSG_MOD(extack, "unsupported offload: Conntrack match not supported");
-       return -EOPNOTSUPP;
+       return 0;
+}
+
+int nfp_fl_ct_del_flow(struct nfp_fl_ct_map_entry *ct_map_ent)
+{
+       struct nfp_fl_ct_flow_entry *ct_entry;
+       struct nfp_fl_ct_zone_entry *zt;
+       struct rhashtable *m_table;
+
+       zt = ct_map_ent->ct_entry->zt;
+       ct_entry = ct_map_ent->ct_entry;
+       m_table = &zt->priv->ct_map_table;
+
+       switch (ct_entry->type) {
+       case CT_TYPE_PRE_CT:
+               zt->pre_ct_count--;
+               rhashtable_remove_fast(m_table, &ct_map_ent->hash_node,
+                                      nfp_ct_map_params);
+               nfp_fl_ct_clean_flow_entry(ct_entry);
+               kfree(ct_map_ent);
+               break;
+       case CT_TYPE_POST_CT:
+               zt->post_ct_count--;
+               rhashtable_remove_fast(m_table, &ct_map_ent->hash_node,
+                                      nfp_ct_map_params);
+               nfp_fl_ct_clean_flow_entry(ct_entry);
+               kfree(ct_map_ent);
+               break;
+       default:
+               break;
+       }
+
+       return 0;
 }
index 3d7d260c6e5c31f5f74c7b9093fa83682e3150d0..dbb18fbbae69e1cd37b382370995658894a3c664 100644 (file)
@@ -152,4 +152,10 @@ 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);
 #endif
index 7e4ad5d58859b9cc4d4c088e0a0a0d797d00a02c..2406d33356ad239cbc72acb276517d7d06e34c40 100644 (file)
@@ -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");