net: hns3: support two more actions for tc flow

Currently, the driver supports only one action:HCLGE_FD_ACTION_SELECT_TC.

This patch adds support for HCLGE_FD_ACTION_SELECT_QUEUE and
HCLGE_FD_ACTION_DROP_PACKET.

A rule can have only one action. Therefore, the driver intercepts rules
that have multiple actions or no action.

Note: The driver considers cls_flower->classid as an action:
HCLGE_FD_ACTION_SELECT_TC.

Signed-off-by: Jijie Shao <shaojijie@huawei.com>
Link: https://patch.msgid.link/20260610060618.834987-4-shaojijie@huawei.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
Jijie Shao 2026-06-10 14:06:15 +08:00 committed by Jakub Kicinski
parent 1ad6f1ff3e
commit e6703605b4

View File

@ -7344,19 +7344,49 @@ static int hclge_get_tc_flower_action(struct hclge_dev *hdev,
struct flow_cls_offload *cls_flower,
struct hclge_fd_rule *rule)
{
struct flow_rule *flow = flow_cls_offload_flow_rule(cls_flower);
struct netlink_ext_ack *extack = cls_flower->common.extack;
struct hnae3_handle *handle = &hdev->vport[0].nic;
struct flow_action *action = &flow->action;
struct flow_action_entry *act;
int tc;
tc = tc_classid_to_hwtc(handle->netdev, cls_flower->classid);
if (tc < 0 || tc > hdev->tc_max) {
NL_SET_ERR_MSG_FMT_MOD(extack, "invalid traffic class: %d", tc);
return -EINVAL;
if (!flow_action_has_entries(&flow->action)) {
tc = tc_classid_to_hwtc(handle->netdev, cls_flower->classid);
if (tc < 0 || tc > hdev->tc_max) {
NL_SET_ERR_MSG_FMT_MOD(extack,
"invalid traffic class: %d",
tc);
return -EINVAL;
}
rule->action = HCLGE_FD_ACTION_SELECT_TC;
rule->cls_flower.tc = tc;
return 0;
}
rule->action = HCLGE_FD_ACTION_SELECT_TC;
rule->cls_flower.tc = tc;
return 0;
act = &action->entries[0];
switch (act->id) {
case FLOW_ACTION_RX_QUEUE_MAPPING:
if (act->rx_queue >= handle->kinfo.num_tqps) {
NL_SET_ERR_MSG_FMT_MOD(extack,
"queue id (%u) should be less than %u",
act->rx_queue,
handle->kinfo.num_tqps);
return -EINVAL;
}
rule->queue_id = act->rx_queue;
rule->action = HCLGE_FD_ACTION_SELECT_QUEUE;
return 0;
case FLOW_ACTION_DROP:
rule->action = HCLGE_FD_ACTION_DROP_PACKET;
return 0;
default:
NL_SET_ERR_MSG_FMT_MOD(extack,
"unsupported action(%d)", act->id);
return -EOPNOTSUPP;
}
}
static int hclge_parse_cls_flower(struct hclge_dev *hdev,
@ -7420,6 +7450,25 @@ static int hclge_check_cls_flower(struct hclge_dev *hdev,
return -EOPNOTSUPP;
}
/* driver will parses classid into an action */
if (cls_flower->classid && flow_action_has_entries(&flow->action)) {
NL_SET_ERR_MSG_MOD(extack,
"cannot specify both classid and action");
return -EOPNOTSUPP;
}
if (!flow_action_has_entries(&flow->action) && !cls_flower->classid) {
NL_SET_ERR_MSG_MOD(extack,
"must specify either classid or action");
return -EINVAL;
}
if (flow_action_has_entries(&flow->action) &&
!flow_offload_has_one_action(&flow->action)) {
NL_SET_ERR_MSG_MOD(extack, "unsupported multiple actions");
return -EOPNOTSUPP;
}
return 0;
}