mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2025-01-10 15:54:39 +08:00
mlxsw: spectrum_flower: Implement support for ingress device matching
Benefit from the previously extended flow_dissector infrastructure and offload matching on ingress port. Signed-off-by: Jiri Pirko <jiri@mellanox.com> Signed-off-by: Ido Schimmel <idosch@mellanox.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
d8e9461446
commit
0c1f391d19
@ -623,6 +623,15 @@ enum mlxsw_sp_acl_profile {
|
||||
MLXSW_SP_ACL_PROFILE_MR,
|
||||
};
|
||||
|
||||
struct mlxsw_sp_acl_block {
|
||||
struct list_head binding_list;
|
||||
struct mlxsw_sp_acl_ruleset *ruleset_zero;
|
||||
struct mlxsw_sp *mlxsw_sp;
|
||||
unsigned int rule_count;
|
||||
unsigned int disable_count;
|
||||
struct net *net;
|
||||
};
|
||||
|
||||
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);
|
||||
|
@ -45,14 +45,6 @@ struct mlxsw_sp_acl_block_binding {
|
||||
bool ingress;
|
||||
};
|
||||
|
||||
struct mlxsw_sp_acl_block {
|
||||
struct list_head binding_list;
|
||||
struct mlxsw_sp_acl_ruleset *ruleset_zero;
|
||||
struct mlxsw_sp *mlxsw_sp;
|
||||
unsigned int rule_count;
|
||||
unsigned int disable_count;
|
||||
};
|
||||
|
||||
struct mlxsw_sp_acl_ruleset_ht_key {
|
||||
struct mlxsw_sp_acl_block *block;
|
||||
u32 chain_index;
|
||||
@ -221,6 +213,7 @@ struct mlxsw_sp_acl_block *mlxsw_sp_acl_block_create(struct mlxsw_sp *mlxsw_sp,
|
||||
return NULL;
|
||||
INIT_LIST_HEAD(&block->binding_list);
|
||||
block->mlxsw_sp = mlxsw_sp;
|
||||
block->net = net;
|
||||
return block;
|
||||
}
|
||||
|
||||
|
@ -120,6 +120,49 @@ static int mlxsw_sp_flower_parse_actions(struct mlxsw_sp *mlxsw_sp,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mlxsw_sp_flower_parse_meta(struct mlxsw_sp_acl_rule_info *rulei,
|
||||
struct tc_cls_flower_offload *f,
|
||||
struct mlxsw_sp_acl_block *block)
|
||||
{
|
||||
struct flow_rule *rule = tc_cls_flower_offload_flow_rule(f);
|
||||
struct mlxsw_sp_port *mlxsw_sp_port;
|
||||
struct net_device *ingress_dev;
|
||||
struct flow_match_meta match;
|
||||
|
||||
if (!flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_META))
|
||||
return 0;
|
||||
|
||||
flow_rule_match_meta(rule, &match);
|
||||
if (match.mask->ingress_ifindex != 0xFFFFFFFF) {
|
||||
NL_SET_ERR_MSG_MOD(f->common.extack, "Unsupported ingress ifindex mask");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ingress_dev = __dev_get_by_index(block->net,
|
||||
match.key->ingress_ifindex);
|
||||
if (!ingress_dev) {
|
||||
NL_SET_ERR_MSG_MOD(f->common.extack, "Can't find specified ingress port to match on");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (!mlxsw_sp_port_dev_check(ingress_dev)) {
|
||||
NL_SET_ERR_MSG_MOD(f->common.extack, "Can't match on non-mlxsw ingress port");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
mlxsw_sp_port = netdev_priv(ingress_dev);
|
||||
if (mlxsw_sp_port->mlxsw_sp != block->mlxsw_sp) {
|
||||
NL_SET_ERR_MSG_MOD(f->common.extack, "Can't match on a port from different device");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
mlxsw_sp_acl_rulei_keymask_u32(rulei,
|
||||
MLXSW_AFK_ELEMENT_SRC_SYS_PORT,
|
||||
mlxsw_sp_port->local_port,
|
||||
0xFFFFFFFF);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void mlxsw_sp_flower_parse_ipv4(struct mlxsw_sp_acl_rule_info *rulei,
|
||||
struct tc_cls_flower_offload *f)
|
||||
{
|
||||
@ -267,7 +310,8 @@ static int mlxsw_sp_flower_parse(struct mlxsw_sp *mlxsw_sp,
|
||||
int err;
|
||||
|
||||
if (dissector->used_keys &
|
||||
~(BIT(FLOW_DISSECTOR_KEY_CONTROL) |
|
||||
~(BIT(FLOW_DISSECTOR_KEY_META) |
|
||||
BIT(FLOW_DISSECTOR_KEY_CONTROL) |
|
||||
BIT(FLOW_DISSECTOR_KEY_BASIC) |
|
||||
BIT(FLOW_DISSECTOR_KEY_ETH_ADDRS) |
|
||||
BIT(FLOW_DISSECTOR_KEY_IPV4_ADDRS) |
|
||||
@ -283,6 +327,10 @@ static int mlxsw_sp_flower_parse(struct mlxsw_sp *mlxsw_sp,
|
||||
|
||||
mlxsw_sp_acl_rulei_priority(rulei, f->common.prio);
|
||||
|
||||
err = mlxsw_sp_flower_parse_meta(rulei, f, block);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_CONTROL)) {
|
||||
struct flow_match_control match;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user