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 edd397f..41a5de4 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 677526e..fe270c1 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 44bbe7c..695d333 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 8d21197..ff07235 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);