mlxsw: spectrum_acl: Support rule creation without action creation
authorNir Dotan <nird@mellanox.com>
Mon, 10 Dec 2018 07:11:43 +0000 (07:11 +0000)
committerDavid S. Miller <davem@davemloft.net>
Wed, 12 Dec 2018 07:01:33 +0000 (23:01 -0800)
Up until now, when ACL rule was created its action was created with it.
It suits well for tc flower where ACL rule always needs an action, however
it does not suit multicast router, where the action is created prior to
setting a route, which in Spectrum-2 is actually an ACL rule.

Add support for rule creation without action creation. Do it by adding
afa_block argument to mlxsw_sp_acl_rule_create, which if NULL then an
action would be created, also add an indication within struct
mlxsw_sp_acl_rule_info that tells if the action should be destroyed when
the rule is destroyed.

Signed-off-by: Nir Dotan <nird@mellanox.com>
Reviewed-by: Jiri Pirko <jiri@mellanox.com>
Signed-off-by: Ido Schimmel <idosch@mellanox.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/mellanox/mlxsw/spectrum.h
drivers/net/ethernet/mellanox/mlxsw/spectrum1_acl_tcam.c
drivers/net/ethernet/mellanox/mlxsw/spectrum_acl.c
drivers/net/ethernet/mellanox/mlxsw/spectrum_flower.c

index edd397f42228a20d0af363b2b3de5af06a551745..41a5de4a09651c77c6d950a90c59e64289b39a39 100644 (file)
@@ -563,6 +563,7 @@ struct mlxsw_sp_acl_rule_info {
        unsigned int priority;
        struct mlxsw_afk_element_values values;
        struct mlxsw_afa_block *act_block;
+       u8 action_created:1;
        unsigned int counter_index;
 };
 
@@ -607,7 +608,8 @@ void mlxsw_sp_acl_ruleset_put(struct mlxsw_sp *mlxsw_sp,
 u16 mlxsw_sp_acl_ruleset_group_id(struct mlxsw_sp_acl_ruleset *ruleset);
 
 struct mlxsw_sp_acl_rule_info *
-mlxsw_sp_acl_rulei_create(struct mlxsw_sp_acl *acl);
+mlxsw_sp_acl_rulei_create(struct mlxsw_sp_acl *acl,
+                         struct mlxsw_afa_block *afa_block);
 void mlxsw_sp_acl_rulei_destroy(struct mlxsw_sp_acl_rule_info *rulei);
 int mlxsw_sp_acl_rulei_commit(struct mlxsw_sp_acl_rule_info *rulei);
 void mlxsw_sp_acl_rulei_priority(struct mlxsw_sp_acl_rule_info *rulei,
@@ -651,6 +653,7 @@ struct mlxsw_sp_acl_rule *
 mlxsw_sp_acl_rule_create(struct mlxsw_sp *mlxsw_sp,
                         struct mlxsw_sp_acl_ruleset *ruleset,
                         unsigned long cookie,
+                        struct mlxsw_afa_block *afa_block,
                         struct netlink_ext_ack *extack);
 void mlxsw_sp_acl_rule_destroy(struct mlxsw_sp *mlxsw_sp,
                               struct mlxsw_sp_acl_rule *rule);
index 677526e5875032087438bc12fe54f75e9bd68a57..fe270c1a26a621b99a37463315f0dbf70e03f953 100644 (file)
@@ -67,7 +67,7 @@ mlxsw_sp1_acl_ctcam_region_catchall_add(struct mlxsw_sp *mlxsw_sp,
        mlxsw_sp_acl_ctcam_chunk_init(&region->cregion,
                                      &region->catchall.cchunk,
                                      MLXSW_SP_ACL_TCAM_CATCHALL_PRIO);
-       rulei = mlxsw_sp_acl_rulei_create(mlxsw_sp->acl);
+       rulei = mlxsw_sp_acl_rulei_create(mlxsw_sp->acl, NULL);
        if (IS_ERR(rulei)) {
                err = PTR_ERR(rulei);
                goto err_rulei_create;
index 44bbe7c9b68c032bc07de05ea3df8565559dd37e..695d33358988e8d1e899299dc79a84e4d3b2bfe9 100644 (file)
@@ -435,7 +435,8 @@ u16 mlxsw_sp_acl_ruleset_group_id(struct mlxsw_sp_acl_ruleset *ruleset)
 }
 
 struct mlxsw_sp_acl_rule_info *
-mlxsw_sp_acl_rulei_create(struct mlxsw_sp_acl *acl)
+mlxsw_sp_acl_rulei_create(struct mlxsw_sp_acl *acl,
+                         struct mlxsw_afa_block *afa_block)
 {
        struct mlxsw_sp_acl_rule_info *rulei;
        int err;
@@ -443,11 +444,18 @@ mlxsw_sp_acl_rulei_create(struct mlxsw_sp_acl *acl)
        rulei = kzalloc(sizeof(*rulei), GFP_KERNEL);
        if (!rulei)
                return NULL;
+
+       if (afa_block) {
+               rulei->act_block = afa_block;
+               return rulei;
+       }
+
        rulei->act_block = mlxsw_afa_block_create(acl->mlxsw_sp->afa);
        if (IS_ERR(rulei->act_block)) {
                err = PTR_ERR(rulei->act_block);
                goto err_afa_block_create;
        }
+       rulei->action_created = 1;
        return rulei;
 
 err_afa_block_create:
@@ -457,7 +465,8 @@ err_afa_block_create:
 
 void mlxsw_sp_acl_rulei_destroy(struct mlxsw_sp_acl_rule_info *rulei)
 {
-       mlxsw_afa_block_destroy(rulei->act_block);
+       if (rulei->action_created)
+               mlxsw_afa_block_destroy(rulei->act_block);
        kfree(rulei);
 }
 
@@ -623,6 +632,7 @@ struct mlxsw_sp_acl_rule *
 mlxsw_sp_acl_rule_create(struct mlxsw_sp *mlxsw_sp,
                         struct mlxsw_sp_acl_ruleset *ruleset,
                         unsigned long cookie,
+                        struct mlxsw_afa_block *afa_block,
                         struct netlink_ext_ack *extack)
 {
        const struct mlxsw_sp_acl_profile_ops *ops = ruleset->ht_key.ops;
@@ -639,7 +649,7 @@ mlxsw_sp_acl_rule_create(struct mlxsw_sp *mlxsw_sp,
        rule->cookie = cookie;
        rule->ruleset = ruleset;
 
-       rule->rulei = mlxsw_sp_acl_rulei_create(mlxsw_sp->acl);
+       rule->rulei = mlxsw_sp_acl_rulei_create(mlxsw_sp->acl, afa_block);
        if (IS_ERR(rule->rulei)) {
                err = PTR_ERR(rule->rulei);
                goto err_rulei_create;
index 8d211972c5e90fbe1a24dc32edf6f371ff018bd4..ff072358d95064fd4bd466e49d67e16554f7efe9 100644 (file)
@@ -406,7 +406,7 @@ int mlxsw_sp_flower_replace(struct mlxsw_sp *mlxsw_sp,
        if (IS_ERR(ruleset))
                return PTR_ERR(ruleset);
 
-       rule = mlxsw_sp_acl_rule_create(mlxsw_sp, ruleset, f->cookie,
+       rule = mlxsw_sp_acl_rule_create(mlxsw_sp, ruleset, f->cookie, NULL,
                                        f->common.extack);
        if (IS_ERR(rule)) {
                err = PTR_ERR(rule);