Skip to content

Commit

Permalink
ice: add drop rule matching on not active lport
Browse files Browse the repository at this point in the history
Inactive LAG port should not receive any packets, as it can cause adding
invalid FDBs (bridge offload). Add a drop rule matching on inactive lport
in LAG.

Reviewed-by: Simon Horman <horms@kernel.org>
Co-developed-by: Marcin Szycik <marcin.szycik@intel.com>
Signed-off-by: Marcin Szycik <marcin.szycik@intel.com>
Signed-off-by: Michal Swiatkowski <michal.swiatkowski@linux.intel.com>
Tested-by: Sujai Buvaneswaran <sujai.buvaneswaran@intel.com>
Signed-off-by: Jacob Keller <jacob.e.keller@intel.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Michal Swiatkowski authored and David S. Miller committed Oct 20, 2023
1 parent 4cd7bc7 commit 9dffb97
Show file tree
Hide file tree
Showing 3 changed files with 75 additions and 20 deletions.
6 changes: 3 additions & 3 deletions drivers/net/ethernet/intel/ice/ice_eswitch_br.c
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ ice_eswitch_br_ingress_rule_setup(struct ice_adv_rule_info *rule_info,
rule_info->sw_act.vsi_handle = vf_vsi_idx;
rule_info->sw_act.flag |= ICE_FLTR_RX;
rule_info->sw_act.src = pf_id;
rule_info->priority = 5;
rule_info->priority = 2;
}

static void
Expand All @@ -84,7 +84,7 @@ ice_eswitch_br_egress_rule_setup(struct ice_adv_rule_info *rule_info,
rule_info->sw_act.flag |= ICE_FLTR_TX;
rule_info->flags_info.act = ICE_SINGLE_ACT_LAN_ENABLE;
rule_info->flags_info.act_valid = true;
rule_info->priority = 5;
rule_info->priority = 2;
}

static int
Expand Down Expand Up @@ -207,7 +207,7 @@ ice_eswitch_br_guard_rule_create(struct ice_hw *hw, u16 vsi_idx,
rule_info.allow_pass_l2 = true;
rule_info.sw_act.vsi_handle = vsi_idx;
rule_info.sw_act.fltr_act = ICE_NOP;
rule_info.priority = 5;
rule_info.priority = 2;

err = ice_add_adv_rule(hw, list, lkups_cnt, &rule_info, rule);
if (err)
Expand Down
87 changes: 70 additions & 17 deletions drivers/net/ethernet/intel/ice/ice_lag.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,11 @@ static const u8 lacp_train_pkt[LACP_TRAIN_PKT_LEN] = { 0, 0, 0, 0, 0, 0,
static const u8 ice_dflt_vsi_rcp[ICE_RECIPE_LEN] = {
0x05, 0, 0, 0, 0x20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0x85, 0, 0x01, 0, 0, 0, 0xff, 0xff, 0x08, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0x30, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
0, 0, 0, 0, 0, 0, 0x30 };
static const u8 ice_lport_rcp[ICE_RECIPE_LEN] = {
0x05, 0, 0, 0, 0x20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0x85, 0, 0x16, 0, 0, 0, 0xff, 0xff, 0x07, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0x30 };

/**
* ice_lag_set_primary - set PF LAG state as Primary
Expand Down Expand Up @@ -173,18 +176,22 @@ static struct ice_lag *ice_lag_find_primary(struct ice_lag *lag)
}

/**
* ice_lag_cfg_dflt_fltr - Add/Remove default VSI rule for LAG
* ice_lag_cfg_fltr - Add/Remove rule for LAG
* @lag: lag struct for local interface
* @act: rule action
* @recipe_id: recipe id for the new rule
* @rule_idx: pointer to rule index
* @add: boolean on whether we are adding filters
*/
static int
ice_lag_cfg_dflt_fltr(struct ice_lag *lag, bool add)
ice_lag_cfg_fltr(struct ice_lag *lag, u32 act, u16 recipe_id, u16 *rule_idx,
bool add)
{
struct ice_sw_rule_lkup_rx_tx *s_rule;
u16 s_rule_sz, vsi_num;
struct ice_hw *hw;
u32 act, opc;
u8 *eth_hdr;
u32 opc;
int err;

hw = &lag->pf->hw;
Expand All @@ -193,27 +200,25 @@ ice_lag_cfg_dflt_fltr(struct ice_lag *lag, bool add)
s_rule_sz = ICE_SW_RULE_RX_TX_ETH_HDR_SIZE(s_rule);
s_rule = kzalloc(s_rule_sz, GFP_KERNEL);
if (!s_rule) {
dev_err(ice_pf_to_dev(lag->pf), "error allocating rule for LAG default VSI\n");
dev_err(ice_pf_to_dev(lag->pf), "error allocating rule for LAG\n");
return -ENOMEM;
}

if (add) {
eth_hdr = s_rule->hdr_data;
ice_fill_eth_hdr(eth_hdr);

act = (vsi_num << ICE_SINGLE_ACT_VSI_ID_S) &
act |= (vsi_num << ICE_SINGLE_ACT_VSI_ID_S) &
ICE_SINGLE_ACT_VSI_ID_M;
act |= ICE_SINGLE_ACT_VSI_FORWARDING |
ICE_SINGLE_ACT_VALID_BIT | ICE_SINGLE_ACT_LAN_ENABLE;

s_rule->hdr.type = cpu_to_le16(ICE_AQC_SW_RULES_T_LKUP_RX);
s_rule->recipe_id = cpu_to_le16(lag->pf_recipe);
s_rule->recipe_id = cpu_to_le16(recipe_id);
s_rule->src = cpu_to_le16(hw->port_info->lport);
s_rule->act = cpu_to_le32(act);
s_rule->hdr_len = cpu_to_le16(DUMMY_ETH_HDR_LEN);
opc = ice_aqc_opc_add_sw_rules;
} else {
s_rule->index = cpu_to_le16(lag->pf_rule_id);
s_rule->index = cpu_to_le16(*rule_idx);
opc = ice_aqc_opc_remove_sw_rules;
}

Expand All @@ -222,15 +227,46 @@ ice_lag_cfg_dflt_fltr(struct ice_lag *lag, bool add)
goto dflt_fltr_free;

if (add)
lag->pf_rule_id = le16_to_cpu(s_rule->index);
*rule_idx = le16_to_cpu(s_rule->index);
else
lag->pf_rule_id = 0;
*rule_idx = 0;

dflt_fltr_free:
kfree(s_rule);
return err;
}

/**
* ice_lag_cfg_dflt_fltr - Add/Remove default VSI rule for LAG
* @lag: lag struct for local interface
* @add: boolean on whether to add filter
*/
static int
ice_lag_cfg_dflt_fltr(struct ice_lag *lag, bool add)
{
u32 act = ICE_SINGLE_ACT_VSI_FORWARDING |
ICE_SINGLE_ACT_VALID_BIT | ICE_SINGLE_ACT_LAN_ENABLE;

return ice_lag_cfg_fltr(lag, act, lag->pf_recipe,
&lag->pf_rule_id, add);
}

/**
* ice_lag_cfg_drop_fltr - Add/Remove lport drop rule
* @lag: lag struct for local interface
* @add: boolean on whether to add filter
*/
static int
ice_lag_cfg_drop_fltr(struct ice_lag *lag, bool add)
{
u32 act = ICE_SINGLE_ACT_VSI_FORWARDING |
ICE_SINGLE_ACT_VALID_BIT |
ICE_SINGLE_ACT_DROP;

return ice_lag_cfg_fltr(lag, act, lag->lport_recipe,
&lag->lport_rule_idx, add);
}

/**
* ice_lag_cfg_pf_fltrs - set filters up for new active port
* @lag: local interfaces lag struct
Expand All @@ -257,13 +293,18 @@ ice_lag_cfg_pf_fltrs(struct ice_lag *lag, void *ptr)
if (bonding_info->slave.state && lag->pf_rule_id) {
if (ice_lag_cfg_dflt_fltr(lag, false))
dev_err(dev, "Error removing old default VSI filter\n");
if (ice_lag_cfg_drop_fltr(lag, true))
dev_err(dev, "Error adding new drop filter\n");
return;
}

/* interface becoming active - add new default VSI rule */
if (!bonding_info->slave.state && !lag->pf_rule_id)
if (!bonding_info->slave.state && !lag->pf_rule_id) {
if (ice_lag_cfg_dflt_fltr(lag, true))
dev_err(dev, "Error adding new default VSI filter\n");
if (lag->lport_rule_idx && ice_lag_cfg_drop_fltr(lag, false))
dev_err(dev, "Error removing old drop filter\n");
}
}

/**
Expand Down Expand Up @@ -1179,6 +1220,7 @@ static void ice_lag_changeupper_event(struct ice_lag *lag, void *ptr)
swid = primary_lag->pf->hw.port_info->sw_id;
ice_lag_set_swid(swid, lag, true);
ice_lag_add_prune_list(primary_lag, lag->pf);
ice_lag_cfg_drop_fltr(lag, true);
}
/* add filter for primary control packets */
ice_lag_cfg_cp_fltr(lag, true);
Expand Down Expand Up @@ -1929,11 +1971,16 @@ int ice_init_lag(struct ice_pf *pf)
goto lag_error;
}

err = ice_create_lag_recipe(&pf->hw, &lag->pf_recipe, ice_dflt_vsi_rcp,
1);
err = ice_create_lag_recipe(&pf->hw, &lag->pf_recipe,
ice_dflt_vsi_rcp, 1);
if (err)
goto lag_error;

err = ice_create_lag_recipe(&pf->hw, &lag->lport_recipe,
ice_lport_rcp, 3);
if (err)
goto free_rcp_res;

/* associate recipes to profiles */
for (n = 0; n < ICE_PROFID_IPV6_GTPU_IPV6_TCP_INNER; n++) {
err = ice_aq_get_recipe_to_profile(&pf->hw, n,
Expand All @@ -1942,7 +1989,8 @@ int ice_init_lag(struct ice_pf *pf)
continue;

if (recipe_bits & BIT(ICE_SW_LKUP_DFLT)) {
recipe_bits |= BIT(lag->pf_recipe);
recipe_bits |= BIT(lag->pf_recipe) |
BIT(lag->lport_recipe);
ice_aq_map_recipe_to_profile(&pf->hw, n,
(u8 *)&recipe_bits, NULL);
}
Expand All @@ -1953,6 +2001,9 @@ int ice_init_lag(struct ice_pf *pf)
dev_dbg(dev, "INIT LAG complete\n");
return 0;

free_rcp_res:
ice_free_hw_res(&pf->hw, ICE_AQC_RES_TYPE_RECIPE, 1,
&pf->lag->pf_recipe);
lag_error:
kfree(lag);
pf->lag = NULL;
Expand Down Expand Up @@ -1982,6 +2033,8 @@ void ice_deinit_lag(struct ice_pf *pf)

ice_free_hw_res(&pf->hw, ICE_AQC_RES_TYPE_RECIPE, 1,
&pf->lag->pf_recipe);
ice_free_hw_res(&pf->hw, ICE_AQC_RES_TYPE_RECIPE, 1,
&pf->lag->lport_recipe);

kfree(lag);

Expand Down
2 changes: 2 additions & 0 deletions drivers/net/ethernet/intel/ice/ice_lag.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,10 @@ struct ice_lag {
u8 bonded:1; /* currently bonded */
u8 primary:1; /* this is primary */
u16 pf_recipe;
u16 lport_recipe;
u16 pf_rule_id;
u16 cp_rule_idx;
u16 lport_rule_idx;
u8 role;
};

Expand Down

0 comments on commit 9dffb97

Please sign in to comment.