mlxsw: spectrum_flower: Offload goto_chain termination action
authorJiri Pirko <jiri@mellanox.com>
Wed, 23 Aug 2017 08:08:22 +0000 (10:08 +0200)
committerDavid S. Miller <davem@davemloft.net>
Thu, 24 Aug 2017 03:44:32 +0000 (20:44 -0700)
If action is gact goto_chain, offload it to HW by jumping to another
ruleset.

Signed-off-by: Jiri Pirko <jiri@mellanox.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/mellanox/mlxsw/spectrum_flower.c

index 34872aa520739eb3592e993d76178efee9c42cf1..8aace9a06a5d8e7e396bc5504619dacc556278f2 100644 (file)
@@ -45,7 +45,7 @@
 #include "core_acl_flex_keys.h"
 
 static int mlxsw_sp_flower_parse_actions(struct mlxsw_sp *mlxsw_sp,
-                                        struct net_device *dev,
+                                        struct net_device *dev, bool ingress,
                                         struct mlxsw_sp_acl_rule_info *rulei,
                                         struct tcf_exts *exts)
 {
@@ -71,6 +71,20 @@ static int mlxsw_sp_flower_parse_actions(struct mlxsw_sp *mlxsw_sp,
                        err = mlxsw_sp_acl_rulei_act_trap(rulei);
                        if (err)
                                return err;
+               } else if (is_tcf_gact_goto_chain(a)) {
+                       u32 chain_index = tcf_gact_goto_chain_index(a);
+                       struct mlxsw_sp_acl_ruleset *ruleset;
+                       u16 group_id;
+
+                       ruleset = mlxsw_sp_acl_ruleset_lookup(mlxsw_sp, dev,
+                                                             ingress,
+                                                             chain_index,
+                                                             MLXSW_SP_ACL_PROFILE_FLOWER);
+                       if (IS_ERR(ruleset))
+                               return PTR_ERR(ruleset);
+
+                       group_id = mlxsw_sp_acl_ruleset_group_id(ruleset);
+                       mlxsw_sp_acl_rulei_act_jump(rulei, group_id);
                } else if (is_tcf_mirred_egress_redirect(a)) {
                        int ifindex = tcf_mirred_ifindex(a);
                        struct net_device *out_dev;
@@ -246,7 +260,7 @@ static int mlxsw_sp_flower_parse_ip(struct mlxsw_sp *mlxsw_sp,
 }
 
 static int mlxsw_sp_flower_parse(struct mlxsw_sp *mlxsw_sp,
-                                struct net_device *dev,
+                                struct net_device *dev, bool ingress,
                                 struct mlxsw_sp_acl_rule_info *rulei,
                                 struct tc_cls_flower_offload *f)
 {
@@ -364,7 +378,8 @@ static int mlxsw_sp_flower_parse(struct mlxsw_sp *mlxsw_sp,
        if (err)
                return err;
 
-       return mlxsw_sp_flower_parse_actions(mlxsw_sp, dev, rulei, f->exts);
+       return mlxsw_sp_flower_parse_actions(mlxsw_sp, dev, ingress,
+                                            rulei, f->exts);
 }
 
 int mlxsw_sp_flower_replace(struct mlxsw_sp_port *mlxsw_sp_port, bool ingress,
@@ -390,7 +405,7 @@ int mlxsw_sp_flower_replace(struct mlxsw_sp_port *mlxsw_sp_port, bool ingress,
        }
 
        rulei = mlxsw_sp_acl_rule_rulei(rule);
-       err = mlxsw_sp_flower_parse(mlxsw_sp, dev, rulei, f);
+       err = mlxsw_sp_flower_parse(mlxsw_sp, dev, ingress, rulei, f);
        if (err)
                goto err_flower_parse;