ice: Fix VF-VF filter rules in switchdev mode

Any packet leaving VSI i.e VF's VSI is considered as
egress traffic by HW, thus failing to match the added
rule.

Mark the direction for redirect rules as below:
1. VF-VF - Egress
2. Uplink-VF - Ingress
3. VF-Uplink - Egress
4. Link_Partner-Uplink - Ingress
5. Link_Partner-VF - Ingress

Fixes: 0960a27bd4 ("ice: Add direction metadata")
Reviewed-by: Przemek Kitszel <przemyslaw.kitszel@intel.com>
Reviewed-by: Wojciech Drewek <wojciech.drewek@intel.com>
Signed-off-by: Aniruddha Paul <aniruddha.paul@intel.com>
Tested-by: Sujai Buvaneswaran <sujai.buvaneswaran@intel.com>
Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
This commit is contained in:
Aniruddha Paul 2023-10-13 19:13:42 +05:30 committed by Tony Nguyen
parent e1db8c2a01
commit 8b3c8c55cc
1 changed files with 62 additions and 28 deletions

View File

@ -630,32 +630,61 @@ bool ice_is_tunnel_supported(struct net_device *dev)
return ice_tc_tun_get_type(dev) != TNL_LAST;
}
static int
ice_eswitch_tc_parse_action(struct ice_tc_flower_fltr *fltr,
struct flow_action_entry *act)
static bool ice_tc_is_dev_uplink(struct net_device *dev)
{
return netif_is_ice(dev) || ice_is_tunnel_supported(dev);
}
static int ice_tc_setup_redirect_action(struct net_device *filter_dev,
struct ice_tc_flower_fltr *fltr,
struct net_device *target_dev)
{
struct ice_repr *repr;
fltr->action.fltr_act = ICE_FWD_TO_VSI;
if (ice_is_port_repr_netdev(filter_dev) &&
ice_is_port_repr_netdev(target_dev)) {
repr = ice_netdev_to_repr(target_dev);
fltr->dest_vsi = repr->src_vsi;
fltr->direction = ICE_ESWITCH_FLTR_EGRESS;
} else if (ice_is_port_repr_netdev(filter_dev) &&
ice_tc_is_dev_uplink(target_dev)) {
repr = ice_netdev_to_repr(filter_dev);
fltr->dest_vsi = repr->src_vsi->back->switchdev.uplink_vsi;
fltr->direction = ICE_ESWITCH_FLTR_EGRESS;
} else if (ice_tc_is_dev_uplink(filter_dev) &&
ice_is_port_repr_netdev(target_dev)) {
repr = ice_netdev_to_repr(target_dev);
fltr->dest_vsi = repr->src_vsi;
fltr->direction = ICE_ESWITCH_FLTR_INGRESS;
} else {
NL_SET_ERR_MSG_MOD(fltr->extack,
"Unsupported netdevice in switchdev mode");
return -EINVAL;
}
return 0;
}
static int ice_eswitch_tc_parse_action(struct net_device *filter_dev,
struct ice_tc_flower_fltr *fltr,
struct flow_action_entry *act)
{
int err;
switch (act->id) {
case FLOW_ACTION_DROP:
fltr->action.fltr_act = ICE_DROP_PACKET;
break;
case FLOW_ACTION_REDIRECT:
fltr->action.fltr_act = ICE_FWD_TO_VSI;
if (ice_is_port_repr_netdev(act->dev)) {
repr = ice_netdev_to_repr(act->dev);
fltr->dest_vsi = repr->src_vsi;
fltr->direction = ICE_ESWITCH_FLTR_INGRESS;
} else if (netif_is_ice(act->dev) ||
ice_is_tunnel_supported(act->dev)) {
fltr->direction = ICE_ESWITCH_FLTR_EGRESS;
} else {
NL_SET_ERR_MSG_MOD(fltr->extack, "Unsupported netdevice in switchdev mode");
return -EINVAL;
}
err = ice_tc_setup_redirect_action(filter_dev, fltr, act->dev);
if (err)
return err;
break;
@ -696,10 +725,6 @@ ice_eswitch_add_tc_fltr(struct ice_vsi *vsi, struct ice_tc_flower_fltr *fltr)
goto exit;
}
/* egress traffic is always redirect to uplink */
if (fltr->direction == ICE_ESWITCH_FLTR_EGRESS)
fltr->dest_vsi = vsi->back->switchdev.uplink_vsi;
rule_info.sw_act.fltr_act = fltr->action.fltr_act;
if (fltr->action.fltr_act != ICE_DROP_PACKET)
rule_info.sw_act.vsi_handle = fltr->dest_vsi->idx;
@ -713,13 +738,21 @@ ice_eswitch_add_tc_fltr(struct ice_vsi *vsi, struct ice_tc_flower_fltr *fltr)
rule_info.flags_info.act_valid = true;
if (fltr->direction == ICE_ESWITCH_FLTR_INGRESS) {
/* Uplink to VF */
rule_info.sw_act.flag |= ICE_FLTR_RX;
rule_info.sw_act.src = hw->pf_id;
rule_info.flags_info.act = ICE_SINGLE_ACT_LB_ENABLE;
} else {
} else if (fltr->direction == ICE_ESWITCH_FLTR_EGRESS &&
fltr->dest_vsi == vsi->back->switchdev.uplink_vsi) {
/* VF to Uplink */
rule_info.sw_act.flag |= ICE_FLTR_TX;
rule_info.sw_act.src = vsi->idx;
rule_info.flags_info.act = ICE_SINGLE_ACT_LAN_ENABLE;
} else {
/* VF to VF */
rule_info.sw_act.flag |= ICE_FLTR_TX;
rule_info.sw_act.src = vsi->idx;
rule_info.flags_info.act = ICE_SINGLE_ACT_LB_ENABLE;
}
/* specify the cookie as filter_rule_id */
@ -1745,16 +1778,17 @@ ice_tc_parse_action(struct ice_vsi *vsi, struct ice_tc_flower_fltr *fltr,
/**
* ice_parse_tc_flower_actions - Parse the actions for a TC filter
* @filter_dev: Pointer to device on which filter is being added
* @vsi: Pointer to VSI
* @cls_flower: Pointer to TC flower offload structure
* @fltr: Pointer to TC flower filter structure
*
* Parse the actions for a TC filter
*/
static int
ice_parse_tc_flower_actions(struct ice_vsi *vsi,
struct flow_cls_offload *cls_flower,
struct ice_tc_flower_fltr *fltr)
static int ice_parse_tc_flower_actions(struct net_device *filter_dev,
struct ice_vsi *vsi,
struct flow_cls_offload *cls_flower,
struct ice_tc_flower_fltr *fltr)
{
struct flow_rule *rule = flow_cls_offload_flow_rule(cls_flower);
struct flow_action *flow_action = &rule->action;
@ -1769,7 +1803,7 @@ ice_parse_tc_flower_actions(struct ice_vsi *vsi,
flow_action_for_each(i, act, flow_action) {
if (ice_is_eswitch_mode_switchdev(vsi->back))
err = ice_eswitch_tc_parse_action(fltr, act);
err = ice_eswitch_tc_parse_action(filter_dev, fltr, act);
else
err = ice_tc_parse_action(vsi, fltr, act);
if (err)
@ -1856,7 +1890,7 @@ ice_add_tc_fltr(struct net_device *netdev, struct ice_vsi *vsi,
if (err < 0)
goto err;
err = ice_parse_tc_flower_actions(vsi, f, fltr);
err = ice_parse_tc_flower_actions(netdev, vsi, f, fltr);
if (err < 0)
goto err;