diff options
| author | Jijie Shao <shaojijie@huawei.com> | 2026-06-10 09:06:15 +0300 |
|---|---|---|
| committer | Jakub Kicinski <kuba@kernel.org> | 2026-06-14 03:56:18 +0300 |
| commit | e6703605b47edbb03f60eaf0cc329fe789f8bd62 (patch) | |
| tree | 2c590e59bfe9e4231d843918557195e4cb782834 /drivers | |
| parent | 1ad6f1ff3e96c7ee888475740c8acdaf822e0813 (diff) | |
| download | linux-e6703605b47edbb03f60eaf0cc329fe789f8bd62.tar.xz | |
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>
Diffstat (limited to 'drivers')
| -rw-r--r-- | drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c | 63 |
1 files changed, 56 insertions, 7 deletions
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c index 176ea5aac8aa..ed7cd0a0d267 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c @@ -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; } |
