mirror of
https://github.com/torvalds/linux.git
synced 2026-07-27 17:47:41 +02:00
net: hns3: support IP and tunnel VNI dissectors for tc flow
Currently, the driver does not support FLOW_DISSECTOR_KEY_IP and FLOW_DISSECTOR_KEY_ENC_KEYID. But the hardware supports ip_tos (FLOW_DISSECTOR_KEY_IP) and outer_tun_vni (FLOW_DISSECTOR_KEY_ENC_KEYID). This patch adds support for FLOW_DISSECTOR_KEY_IP and FLOW_DISSECTOR_KEY_ENC_KEYID. Additionally, since tc flow cannot effectively support l2_user_def, l3_user_def, and l4_user_def, this patch explicitly sets them to not be used. Signed-off-by: Jijie Shao <shaojijie@huawei.com> Link: https://patch.msgid.link/20260610060618.834987-5-shaojijie@huawei.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
parent
e6703605b4
commit
cc2c4dbb00
|
|
@ -16,7 +16,7 @@
|
|||
#include <linux/crash_dump.h>
|
||||
|
||||
#include <net/rtnetlink.h>
|
||||
|
||||
#include <net/vxlan.h>
|
||||
#include "hclge_cmd.h"
|
||||
#include "hclge_dcb.h"
|
||||
#include "hclge_main.h"
|
||||
|
|
@ -337,7 +337,9 @@ static const struct key_info tuple_key_info[] = {
|
|||
{ OUTER_SRC_PORT, 16, KEY_OPT_LE16, -1, -1 },
|
||||
{ OUTER_DST_PORT, 16, KEY_OPT_LE16, -1, -1 },
|
||||
{ OUTER_L4_RSV, 32, KEY_OPT_LE32, -1, -1 },
|
||||
{ OUTER_TUN_VNI, 24, KEY_OPT_VNI, -1, -1 },
|
||||
{ OUTER_TUN_VNI, 24, KEY_OPT_VNI,
|
||||
offsetof(struct hclge_fd_rule, tuples.outer_tun_vni),
|
||||
offsetof(struct hclge_fd_rule, tuples_mask.outer_tun_vni) },
|
||||
{ OUTER_TUN_FLOW_ID, 8, KEY_OPT_U8, -1, -1 },
|
||||
{ INNER_DST_MAC, 48, KEY_OPT_MAC,
|
||||
offsetof(struct hclge_fd_rule, tuples.dst_mac),
|
||||
|
|
@ -5590,8 +5592,9 @@ static int hclge_init_fd_config(struct hclge_dev *hdev)
|
|||
|
||||
/* If use max 400bit key, we can support tuples for ether type */
|
||||
if (hdev->fd_cfg.fd_mode == HCLGE_FD_MODE_DEPTH_2K_WIDTH_400B_STAGE_1) {
|
||||
key_cfg->tuple_active |=
|
||||
BIT(INNER_DST_MAC) | BIT(INNER_SRC_MAC);
|
||||
key_cfg->tuple_active |= BIT(INNER_DST_MAC) |
|
||||
BIT(INNER_SRC_MAC) |
|
||||
BIT(OUTER_TUN_VNI);
|
||||
if (hdev->ae_dev->dev_version >= HNAE3_DEVICE_VERSION_V3)
|
||||
key_cfg->tuple_active |= HCLGE_FD_TUPLE_USER_DEF_TUPLES;
|
||||
}
|
||||
|
|
@ -5713,6 +5716,7 @@ static bool hclge_fd_convert_tuple(u32 tuple_bit, u8 *key_x, u8 *key_y,
|
|||
u16 tmp_x_s, tmp_y_s;
|
||||
u32 tmp_x_l, tmp_y_l;
|
||||
u8 *p = (u8 *)rule;
|
||||
__le32 le_x, le_y;
|
||||
int i;
|
||||
|
||||
if (rule->unused_tuple & BIT(tuple_bit))
|
||||
|
|
@ -5760,6 +5764,15 @@ static bool hclge_fd_convert_tuple(u32 tuple_bit, u8 *key_x, u8 *key_y,
|
|||
*(__le32 *)key_x = cpu_to_le32(tmp_x_l);
|
||||
*(__le32 *)key_y = cpu_to_le32(tmp_y_l);
|
||||
|
||||
return true;
|
||||
case KEY_OPT_VNI:
|
||||
calc_x(tmp_x_l, *(u32 *)(&p[offset]), *(u32 *)(&p[moffset]));
|
||||
calc_y(tmp_y_l, *(u32 *)(&p[offset]), *(u32 *)(&p[moffset]));
|
||||
le_x = cpu_to_le32(tmp_x_l);
|
||||
le_y = cpu_to_le32(tmp_y_l);
|
||||
memcpy(key_x, &le_x, HCLGE_VNI_LENGTH);
|
||||
memcpy(key_y, &le_y, HCLGE_VNI_LENGTH);
|
||||
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
|
|
@ -7340,6 +7353,62 @@ static void hclge_get_cls_key_port(const struct flow_rule *flow,
|
|||
}
|
||||
}
|
||||
|
||||
static int hclge_get_cls_enc_keyid(struct hclge_dev *hdev,
|
||||
const struct flow_rule *flow,
|
||||
struct hclge_fd_rule *rule,
|
||||
struct netlink_ext_ack *extack)
|
||||
{
|
||||
if (flow_rule_match_key(flow, FLOW_DISSECTOR_KEY_ENC_KEYID)) {
|
||||
struct flow_match_enc_keyid match;
|
||||
|
||||
flow_rule_match_enc_keyid(flow, &match);
|
||||
|
||||
/* vni is only 24 bits and must be greater than 0,
|
||||
* and it can not be masked.
|
||||
*/
|
||||
if (be32_to_cpu(match.mask->keyid) !=
|
||||
HCLGE_FD_VXLAN_VNI_UNMASK ||
|
||||
be32_to_cpu(match.key->keyid) >= VXLAN_N_VID ||
|
||||
!match.key->keyid) {
|
||||
NL_SET_ERR_MSG_MOD(extack, "invalid enc_keyid");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
rule->tuples.outer_tun_vni = be32_to_cpu(match.key->keyid);
|
||||
rule->tuples_mask.outer_tun_vni =
|
||||
be32_to_cpu(match.mask->keyid);
|
||||
} else {
|
||||
rule->unused_tuple |= BIT(OUTER_TUN_VNI);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int hclge_get_cls_key_ip_tos(const struct flow_rule *flow,
|
||||
struct hclge_fd_rule *rule,
|
||||
struct netlink_ext_ack *extack)
|
||||
{
|
||||
if (flow_rule_match_key(flow, FLOW_DISSECTOR_KEY_IP)) {
|
||||
struct flow_match_ip match;
|
||||
|
||||
flow_rule_match_ip(flow, &match);
|
||||
|
||||
if (match.mask->ttl) {
|
||||
NL_SET_ERR_MSG_MOD(extack, "unsupported TTL");
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
rule->tuples.ip_tos = match.key->tos;
|
||||
rule->tuples_mask.ip_tos = match.mask->tos;
|
||||
if (!rule->tuples_mask.ip_tos)
|
||||
rule->unused_tuple |= BIT(INNER_IP_TOS);
|
||||
} else {
|
||||
rule->unused_tuple |= BIT(INNER_IP_TOS);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int hclge_get_tc_flower_action(struct hclge_dev *hdev,
|
||||
struct flow_cls_offload *cls_flower,
|
||||
struct hclge_fd_rule *rule)
|
||||
|
|
@ -7397,6 +7466,9 @@ static int hclge_parse_cls_flower(struct hclge_dev *hdev,
|
|||
struct netlink_ext_ack *extack = cls_flower->common.extack;
|
||||
int ret;
|
||||
|
||||
/* not support any user def tuples */
|
||||
rule->unused_tuple |= HCLGE_FD_TUPLE_USER_DEF_TUPLES;
|
||||
|
||||
hclge_get_cls_key_basic(flow, rule);
|
||||
hclge_get_cls_key_mac(flow, rule);
|
||||
hclge_get_cls_key_vlan(flow, rule);
|
||||
|
|
@ -7406,8 +7478,11 @@ static int hclge_parse_cls_flower(struct hclge_dev *hdev,
|
|||
return ret;
|
||||
|
||||
hclge_get_cls_key_port(flow, rule);
|
||||
ret = hclge_get_cls_key_ip_tos(flow, rule, extack);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return 0;
|
||||
return hclge_get_cls_enc_keyid(hdev, flow, rule, extack);
|
||||
}
|
||||
|
||||
static int hclge_check_cls_flower(struct hclge_dev *hdev,
|
||||
|
|
@ -7439,10 +7514,12 @@ static int hclge_check_cls_flower(struct hclge_dev *hdev,
|
|||
BIT_ULL(FLOW_DISSECTOR_KEY_VLAN) |
|
||||
BIT_ULL(FLOW_DISSECTOR_KEY_IPV4_ADDRS) |
|
||||
BIT_ULL(FLOW_DISSECTOR_KEY_IPV6_ADDRS) |
|
||||
BIT_ULL(FLOW_DISSECTOR_KEY_PORTS);
|
||||
BIT_ULL(FLOW_DISSECTOR_KEY_PORTS) |
|
||||
BIT_ULL(FLOW_DISSECTOR_KEY_IP);
|
||||
|
||||
if (hdev->fd_cfg.fd_mode == HCLGE_FD_MODE_DEPTH_2K_WIDTH_400B_STAGE_1)
|
||||
support_keys |= BIT_ULL(FLOW_DISSECTOR_KEY_ETH_ADDRS);
|
||||
support_keys |= BIT_ULL(FLOW_DISSECTOR_KEY_ETH_ADDRS) |
|
||||
BIT_ULL(FLOW_DISSECTOR_KEY_ENC_KEYID);
|
||||
|
||||
if (dissector->used_keys & ~support_keys) {
|
||||
NL_SET_ERR_MSG_FMT_MOD(extack, "unsupported key set: %#llx",
|
||||
|
|
|
|||
|
|
@ -645,6 +645,9 @@ struct key_info {
|
|||
#define HCLGE_FD_USER_DEF_DATA GENMASK(15, 0)
|
||||
#define HCLGE_FD_USER_DEF_OFFSET GENMASK(15, 0)
|
||||
#define HCLGE_FD_USER_DEF_OFFSET_UNMASK GENMASK(15, 0)
|
||||
#define HCLGE_FD_VXLAN_VNI_UNMASK GENMASK(31, 0)
|
||||
|
||||
#define HCLGE_VNI_LENGTH 3
|
||||
|
||||
/* assigned by firmware, the real filter number for each pf may be less */
|
||||
#define MAX_FD_FILTER_NUM 4096
|
||||
|
|
@ -738,6 +741,7 @@ struct hclge_fd_rule_tuples {
|
|||
u32 l4_user_def;
|
||||
u8 ip_tos;
|
||||
u8 ip_proto;
|
||||
u32 outer_tun_vni;
|
||||
};
|
||||
|
||||
struct hclge_fd_rule {
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user