Commit 8a271746 authored by Mohamad Haj Yahia's avatar Mohamad Haj Yahia Committed by Saeed Mahameed

net/mlx5e: Receive s-tagged packets in promiscuous mode

Today when the driver enter to promiscuous mode or vlan
filter is disabled, we add flow rule to receive any c-taggd
packets, therefore s-tagged packets are dropped.
In order to receive s-tagged packets as well we need to add
flow rule to receive any s-tagged packet.

Fixes: 7cb21b79 ('net/mlx5e: Rename en_flow_table.c to en_fs.c')
Signed-off-by: default avatarMohamad Haj Yahia <mohamad@mellanox.com>
Signed-off-by: default avatarSaeed Mahameed <saeedm@mellanox.com>
parent 10543365
...@@ -572,7 +572,8 @@ struct mlx5e_vlan_table { ...@@ -572,7 +572,8 @@ struct mlx5e_vlan_table {
unsigned long active_vlans[BITS_TO_LONGS(VLAN_N_VID)]; unsigned long active_vlans[BITS_TO_LONGS(VLAN_N_VID)];
struct mlx5_flow_handle *active_vlans_rule[VLAN_N_VID]; struct mlx5_flow_handle *active_vlans_rule[VLAN_N_VID];
struct mlx5_flow_handle *untagged_rule; struct mlx5_flow_handle *untagged_rule;
struct mlx5_flow_handle *any_vlan_rule; struct mlx5_flow_handle *any_cvlan_rule;
struct mlx5_flow_handle *any_svlan_rule;
bool filter_disabled; bool filter_disabled;
}; };
......
...@@ -150,7 +150,8 @@ static int mlx5e_vport_context_update_vlans(struct mlx5e_priv *priv) ...@@ -150,7 +150,8 @@ static int mlx5e_vport_context_update_vlans(struct mlx5e_priv *priv)
enum mlx5e_vlan_rule_type { enum mlx5e_vlan_rule_type {
MLX5E_VLAN_RULE_TYPE_UNTAGGED, MLX5E_VLAN_RULE_TYPE_UNTAGGED,
MLX5E_VLAN_RULE_TYPE_ANY_VID, MLX5E_VLAN_RULE_TYPE_ANY_CTAG_VID,
MLX5E_VLAN_RULE_TYPE_ANY_STAG_VID,
MLX5E_VLAN_RULE_TYPE_MATCH_VID, MLX5E_VLAN_RULE_TYPE_MATCH_VID,
}; };
...@@ -172,18 +173,30 @@ static int __mlx5e_add_vlan_rule(struct mlx5e_priv *priv, ...@@ -172,18 +173,30 @@ static int __mlx5e_add_vlan_rule(struct mlx5e_priv *priv,
dest.ft = priv->fs.l2.ft.t; dest.ft = priv->fs.l2.ft.t;
spec->match_criteria_enable = MLX5_MATCH_OUTER_HEADERS; spec->match_criteria_enable = MLX5_MATCH_OUTER_HEADERS;
MLX5_SET_TO_ONES(fte_match_param, spec->match_criteria, outer_headers.cvlan_tag);
switch (rule_type) { switch (rule_type) {
case MLX5E_VLAN_RULE_TYPE_UNTAGGED: case MLX5E_VLAN_RULE_TYPE_UNTAGGED:
rule_p = &priv->fs.vlan.untagged_rule; rule_p = &priv->fs.vlan.untagged_rule;
MLX5_SET_TO_ONES(fte_match_param, spec->match_criteria,
outer_headers.cvlan_tag);
break; break;
case MLX5E_VLAN_RULE_TYPE_ANY_VID: case MLX5E_VLAN_RULE_TYPE_ANY_CTAG_VID:
rule_p = &priv->fs.vlan.any_vlan_rule; rule_p = &priv->fs.vlan.any_cvlan_rule;
MLX5_SET_TO_ONES(fte_match_param, spec->match_criteria,
outer_headers.cvlan_tag);
MLX5_SET(fte_match_param, spec->match_value, outer_headers.cvlan_tag, 1); MLX5_SET(fte_match_param, spec->match_value, outer_headers.cvlan_tag, 1);
break; break;
case MLX5E_VLAN_RULE_TYPE_ANY_STAG_VID:
rule_p = &priv->fs.vlan.any_svlan_rule;
MLX5_SET_TO_ONES(fte_match_param, spec->match_criteria,
outer_headers.svlan_tag);
MLX5_SET(fte_match_param, spec->match_value, outer_headers.svlan_tag, 1);
break;
default: /* MLX5E_VLAN_RULE_TYPE_MATCH_VID */ default: /* MLX5E_VLAN_RULE_TYPE_MATCH_VID */
rule_p = &priv->fs.vlan.active_vlans_rule[vid]; rule_p = &priv->fs.vlan.active_vlans_rule[vid];
MLX5_SET_TO_ONES(fte_match_param, spec->match_criteria,
outer_headers.cvlan_tag);
MLX5_SET(fte_match_param, spec->match_value, outer_headers.cvlan_tag, 1); MLX5_SET(fte_match_param, spec->match_value, outer_headers.cvlan_tag, 1);
MLX5_SET_TO_ONES(fte_match_param, spec->match_criteria, MLX5_SET_TO_ONES(fte_match_param, spec->match_criteria,
outer_headers.first_vid); outer_headers.first_vid);
...@@ -235,10 +248,16 @@ static void mlx5e_del_vlan_rule(struct mlx5e_priv *priv, ...@@ -235,10 +248,16 @@ static void mlx5e_del_vlan_rule(struct mlx5e_priv *priv,
priv->fs.vlan.untagged_rule = NULL; priv->fs.vlan.untagged_rule = NULL;
} }
break; break;
case MLX5E_VLAN_RULE_TYPE_ANY_VID: case MLX5E_VLAN_RULE_TYPE_ANY_CTAG_VID:
if (priv->fs.vlan.any_vlan_rule) { if (priv->fs.vlan.any_cvlan_rule) {
mlx5_del_flow_rules(priv->fs.vlan.any_vlan_rule); mlx5_del_flow_rules(priv->fs.vlan.any_cvlan_rule);
priv->fs.vlan.any_vlan_rule = NULL; priv->fs.vlan.any_cvlan_rule = NULL;
}
break;
case MLX5E_VLAN_RULE_TYPE_ANY_STAG_VID:
if (priv->fs.vlan.any_svlan_rule) {
mlx5_del_flow_rules(priv->fs.vlan.any_svlan_rule);
priv->fs.vlan.any_svlan_rule = NULL;
} }
break; break;
case MLX5E_VLAN_RULE_TYPE_MATCH_VID: case MLX5E_VLAN_RULE_TYPE_MATCH_VID:
...@@ -252,6 +271,23 @@ static void mlx5e_del_vlan_rule(struct mlx5e_priv *priv, ...@@ -252,6 +271,23 @@ static void mlx5e_del_vlan_rule(struct mlx5e_priv *priv,
} }
} }
static void mlx5e_del_any_vid_rules(struct mlx5e_priv *priv)
{
mlx5e_del_vlan_rule(priv, MLX5E_VLAN_RULE_TYPE_ANY_CTAG_VID, 0);
mlx5e_del_vlan_rule(priv, MLX5E_VLAN_RULE_TYPE_ANY_STAG_VID, 0);
}
static int mlx5e_add_any_vid_rules(struct mlx5e_priv *priv)
{
int err;
err = mlx5e_add_vlan_rule(priv, MLX5E_VLAN_RULE_TYPE_ANY_CTAG_VID, 0);
if (err)
return err;
return mlx5e_add_vlan_rule(priv, MLX5E_VLAN_RULE_TYPE_ANY_STAG_VID, 0);
}
void mlx5e_enable_vlan_filter(struct mlx5e_priv *priv) void mlx5e_enable_vlan_filter(struct mlx5e_priv *priv)
{ {
if (!priv->fs.vlan.filter_disabled) if (!priv->fs.vlan.filter_disabled)
...@@ -260,7 +296,7 @@ void mlx5e_enable_vlan_filter(struct mlx5e_priv *priv) ...@@ -260,7 +296,7 @@ void mlx5e_enable_vlan_filter(struct mlx5e_priv *priv)
priv->fs.vlan.filter_disabled = false; priv->fs.vlan.filter_disabled = false;
if (priv->netdev->flags & IFF_PROMISC) if (priv->netdev->flags & IFF_PROMISC)
return; return;
mlx5e_del_vlan_rule(priv, MLX5E_VLAN_RULE_TYPE_ANY_VID, 0); mlx5e_del_any_vid_rules(priv);
} }
void mlx5e_disable_vlan_filter(struct mlx5e_priv *priv) void mlx5e_disable_vlan_filter(struct mlx5e_priv *priv)
...@@ -271,7 +307,7 @@ void mlx5e_disable_vlan_filter(struct mlx5e_priv *priv) ...@@ -271,7 +307,7 @@ void mlx5e_disable_vlan_filter(struct mlx5e_priv *priv)
priv->fs.vlan.filter_disabled = true; priv->fs.vlan.filter_disabled = true;
if (priv->netdev->flags & IFF_PROMISC) if (priv->netdev->flags & IFF_PROMISC)
return; return;
mlx5e_add_vlan_rule(priv, MLX5E_VLAN_RULE_TYPE_ANY_VID, 0); mlx5e_add_any_vid_rules(priv);
} }
int mlx5e_vlan_rx_add_vid(struct net_device *dev, __always_unused __be16 proto, int mlx5e_vlan_rx_add_vid(struct net_device *dev, __always_unused __be16 proto,
...@@ -308,7 +344,7 @@ static void mlx5e_add_vlan_rules(struct mlx5e_priv *priv) ...@@ -308,7 +344,7 @@ static void mlx5e_add_vlan_rules(struct mlx5e_priv *priv)
if (priv->fs.vlan.filter_disabled && if (priv->fs.vlan.filter_disabled &&
!(priv->netdev->flags & IFF_PROMISC)) !(priv->netdev->flags & IFF_PROMISC))
mlx5e_add_vlan_rule(priv, MLX5E_VLAN_RULE_TYPE_ANY_VID, 0); mlx5e_add_any_vid_rules(priv);
} }
static void mlx5e_del_vlan_rules(struct mlx5e_priv *priv) static void mlx5e_del_vlan_rules(struct mlx5e_priv *priv)
...@@ -323,7 +359,7 @@ static void mlx5e_del_vlan_rules(struct mlx5e_priv *priv) ...@@ -323,7 +359,7 @@ static void mlx5e_del_vlan_rules(struct mlx5e_priv *priv)
if (priv->fs.vlan.filter_disabled && if (priv->fs.vlan.filter_disabled &&
!(priv->netdev->flags & IFF_PROMISC)) !(priv->netdev->flags & IFF_PROMISC))
mlx5e_del_vlan_rule(priv, MLX5E_VLAN_RULE_TYPE_ANY_VID, 0); mlx5e_del_any_vid_rules(priv);
} }
#define mlx5e_for_each_hash_node(hn, tmp, hash, i) \ #define mlx5e_for_each_hash_node(hn, tmp, hash, i) \
...@@ -503,8 +539,7 @@ void mlx5e_set_rx_mode_work(struct work_struct *work) ...@@ -503,8 +539,7 @@ void mlx5e_set_rx_mode_work(struct work_struct *work)
if (enable_promisc) { if (enable_promisc) {
mlx5e_add_l2_flow_rule(priv, &ea->promisc, MLX5E_PROMISC); mlx5e_add_l2_flow_rule(priv, &ea->promisc, MLX5E_PROMISC);
if (!priv->fs.vlan.filter_disabled) if (!priv->fs.vlan.filter_disabled)
mlx5e_add_vlan_rule(priv, MLX5E_VLAN_RULE_TYPE_ANY_VID, mlx5e_add_any_vid_rules(priv);
0);
} }
if (enable_allmulti) if (enable_allmulti)
mlx5e_add_l2_flow_rule(priv, &ea->allmulti, MLX5E_ALLMULTI); mlx5e_add_l2_flow_rule(priv, &ea->allmulti, MLX5E_ALLMULTI);
...@@ -519,8 +554,7 @@ void mlx5e_set_rx_mode_work(struct work_struct *work) ...@@ -519,8 +554,7 @@ void mlx5e_set_rx_mode_work(struct work_struct *work)
mlx5e_del_l2_flow_rule(priv, &ea->allmulti); mlx5e_del_l2_flow_rule(priv, &ea->allmulti);
if (disable_promisc) { if (disable_promisc) {
if (!priv->fs.vlan.filter_disabled) if (!priv->fs.vlan.filter_disabled)
mlx5e_del_vlan_rule(priv, MLX5E_VLAN_RULE_TYPE_ANY_VID, mlx5e_del_any_vid_rules(priv);
0);
mlx5e_del_l2_flow_rule(priv, &ea->promisc); mlx5e_del_l2_flow_rule(priv, &ea->promisc);
} }
...@@ -976,11 +1010,13 @@ static int mlx5e_create_l2_table(struct mlx5e_priv *priv) ...@@ -976,11 +1010,13 @@ static int mlx5e_create_l2_table(struct mlx5e_priv *priv)
return err; return err;
} }
#define MLX5E_NUM_VLAN_GROUPS 2 #define MLX5E_NUM_VLAN_GROUPS 3
#define MLX5E_VLAN_GROUP0_SIZE BIT(12) #define MLX5E_VLAN_GROUP0_SIZE BIT(12)
#define MLX5E_VLAN_GROUP1_SIZE BIT(1) #define MLX5E_VLAN_GROUP1_SIZE BIT(1)
#define MLX5E_VLAN_GROUP2_SIZE BIT(0)
#define MLX5E_VLAN_TABLE_SIZE (MLX5E_VLAN_GROUP0_SIZE +\ #define MLX5E_VLAN_TABLE_SIZE (MLX5E_VLAN_GROUP0_SIZE +\
MLX5E_VLAN_GROUP1_SIZE) MLX5E_VLAN_GROUP1_SIZE +\
MLX5E_VLAN_GROUP2_SIZE)
static int __mlx5e_create_vlan_table_groups(struct mlx5e_flow_table *ft, u32 *in, static int __mlx5e_create_vlan_table_groups(struct mlx5e_flow_table *ft, u32 *in,
int inlen) int inlen)
...@@ -1012,6 +1048,17 @@ static int __mlx5e_create_vlan_table_groups(struct mlx5e_flow_table *ft, u32 *in ...@@ -1012,6 +1048,17 @@ static int __mlx5e_create_vlan_table_groups(struct mlx5e_flow_table *ft, u32 *in
goto err_destroy_groups; goto err_destroy_groups;
ft->num_groups++; ft->num_groups++;
memset(in, 0, inlen);
MLX5_SET_CFG(in, match_criteria_enable, MLX5_MATCH_OUTER_HEADERS);
MLX5_SET_TO_ONES(fte_match_param, mc, outer_headers.svlan_tag);
MLX5_SET_CFG(in, start_flow_index, ix);
ix += MLX5E_VLAN_GROUP2_SIZE;
MLX5_SET_CFG(in, end_flow_index, ix - 1);
ft->g[ft->num_groups] = mlx5_create_flow_group(ft->t, in);
if (IS_ERR(ft->g[ft->num_groups]))
goto err_destroy_groups;
ft->num_groups++;
return 0; return 0;
err_destroy_groups: err_destroy_groups:
......
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