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,
|
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_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);
|
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);
|
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;
|
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_ruleset_ht_key {
|
||||||
struct mlxsw_sp_acl_block *block;
|
struct mlxsw_sp_acl_block *block;
|
||||||
u32 chain_index;
|
u32 chain_index;
|
||||||
|
@ -221,6 +213,7 @@ struct mlxsw_sp_acl_block *mlxsw_sp_acl_block_create(struct mlxsw_sp *mlxsw_sp,
|
||||||
return NULL;
|
return NULL;
|
||||||
INIT_LIST_HEAD(&block->binding_list);
|
INIT_LIST_HEAD(&block->binding_list);
|
||||||
block->mlxsw_sp = mlxsw_sp;
|
block->mlxsw_sp = mlxsw_sp;
|
||||||
|
block->net = net;
|
||||||
return block;
|
return block;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -120,6 +120,49 @@ static int mlxsw_sp_flower_parse_actions(struct mlxsw_sp *mlxsw_sp,
|
||||||
return 0;
|
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,
|
static void mlxsw_sp_flower_parse_ipv4(struct mlxsw_sp_acl_rule_info *rulei,
|
||||||
struct tc_cls_flower_offload *f)
|
struct tc_cls_flower_offload *f)
|
||||||
{
|
{
|
||||||
|
@ -267,7 +310,8 @@ static int mlxsw_sp_flower_parse(struct mlxsw_sp *mlxsw_sp,
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
if (dissector->used_keys &
|
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_BASIC) |
|
||||||
BIT(FLOW_DISSECTOR_KEY_ETH_ADDRS) |
|
BIT(FLOW_DISSECTOR_KEY_ETH_ADDRS) |
|
||||||
BIT(FLOW_DISSECTOR_KEY_IPV4_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);
|
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)) {
|
if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_CONTROL)) {
|
||||||
struct flow_match_control match;
|
struct flow_match_control match;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue