Commit 3aaff323 authored by Jiri Pirko's avatar Jiri Pirko Committed by David S. Miller

mlxsw: spectrum_acl: Implement TC block sharing

Benefit from the prepared TC and in-driver ACL infrastructure and
introduce block sharing offload. For that, a new struct "block" is
introduced in spectrum_acl in order to hold a list of specific
block-port bindings.
Signed-off-by: default avatarJiri Pirko <jiri@mellanox.com>
Acked-by: default avatarDavid Ahern <dsahern@gmail.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 02caf499
...@@ -1747,72 +1747,186 @@ static int mlxsw_sp_setup_tc_cls_matchall(struct mlxsw_sp_port *mlxsw_sp_port, ...@@ -1747,72 +1747,186 @@ static int mlxsw_sp_setup_tc_cls_matchall(struct mlxsw_sp_port *mlxsw_sp_port,
} }
static int static int
mlxsw_sp_setup_tc_cls_flower(struct mlxsw_sp_port *mlxsw_sp_port, mlxsw_sp_setup_tc_cls_flower(struct mlxsw_sp_acl_block *acl_block,
struct tc_cls_flower_offload *f, struct tc_cls_flower_offload *f)
bool ingress)
{ {
struct mlxsw_sp *mlxsw_sp = mlxsw_sp_acl_block_mlxsw_sp(acl_block);
switch (f->command) { switch (f->command) {
case TC_CLSFLOWER_REPLACE: case TC_CLSFLOWER_REPLACE:
return mlxsw_sp_flower_replace(mlxsw_sp_port, ingress, f); return mlxsw_sp_flower_replace(mlxsw_sp, acl_block, f);
case TC_CLSFLOWER_DESTROY: case TC_CLSFLOWER_DESTROY:
mlxsw_sp_flower_destroy(mlxsw_sp_port, ingress, f); mlxsw_sp_flower_destroy(mlxsw_sp, acl_block, f);
return 0; return 0;
case TC_CLSFLOWER_STATS: case TC_CLSFLOWER_STATS:
return mlxsw_sp_flower_stats(mlxsw_sp_port, ingress, f); return mlxsw_sp_flower_stats(mlxsw_sp, acl_block, f);
default: default:
return -EOPNOTSUPP; return -EOPNOTSUPP;
} }
} }
static int mlxsw_sp_setup_tc_block_cb(enum tc_setup_type type, void *type_data, static int mlxsw_sp_setup_tc_block_cb_matchall(enum tc_setup_type type,
void *cb_priv, bool ingress) void *type_data,
void *cb_priv, bool ingress)
{ {
struct mlxsw_sp_port *mlxsw_sp_port = cb_priv; struct mlxsw_sp_port *mlxsw_sp_port = cb_priv;
if (!tc_can_offload(mlxsw_sp_port->dev))
return -EOPNOTSUPP;
switch (type) { switch (type) {
case TC_SETUP_CLSMATCHALL: case TC_SETUP_CLSMATCHALL:
if (!tc_can_offload(mlxsw_sp_port->dev))
return -EOPNOTSUPP;
return mlxsw_sp_setup_tc_cls_matchall(mlxsw_sp_port, type_data, return mlxsw_sp_setup_tc_cls_matchall(mlxsw_sp_port, type_data,
ingress); ingress);
case TC_SETUP_CLSFLOWER: case TC_SETUP_CLSFLOWER:
return mlxsw_sp_setup_tc_cls_flower(mlxsw_sp_port, type_data, return 0;
ingress);
default: default:
return -EOPNOTSUPP; return -EOPNOTSUPP;
} }
} }
static int mlxsw_sp_setup_tc_block_cb_ig(enum tc_setup_type type, static int mlxsw_sp_setup_tc_block_cb_matchall_ig(enum tc_setup_type type,
void *type_data, void *cb_priv) void *type_data,
void *cb_priv)
{ {
return mlxsw_sp_setup_tc_block_cb(type, type_data, cb_priv, true); return mlxsw_sp_setup_tc_block_cb_matchall(type, type_data,
cb_priv, true);
} }
static int mlxsw_sp_setup_tc_block_cb_eg(enum tc_setup_type type, static int mlxsw_sp_setup_tc_block_cb_matchall_eg(enum tc_setup_type type,
void *type_data, void *cb_priv) void *type_data,
void *cb_priv)
{ {
return mlxsw_sp_setup_tc_block_cb(type, type_data, cb_priv, false); return mlxsw_sp_setup_tc_block_cb_matchall(type, type_data,
cb_priv, false);
}
static int mlxsw_sp_setup_tc_block_cb_flower(enum tc_setup_type type,
void *type_data, void *cb_priv)
{
struct mlxsw_sp_acl_block *acl_block = cb_priv;
switch (type) {
case TC_SETUP_CLSMATCHALL:
return 0;
case TC_SETUP_CLSFLOWER:
if (mlxsw_sp_acl_block_disabled(acl_block))
return -EOPNOTSUPP;
return mlxsw_sp_setup_tc_cls_flower(acl_block, type_data);
default:
return -EOPNOTSUPP;
}
}
static int
mlxsw_sp_setup_tc_block_flower_bind(struct mlxsw_sp_port *mlxsw_sp_port,
struct tcf_block *block, bool ingress)
{
struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
struct mlxsw_sp_acl_block *acl_block;
struct tcf_block_cb *block_cb;
int err;
block_cb = tcf_block_cb_lookup(block, mlxsw_sp_setup_tc_block_cb_flower,
mlxsw_sp);
if (!block_cb) {
acl_block = mlxsw_sp_acl_block_create(mlxsw_sp, block->net);
if (!acl_block)
return -ENOMEM;
block_cb = __tcf_block_cb_register(block,
mlxsw_sp_setup_tc_block_cb_flower,
mlxsw_sp, acl_block);
if (IS_ERR(block_cb)) {
err = PTR_ERR(block_cb);
goto err_cb_register;
}
} else {
acl_block = tcf_block_cb_priv(block_cb);
}
tcf_block_cb_incref(block_cb);
err = mlxsw_sp_acl_block_bind(mlxsw_sp, acl_block,
mlxsw_sp_port, ingress);
if (err)
goto err_block_bind;
if (ingress)
mlxsw_sp_port->ing_acl_block = acl_block;
else
mlxsw_sp_port->eg_acl_block = acl_block;
return 0;
err_block_bind:
if (!tcf_block_cb_decref(block_cb)) {
__tcf_block_cb_unregister(block_cb);
err_cb_register:
mlxsw_sp_acl_block_destroy(acl_block);
}
return err;
}
static void
mlxsw_sp_setup_tc_block_flower_unbind(struct mlxsw_sp_port *mlxsw_sp_port,
struct tcf_block *block, bool ingress)
{
struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
struct mlxsw_sp_acl_block *acl_block;
struct tcf_block_cb *block_cb;
int err;
block_cb = tcf_block_cb_lookup(block, mlxsw_sp_setup_tc_block_cb_flower,
mlxsw_sp);
if (!block_cb)
return;
if (ingress)
mlxsw_sp_port->ing_acl_block = NULL;
else
mlxsw_sp_port->eg_acl_block = NULL;
acl_block = tcf_block_cb_priv(block_cb);
err = mlxsw_sp_acl_block_unbind(mlxsw_sp, acl_block,
mlxsw_sp_port, ingress);
if (!err && !tcf_block_cb_decref(block_cb)) {
__tcf_block_cb_unregister(block_cb);
mlxsw_sp_acl_block_destroy(acl_block);
}
} }
static int mlxsw_sp_setup_tc_block(struct mlxsw_sp_port *mlxsw_sp_port, static int mlxsw_sp_setup_tc_block(struct mlxsw_sp_port *mlxsw_sp_port,
struct tc_block_offload *f) struct tc_block_offload *f)
{ {
tc_setup_cb_t *cb; tc_setup_cb_t *cb;
bool ingress;
int err;
if (f->binder_type == TCF_BLOCK_BINDER_TYPE_CLSACT_INGRESS) if (f->binder_type == TCF_BLOCK_BINDER_TYPE_CLSACT_INGRESS) {
cb = mlxsw_sp_setup_tc_block_cb_ig; cb = mlxsw_sp_setup_tc_block_cb_matchall_ig;
else if (f->binder_type == TCF_BLOCK_BINDER_TYPE_CLSACT_EGRESS) ingress = true;
cb = mlxsw_sp_setup_tc_block_cb_eg; } else if (f->binder_type == TCF_BLOCK_BINDER_TYPE_CLSACT_EGRESS) {
else cb = mlxsw_sp_setup_tc_block_cb_matchall_eg;
ingress = false;
} else {
return -EOPNOTSUPP; return -EOPNOTSUPP;
}
switch (f->command) { switch (f->command) {
case TC_BLOCK_BIND: case TC_BLOCK_BIND:
return tcf_block_cb_register(f->block, cb, mlxsw_sp_port, err = tcf_block_cb_register(f->block, cb, mlxsw_sp_port,
mlxsw_sp_port); mlxsw_sp_port);
if (err)
return err;
err = mlxsw_sp_setup_tc_block_flower_bind(mlxsw_sp_port,
f->block, ingress);
if (err) {
tcf_block_cb_unregister(f->block, cb, mlxsw_sp_port);
return err;
}
return 0;
case TC_BLOCK_UNBIND: case TC_BLOCK_UNBIND:
mlxsw_sp_setup_tc_block_flower_unbind(mlxsw_sp_port,
f->block, ingress);
tcf_block_cb_unregister(f->block, cb, mlxsw_sp_port); tcf_block_cb_unregister(f->block, cb, mlxsw_sp_port);
return 0; return 0;
default: default:
...@@ -1842,10 +1956,18 @@ static int mlxsw_sp_feature_hw_tc(struct net_device *dev, bool enable) ...@@ -1842,10 +1956,18 @@ static int mlxsw_sp_feature_hw_tc(struct net_device *dev, bool enable)
{ {
struct mlxsw_sp_port *mlxsw_sp_port = netdev_priv(dev); struct mlxsw_sp_port *mlxsw_sp_port = netdev_priv(dev);
if (!enable && (mlxsw_sp_port->acl_rule_count || if (!enable) {
!list_empty(&mlxsw_sp_port->mall_tc_list))) { if (mlxsw_sp_acl_block_rule_count(mlxsw_sp_port->ing_acl_block) ||
netdev_err(dev, "Active offloaded tc filters, can't turn hw_tc_offload off\n"); mlxsw_sp_acl_block_rule_count(mlxsw_sp_port->eg_acl_block) ||
return -EINVAL; !list_empty(&mlxsw_sp_port->mall_tc_list)) {
netdev_err(dev, "Active offloaded tc filters, can't turn hw_tc_offload off\n");
return -EINVAL;
}
mlxsw_sp_acl_block_disable_inc(mlxsw_sp_port->ing_acl_block);
mlxsw_sp_acl_block_disable_inc(mlxsw_sp_port->eg_acl_block);
} else {
mlxsw_sp_acl_block_disable_dec(mlxsw_sp_port->ing_acl_block);
mlxsw_sp_acl_block_disable_dec(mlxsw_sp_port->eg_acl_block);
} }
return 0; return 0;
} }
......
...@@ -260,6 +260,8 @@ struct mlxsw_sp_port { ...@@ -260,6 +260,8 @@ struct mlxsw_sp_port {
struct list_head vlans_list; struct list_head vlans_list;
struct mlxsw_sp_qdisc *root_qdisc; struct mlxsw_sp_qdisc *root_qdisc;
unsigned acl_rule_count; unsigned acl_rule_count;
struct mlxsw_sp_acl_block *ing_acl_block;
struct mlxsw_sp_acl_block *eg_acl_block;
}; };
static inline bool static inline bool
...@@ -490,17 +492,34 @@ struct mlxsw_sp_acl_ops { ...@@ -490,17 +492,34 @@ struct mlxsw_sp_acl_ops {
enum mlxsw_sp_acl_profile profile); enum mlxsw_sp_acl_profile profile);
}; };
struct mlxsw_sp_acl_block;
struct mlxsw_sp_acl_ruleset; struct mlxsw_sp_acl_ruleset;
/* spectrum_acl.c */ /* spectrum_acl.c */
struct mlxsw_afk *mlxsw_sp_acl_afk(struct mlxsw_sp_acl *acl); struct mlxsw_afk *mlxsw_sp_acl_afk(struct mlxsw_sp_acl *acl);
struct mlxsw_sp *mlxsw_sp_acl_block_mlxsw_sp(struct mlxsw_sp_acl_block *block);
unsigned int mlxsw_sp_acl_block_rule_count(struct mlxsw_sp_acl_block *block);
void mlxsw_sp_acl_block_disable_inc(struct mlxsw_sp_acl_block *block);
void mlxsw_sp_acl_block_disable_dec(struct mlxsw_sp_acl_block *block);
bool mlxsw_sp_acl_block_disabled(struct mlxsw_sp_acl_block *block);
struct mlxsw_sp_acl_block *mlxsw_sp_acl_block_create(struct mlxsw_sp *mlxsw_sp,
struct net *net);
void mlxsw_sp_acl_block_destroy(struct mlxsw_sp_acl_block *block);
int mlxsw_sp_acl_block_bind(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_acl_block *block,
struct mlxsw_sp_port *mlxsw_sp_port,
bool ingress);
int mlxsw_sp_acl_block_unbind(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_acl_block *block,
struct mlxsw_sp_port *mlxsw_sp_port,
bool ingress);
struct mlxsw_sp_acl_ruleset * struct mlxsw_sp_acl_ruleset *
mlxsw_sp_acl_ruleset_lookup(struct mlxsw_sp *mlxsw_sp, struct net_device *dev, mlxsw_sp_acl_ruleset_lookup(struct mlxsw_sp *mlxsw_sp,
bool ingress, u32 chain_index, struct mlxsw_sp_acl_block *block, u32 chain_index,
enum mlxsw_sp_acl_profile profile); enum mlxsw_sp_acl_profile profile);
struct mlxsw_sp_acl_ruleset * struct mlxsw_sp_acl_ruleset *
mlxsw_sp_acl_ruleset_get(struct mlxsw_sp *mlxsw_sp, struct net_device *dev, mlxsw_sp_acl_ruleset_get(struct mlxsw_sp *mlxsw_sp,
bool ingress, u32 chain_index, struct mlxsw_sp_acl_block *block, u32 chain_index,
enum mlxsw_sp_acl_profile profile); enum mlxsw_sp_acl_profile profile);
void mlxsw_sp_acl_ruleset_put(struct mlxsw_sp *mlxsw_sp, void mlxsw_sp_acl_ruleset_put(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_acl_ruleset *ruleset); struct mlxsw_sp_acl_ruleset *ruleset);
...@@ -567,11 +586,14 @@ void mlxsw_sp_acl_fini(struct mlxsw_sp *mlxsw_sp); ...@@ -567,11 +586,14 @@ void mlxsw_sp_acl_fini(struct mlxsw_sp *mlxsw_sp);
extern const struct mlxsw_sp_acl_ops mlxsw_sp_acl_tcam_ops; extern const struct mlxsw_sp_acl_ops mlxsw_sp_acl_tcam_ops;
/* spectrum_flower.c */ /* spectrum_flower.c */
int mlxsw_sp_flower_replace(struct mlxsw_sp_port *mlxsw_sp_port, bool ingress, int mlxsw_sp_flower_replace(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_acl_block *block,
struct tc_cls_flower_offload *f); struct tc_cls_flower_offload *f);
void mlxsw_sp_flower_destroy(struct mlxsw_sp_port *mlxsw_sp_port, bool ingress, void mlxsw_sp_flower_destroy(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_acl_block *block,
struct tc_cls_flower_offload *f); struct tc_cls_flower_offload *f);
int mlxsw_sp_flower_stats(struct mlxsw_sp_port *mlxsw_sp_port, bool ingress, int mlxsw_sp_flower_stats(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_acl_block *block,
struct tc_cls_flower_offload *f); struct tc_cls_flower_offload *f);
/* spectrum_qdisc.c */ /* spectrum_qdisc.c */
......
...@@ -35,6 +35,7 @@ ...@@ -35,6 +35,7 @@
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/errno.h> #include <linux/errno.h>
#include <linux/netdevice.h> #include <linux/netdevice.h>
#include <net/net_namespace.h>
#include <net/flow_dissector.h> #include <net/flow_dissector.h>
#include <net/pkt_cls.h> #include <net/pkt_cls.h>
#include <net/tc_act/tc_gact.h> #include <net/tc_act/tc_gact.h>
...@@ -45,7 +46,7 @@ ...@@ -45,7 +46,7 @@
#include "core_acl_flex_keys.h" #include "core_acl_flex_keys.h"
static int mlxsw_sp_flower_parse_actions(struct mlxsw_sp *mlxsw_sp, static int mlxsw_sp_flower_parse_actions(struct mlxsw_sp *mlxsw_sp,
struct net_device *dev, bool ingress, struct mlxsw_sp_acl_block *block,
struct mlxsw_sp_acl_rule_info *rulei, struct mlxsw_sp_acl_rule_info *rulei,
struct tcf_exts *exts) struct tcf_exts *exts)
{ {
...@@ -80,8 +81,7 @@ static int mlxsw_sp_flower_parse_actions(struct mlxsw_sp *mlxsw_sp, ...@@ -80,8 +81,7 @@ static int mlxsw_sp_flower_parse_actions(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_acl_ruleset *ruleset; struct mlxsw_sp_acl_ruleset *ruleset;
u16 group_id; u16 group_id;
ruleset = mlxsw_sp_acl_ruleset_lookup(mlxsw_sp, dev, ruleset = mlxsw_sp_acl_ruleset_lookup(mlxsw_sp, block,
ingress,
chain_index, chain_index,
MLXSW_SP_ACL_PROFILE_FLOWER); MLXSW_SP_ACL_PROFILE_FLOWER);
if (IS_ERR(ruleset)) if (IS_ERR(ruleset))
...@@ -104,9 +104,6 @@ static int mlxsw_sp_flower_parse_actions(struct mlxsw_sp *mlxsw_sp, ...@@ -104,9 +104,6 @@ static int mlxsw_sp_flower_parse_actions(struct mlxsw_sp *mlxsw_sp,
return err; return err;
out_dev = tcf_mirred_dev(a); out_dev = tcf_mirred_dev(a);
if (out_dev == dev)
out_dev = NULL;
err = mlxsw_sp_acl_rulei_act_fwd(mlxsw_sp, rulei, err = mlxsw_sp_acl_rulei_act_fwd(mlxsw_sp, rulei,
out_dev); out_dev);
if (err) if (err)
...@@ -265,7 +262,7 @@ static int mlxsw_sp_flower_parse_ip(struct mlxsw_sp *mlxsw_sp, ...@@ -265,7 +262,7 @@ static int mlxsw_sp_flower_parse_ip(struct mlxsw_sp *mlxsw_sp,
} }
static int mlxsw_sp_flower_parse(struct mlxsw_sp *mlxsw_sp, static int mlxsw_sp_flower_parse(struct mlxsw_sp *mlxsw_sp,
struct net_device *dev, bool ingress, struct mlxsw_sp_acl_block *block,
struct mlxsw_sp_acl_rule_info *rulei, struct mlxsw_sp_acl_rule_info *rulei,
struct tc_cls_flower_offload *f) struct tc_cls_flower_offload *f)
{ {
...@@ -383,21 +380,19 @@ static int mlxsw_sp_flower_parse(struct mlxsw_sp *mlxsw_sp, ...@@ -383,21 +380,19 @@ static int mlxsw_sp_flower_parse(struct mlxsw_sp *mlxsw_sp,
if (err) if (err)
return err; return err;
return mlxsw_sp_flower_parse_actions(mlxsw_sp, dev, ingress, return mlxsw_sp_flower_parse_actions(mlxsw_sp, block, rulei, f->exts);
rulei, f->exts);
} }
int mlxsw_sp_flower_replace(struct mlxsw_sp_port *mlxsw_sp_port, bool ingress, int mlxsw_sp_flower_replace(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_acl_block *block,
struct tc_cls_flower_offload *f) struct tc_cls_flower_offload *f)
{ {
struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
struct net_device *dev = mlxsw_sp_port->dev;
struct mlxsw_sp_acl_rule_info *rulei; struct mlxsw_sp_acl_rule_info *rulei;
struct mlxsw_sp_acl_ruleset *ruleset; struct mlxsw_sp_acl_ruleset *ruleset;
struct mlxsw_sp_acl_rule *rule; struct mlxsw_sp_acl_rule *rule;
int err; int err;
ruleset = mlxsw_sp_acl_ruleset_get(mlxsw_sp, dev, ingress, ruleset = mlxsw_sp_acl_ruleset_get(mlxsw_sp, block,
f->common.chain_index, f->common.chain_index,
MLXSW_SP_ACL_PROFILE_FLOWER); MLXSW_SP_ACL_PROFILE_FLOWER);
if (IS_ERR(ruleset)) if (IS_ERR(ruleset))
...@@ -410,7 +405,7 @@ int mlxsw_sp_flower_replace(struct mlxsw_sp_port *mlxsw_sp_port, bool ingress, ...@@ -410,7 +405,7 @@ int mlxsw_sp_flower_replace(struct mlxsw_sp_port *mlxsw_sp_port, bool ingress,
} }
rulei = mlxsw_sp_acl_rule_rulei(rule); rulei = mlxsw_sp_acl_rule_rulei(rule);
err = mlxsw_sp_flower_parse(mlxsw_sp, dev, ingress, rulei, f); err = mlxsw_sp_flower_parse(mlxsw_sp, block, rulei, f);
if (err) if (err)
goto err_flower_parse; goto err_flower_parse;
...@@ -423,7 +418,6 @@ int mlxsw_sp_flower_replace(struct mlxsw_sp_port *mlxsw_sp_port, bool ingress, ...@@ -423,7 +418,6 @@ int mlxsw_sp_flower_replace(struct mlxsw_sp_port *mlxsw_sp_port, bool ingress,
goto err_rule_add; goto err_rule_add;
mlxsw_sp_acl_ruleset_put(mlxsw_sp, ruleset); mlxsw_sp_acl_ruleset_put(mlxsw_sp, ruleset);
mlxsw_sp_port->acl_rule_count++;
return 0; return 0;
err_rule_add: err_rule_add:
...@@ -435,15 +429,15 @@ int mlxsw_sp_flower_replace(struct mlxsw_sp_port *mlxsw_sp_port, bool ingress, ...@@ -435,15 +429,15 @@ int mlxsw_sp_flower_replace(struct mlxsw_sp_port *mlxsw_sp_port, bool ingress,
return err; return err;
} }
void mlxsw_sp_flower_destroy(struct mlxsw_sp_port *mlxsw_sp_port, bool ingress, void mlxsw_sp_flower_destroy(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_acl_block *block,
struct tc_cls_flower_offload *f) struct tc_cls_flower_offload *f)
{ {
struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
struct mlxsw_sp_acl_ruleset *ruleset; struct mlxsw_sp_acl_ruleset *ruleset;
struct mlxsw_sp_acl_rule *rule; struct mlxsw_sp_acl_rule *rule;
ruleset = mlxsw_sp_acl_ruleset_get(mlxsw_sp, mlxsw_sp_port->dev, ruleset = mlxsw_sp_acl_ruleset_get(mlxsw_sp, block,
ingress, f->common.chain_index, f->common.chain_index,
MLXSW_SP_ACL_PROFILE_FLOWER); MLXSW_SP_ACL_PROFILE_FLOWER);
if (IS_ERR(ruleset)) if (IS_ERR(ruleset))
return; return;
...@@ -455,13 +449,12 @@ void mlxsw_sp_flower_destroy(struct mlxsw_sp_port *mlxsw_sp_port, bool ingress, ...@@ -455,13 +449,12 @@ void mlxsw_sp_flower_destroy(struct mlxsw_sp_port *mlxsw_sp_port, bool ingress,
} }
mlxsw_sp_acl_ruleset_put(mlxsw_sp, ruleset); mlxsw_sp_acl_ruleset_put(mlxsw_sp, ruleset);
mlxsw_sp_port->acl_rule_count--;
} }
int mlxsw_sp_flower_stats(struct mlxsw_sp_port *mlxsw_sp_port, bool ingress, int mlxsw_sp_flower_stats(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_acl_block *block,
struct tc_cls_flower_offload *f) struct tc_cls_flower_offload *f)
{ {
struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
struct mlxsw_sp_acl_ruleset *ruleset; struct mlxsw_sp_acl_ruleset *ruleset;
struct mlxsw_sp_acl_rule *rule; struct mlxsw_sp_acl_rule *rule;
u64 packets; u64 packets;
...@@ -469,8 +462,8 @@ int mlxsw_sp_flower_stats(struct mlxsw_sp_port *mlxsw_sp_port, bool ingress, ...@@ -469,8 +462,8 @@ int mlxsw_sp_flower_stats(struct mlxsw_sp_port *mlxsw_sp_port, bool ingress,
u64 bytes; u64 bytes;
int err; int err;
ruleset = mlxsw_sp_acl_ruleset_get(mlxsw_sp, mlxsw_sp_port->dev, ruleset = mlxsw_sp_acl_ruleset_get(mlxsw_sp, block,
ingress, f->common.chain_index, f->common.chain_index,
MLXSW_SP_ACL_PROFILE_FLOWER); MLXSW_SP_ACL_PROFILE_FLOWER);
if (WARN_ON(IS_ERR(ruleset))) if (WARN_ON(IS_ERR(ruleset)))
return -EINVAL; return -EINVAL;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment