dpaa2-switch: add tc matchall filter support
authorIoana Ciornei <ioana.ciornei@nxp.com>
Tue, 13 Apr 2021 13:24:47 +0000 (16:24 +0300)
committerDavid S. Miller <davem@davemloft.net>
Tue, 13 Apr 2021 22:12:18 +0000 (15:12 -0700)
Add support TC_SETUP_CLSMATCHALL by using the same ACL table entries
framework as for tc flower. Adding a matchall rule is done by installing
an entry which has a mask of all zeroes, thus matching on any packet.

This can be used as a catch-all type of rule if used correctly, ie the
priority of the matchall filter should be kept as the lowest one in the
entire filter block.

Signed-off-by: Ioana Ciornei <ioana.ciornei@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/freescale/dpaa2/dpaa2-switch-flower.c
drivers/net/ethernet/freescale/dpaa2/dpaa2-switch.c
drivers/net/ethernet/freescale/dpaa2/dpaa2-switch.h

index ee987fa..b4807dd 100644 (file)
@@ -434,3 +434,59 @@ int dpaa2_switch_cls_flower_destroy(struct dpaa2_switch_acl_tbl *acl_tbl,
 
        return dpaa2_switch_acl_tbl_remove_entry(acl_tbl, entry);
 }
+
+int dpaa2_switch_cls_matchall_replace(struct dpaa2_switch_acl_tbl *acl_tbl,
+                                     struct tc_cls_matchall_offload *cls)
+{
+       struct netlink_ext_ack *extack = cls->common.extack;
+       struct ethsw_core *ethsw = acl_tbl->ethsw;
+       struct dpaa2_switch_acl_entry *acl_entry;
+       struct flow_action_entry *act;
+       int err;
+
+       if (!flow_offload_has_one_action(&cls->rule->action)) {
+               NL_SET_ERR_MSG(extack, "Only singular actions are supported");
+               return -EOPNOTSUPP;
+       }
+
+       if (dpaa2_switch_acl_tbl_is_full(acl_tbl)) {
+               NL_SET_ERR_MSG(extack, "Maximum filter capacity reached");
+               return -ENOMEM;
+       }
+
+       acl_entry = kzalloc(sizeof(*acl_entry), GFP_KERNEL);
+       if (!acl_entry)
+               return -ENOMEM;
+
+       act = &cls->rule->action.entries[0];
+       err = dpaa2_switch_tc_parse_action(ethsw, act,
+                                          &acl_entry->cfg.result, extack);
+       if (err)
+               goto free_acl_entry;
+
+       acl_entry->prio = cls->common.prio;
+       acl_entry->cookie = cls->cookie;
+
+       err = dpaa2_switch_acl_tbl_add_entry(acl_tbl, acl_entry);
+       if (err)
+               goto free_acl_entry;
+
+       return 0;
+
+free_acl_entry:
+       kfree(acl_entry);
+
+       return err;
+}
+
+int dpaa2_switch_cls_matchall_destroy(struct dpaa2_switch_acl_tbl *acl_tbl,
+                                     struct tc_cls_matchall_offload *cls)
+{
+       struct dpaa2_switch_acl_entry *entry;
+
+       entry = dpaa2_switch_acl_tbl_find_entry_by_cookie(acl_tbl, cls->cookie);
+       if (!entry)
+               return 0;
+
+       return  dpaa2_switch_acl_tbl_remove_entry(acl_tbl, entry);
+}
index 5080788..adf9e58 100644 (file)
@@ -1140,6 +1140,20 @@ dpaa2_switch_setup_tc_cls_flower(struct dpaa2_switch_acl_tbl *acl_tbl,
        }
 }
 
+static int
+dpaa2_switch_setup_tc_cls_matchall(struct dpaa2_switch_acl_tbl *acl_tbl,
+                                  struct tc_cls_matchall_offload *f)
+{
+       switch (f->command) {
+       case TC_CLSMATCHALL_REPLACE:
+               return dpaa2_switch_cls_matchall_replace(acl_tbl, f);
+       case TC_CLSMATCHALL_DESTROY:
+               return dpaa2_switch_cls_matchall_destroy(acl_tbl, f);
+       default:
+               return -EOPNOTSUPP;
+       }
+}
+
 static int dpaa2_switch_port_setup_tc_block_cb_ig(enum tc_setup_type type,
                                                  void *type_data,
                                                  void *cb_priv)
@@ -1147,6 +1161,8 @@ static int dpaa2_switch_port_setup_tc_block_cb_ig(enum tc_setup_type type,
        switch (type) {
        case TC_SETUP_CLSFLOWER:
                return dpaa2_switch_setup_tc_cls_flower(cb_priv, type_data);
+       case TC_SETUP_CLSMATCHALL:
+               return dpaa2_switch_setup_tc_cls_matchall(cb_priv, type_data);
        default:
                return -EOPNOTSUPP;
        }
index 6291862..8575eed 100644 (file)
@@ -18,6 +18,7 @@
 #include <net/switchdev.h>
 #include <linux/if_bridge.h>
 #include <linux/fsl/mc.h>
+#include <net/pkt_cls.h>
 #include <soc/fsl/dpaa2-io.h>
 
 #include "dpsw.h"
@@ -233,4 +234,10 @@ int dpaa2_switch_cls_flower_replace(struct dpaa2_switch_acl_tbl *acl_tbl,
 
 int dpaa2_switch_cls_flower_destroy(struct dpaa2_switch_acl_tbl *acl_tbl,
                                    struct flow_cls_offload *cls);
+
+int dpaa2_switch_cls_matchall_replace(struct dpaa2_switch_acl_tbl *acl_tbl,
+                                     struct tc_cls_matchall_offload *cls);
+
+int dpaa2_switch_cls_matchall_destroy(struct dpaa2_switch_acl_tbl *acl_tbl,
+                                     struct tc_cls_matchall_offload *cls);
 #endif /* __ETHSW_H */