ice_tc_forward_action(struct ice_vsi *vsi, struct ice_tc_flower_fltr *tc_fltr)
{
struct ice_rx_ring *ring = NULL;
- struct ice_vsi *ch_vsi = NULL;
+ struct ice_vsi *dest_vsi = NULL;
struct ice_pf *pf = vsi->back;
struct device *dev;
u32 tc_class;
return ERR_PTR(-EOPNOTSUPP);
}
/* Locate ADQ VSI depending on hw_tc number */
- ch_vsi = vsi->tc_map_vsi[tc_class];
+ dest_vsi = vsi->tc_map_vsi[tc_class];
break;
case ICE_FWD_TO_Q:
/* Locate the Rx queue */
/* Determine destination VSI even though the action is
* FWD_TO_QUEUE, because QUEUE is associated with VSI
*/
- ch_vsi = tc_fltr->dest_vsi;
+ dest_vsi = tc_fltr->dest_vsi;
break;
default:
dev_err(dev,
tc_fltr->action.fltr_act);
return ERR_PTR(-EINVAL);
}
- /* Must have valid ch_vsi (it could be main VSI or ADQ VSI) */
- if (!ch_vsi) {
+ /* Must have valid dest_vsi (it could be main VSI or ADQ VSI) */
+ if (!dest_vsi) {
dev_err(dev,
"Unable to add filter because specified destination VSI doesn't exist\n");
return ERR_PTR(-EINVAL);
}
- return ch_vsi;
+ return dest_vsi;
}
/**
struct ice_pf *pf = vsi->back;
struct ice_hw *hw = &pf->hw;
u32 flags = tc_fltr->flags;
- struct ice_vsi *ch_vsi;
+ struct ice_vsi *dest_vsi;
struct device *dev;
u16 lkups_cnt = 0;
u16 l4_proto = 0;
}
/* validate forwarding action VSI and queue */
- ch_vsi = ice_tc_forward_action(vsi, tc_fltr);
- if (IS_ERR(ch_vsi))
- return PTR_ERR(ch_vsi);
+ if (ice_is_forward_action(tc_fltr->action.fltr_act)) {
+ dest_vsi = ice_tc_forward_action(vsi, tc_fltr);
+ if (IS_ERR(dest_vsi))
+ return PTR_ERR(dest_vsi);
+ }
lkups_cnt = ice_tc_count_lkups(flags, headers, tc_fltr);
list = kcalloc(lkups_cnt, sizeof(*list), GFP_ATOMIC);
switch (tc_fltr->action.fltr_act) {
case ICE_FWD_TO_VSI:
- rule_info.sw_act.vsi_handle = ch_vsi->idx;
+ rule_info.sw_act.vsi_handle = dest_vsi->idx;
rule_info.priority = ICE_SWITCH_FLTR_PRIO_VSI;
rule_info.sw_act.src = hw->pf_id;
rule_info.rx = true;
case ICE_FWD_TO_Q:
/* HW queue number in global space */
rule_info.sw_act.fwd_id.q_id = tc_fltr->action.fwd.q.hw_queue;
- rule_info.sw_act.vsi_handle = ch_vsi->idx;
+ rule_info.sw_act.vsi_handle = dest_vsi->idx;
rule_info.priority = ICE_SWITCH_FLTR_PRIO_QUEUE;
rule_info.sw_act.src = hw->pf_id;
rule_info.rx = true;
tc_fltr->action.fwd.q.queue,
tc_fltr->action.fwd.q.hw_queue, lkups_cnt);
break;
- default:
- rule_info.sw_act.flag |= ICE_FLTR_TX;
- /* In case of Tx (LOOKUP_TX), src needs to be src VSI */
- rule_info.sw_act.src = vsi->idx;
- /* 'Rx' is false, direction of rule(LOOKUPTRX) */
- rule_info.rx = false;
+ case ICE_DROP_PACKET:
+ rule_info.sw_act.flag |= ICE_FLTR_RX;
+ rule_info.sw_act.src = hw->pf_id;
+ rule_info.rx = true;
rule_info.priority = ICE_SWITCH_FLTR_PRIO_VSI;
break;
+ default:
+ ret = -EOPNOTSUPP;
+ goto exit;
}
ret = ice_add_adv_rule(hw, list, lkups_cnt, &rule_info, &rule_added);
tc_fltr->dest_vsi_handle = rule_added.vsi_handle;
if (tc_fltr->action.fltr_act == ICE_FWD_TO_VSI ||
tc_fltr->action.fltr_act == ICE_FWD_TO_Q) {
- tc_fltr->dest_vsi = ch_vsi;
+ tc_fltr->dest_vsi = dest_vsi;
/* keep track of advanced switch filter for
* destination VSI
*/
- ch_vsi->num_chnl_fltr++;
+ dest_vsi->num_chnl_fltr++;
/* keeps track of channel filters for PF VSI */
if (vsi->type == ICE_VSI_PF &&
tc_fltr->action.fwd.q.hw_queue, rule_added.rid,
rule_added.rule_id);
break;
+ case ICE_DROP_PACKET:
+ dev_dbg(dev, "added switch rule (lkups_cnt %u, flags 0x%x), action is drop, rid %u, rule_id %u\n",
+ lkups_cnt, flags, rule_added.rid, rule_added.rule_id);
+ break;
default:
break;
}
case FLOW_ACTION_RX_QUEUE_MAPPING:
/* forward to queue */
return ice_tc_forward_to_queue(vsi, fltr, act);
+ case FLOW_ACTION_DROP:
+ fltr->action.fltr_act = ICE_DROP_PACKET;
+ return 0;
default:
NL_SET_ERR_MSG_MOD(fltr->extack, "Unsupported TC action");
return -EOPNOTSUPP;