未验证 提交 b683f7f9 编写于 作者: O openeuler-ci-bot 提交者: Gitee

!276 support set/get VxLAN rule of rx flow director by ethtool

Merge Pull Request from: @svishen 
 
Background:
Currently, the HNS3 driver, Linux kernel, and standard tools do not support the configuration of VXLAN tunnel tuple information as the key of the flow table. The ethtool –U command supports only the configuration of tuples for non-tunnel packets. Two types of tuples, vxlan4 and vxlan6, need to be added.

Functions:
The vxlan4 and vxlan6 flow types are added to the ethtool –U command. The vni in the outer header and the source MAC address, destination MAC address, source IP address, destination IP address, and VLAN ID in the inner header can be configured as tuple information. The HNS3 driver supports all tuple configurations of both types.

patch name:
(1) net: ethtool: add VxLAN to the NFC API
(2) net: hns3: support set/get VxLAN rule of rx flow director by ethtool


In include/uapi/linux/ethtool.h
We changed a union, but didn't change its size.Neither of the two newly added members exceeds 52 bytes.

The impact on user-mode tools is as follows:
(1)The new tool is compiled on the old kernel and can configure the old flow table. The old kernel does not support VXLAN configuration.

```
[root@locaLhost ~]#
[root@localhost alt rpm -ga | grep ethtool
ethtool-5.15-4.aarch64
[root@localhost ~]#
[root@localhost ~]# uname -a
Linux localhost.localdomain 5.10.0-60.18.0.50.0e2203.aarch64 #1 SMP Wed Mar 30 02:43:08 UTC 2022 aarch64 aarch64 aarch64 GNU/Linux
[root@localhost ~]#
[root@localhost ~]# ethtool -U enol flow-type tep6 tclass Oxi8 src-ip fese::218:2dff:feee:12 loc 4 action -1
[root@localhost ~]# ethtool -u
ethtool: bad command line argument(s)
For more information run ethtool -h
[root@localhost ~]# ethtool -u eno1
32 RX rings available
Total 1 rules
Filter: 4
Rule Type: TCP over IPv6
Src IP addr: fe80::218:2dff:fe00:12 mask: :
Dest Ip addr: :: mask: ffff:ffff:fff:ffff:ffff:ffff:ffff:ffff
Traffic class: 0x18 mask: 0x0
Src port: 0 mask: Oxffff
Dest'port: 0 mask: 0xffff
Action: Drop
[root@localhost ~]# ethtool -U enol flow-type udp4 src-ip 1.1.1.1 vf @ loc 4 queue 2
[root@localhost ~]# ethtool -u enot
32 RX rings available
Total 1 rules
Filter: 4
Rule Type: UDP over IPv4
Src IP addr: 1.1.1.1 mask: 0.0.0.0
Dest IP addr: 0.0.0.0 mask: 255.255.255.255
TOS: 0x0 mask: Oxff
Src port: 0 mask: oxffff
Dest'port: 0 mask: 0xffff
Action: Direct to VF 0 queue 2
[root@localhost ~]# ethtool -U enol flow-type vxlan src-ip 192.168.1.2 loc 4
Add rule, invalid syntax
ethtool: bad command line argument(s)
For more information run ethtool -h
[root@localhost ~]#

```


(2)The old tool is deployed on the new kernel and can configure the old flow table.

```
[root@localhost aarch64]# uname -a
inux (none) 5.106.0+ #1 SMP Thu Nov 24 21:25:01 CST 2022 aarch64 GNU/Linux
[root@localhost aarch64]#
[root@localhost aarch64]# ethtool --version
sthtool version 5.10
[root@localhost aarch64]#
-oot@fpga: /root# ethtool -U eth1 flow-type tcp4 src-ip 192.168.49.30 action 3 loc 4
[root@localhost aarch64]# /root#
[root@localhost aarch64]# ethtool -u etht
1 RX rings_ available
Total 1 rules
-ilter: 4
Rule Type: TCP over IPv4
Src IP addr: 192.168.40.30 mask: 0.0.0.0
Dest IP addr: 0.0.0.0 mask: 255.255.255.255
TOS: 0x0 mask: 0xff
Src port: 0 mask: oxffff
Dest port: 0 mask: Oxffff
Action: Direct to queue 3
[root@localhost aarch64]# ethtool -U eth1 delete 4
[root@localhost aarch64]# ethtool -u eth1
4 RX rings_available
Total @ rules
[root@localhost aarch64]#
```


(3)The VXLAN flow table is successfully configured using the new kernel and tool.

```
[root@localhost aarch64]# ip Link add vxlan® type vxlan id 100 local 192.168.1.2 remote 192.168.1.3 dstport 4789 dev eno1
[root@localhost aarch64]# ethtool -u enol
32 RX rings available
Total 1 rules
Filter: 511
Rule Type: Vxlan IPv4
Vni:  100 mask: 0x0
Src MAC addr: 00:00:00:00:00:00 mask: FF:FF:FF:FF:FF:FF
Dest MAC addr: 00:00:00:00:00:00 mask: FF:FF:FF:FF:FF:FF
Ethertype: 0x0 mask: OxFFFF
Src IP addr: 0.0.0.0 mask: 255.255.255.255
Dest IP addr: 192.168.1.3 mask: 0.0.0.0
TOS: 0x0 mask: Oxff
L4 protocol: © mask: Oxff
Action: Direct to queue 0
[root@localhost aarch64]#
[root@localhost aarch64]# ethtool -N eno1 delete 511
[root@localhost aarch64]# ethtool -u eno1
52 Rx rings available
Total o rdles
[root@localhost aarch64]#
[root@localhost aarch64]# ethtool -U eno1 flow-type vxlan4 vni 100 dst-ip 192.168.1.3
Added rule with ID 511
[root@localhost aarch64]# ethtool -u enot
52 Rx rings available
Total 1 rules
Filter: 511
Rule Type: Vxlan IPv4
Vni:  100 mask: 0x0
Src MAC addr: 00:00:00:00:00:00 mask: FF:FF:FF:FF:FF:FF
Dest MAC addr: 00:00:00:00:00:00 mask: FF:FF:FF:FF:FF:FF
Ethertype: 0x0 mask: 0xFFFF
Src IP addr: 0.0.0.0 mask: 255.255.255.255
Dest IP addr: 192.168.1.3 mask: 0.0.0.0
TOS: 0x0 mask: oxff
L4 protocol: © mask: Oxff
Action: Direct to queue 0
[root@localhost aarch64]# uname -a
Linux localhost.localdomain 5.10.0+ #10 SMP Fri Nov 25 14:12:36 CST 2022 aarch64 aarch64 aarch64 GNU/Linux
[root@localhost aarch64]# ethtool --version
ethtool version 5.15
```

 
 
Link:https://gitee.com/openeuler/kernel/pulls/276 
Reviewed-by: Yue Haibing <yuehaibing@huawei.com> 
Signed-off-by: Xie XiuQi <xiexiuqi@huawei.com> 
......@@ -15,6 +15,7 @@
#include <linux/crash_dump.h>
#include <net/ipv6.h>
#include <net/rtnetlink.h>
#include <net/vxlan.h>
#include "hclge_cmd.h"
#include "hclge_dcb.h"
#include "hclge_main.h"
......@@ -431,7 +432,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),
......@@ -5492,8 +5495,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;
}
......@@ -5605,6 +5609,8 @@ static int hclge_fd_ad_config(struct hclge_dev *hdev, u8 stage, int loc,
static bool hclge_fd_convert_tuple(u32 tuple_bit, u8 *key_x, u8 *key_y,
struct hclge_fd_rule *rule)
{
#define HCLGE_VNI_LENGTH 3
int offset, moffset, ip_offset;
enum HCLGE_FD_KEY_OPT key_opt;
u16 tmp_x_s, tmp_y_s;
......@@ -5657,6 +5663,14 @@ 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]));
for (i = 0; i < HCLGE_VNI_LENGTH; i++) {
key_x[i] = (cpu_to_le32(tmp_x_l) >> (i * BITS_PER_BYTE)) & 0xFF;
key_y[i] = (cpu_to_le32(tmp_y_l) >> (i * BITS_PER_BYTE)) & 0xFF;
}
return true;
default:
return false;
......@@ -5879,6 +5893,45 @@ static int hclge_fd_check_ip4_tuple(struct ethtool_usrip4_spec *spec,
return 0;
}
static int hclge_fd_check_vxlan4_tuple(struct ethtool_rx_flow_spec *fs,
u32 *unused_tuple)
{
struct ethtool_vxlan4_spec *spec = &fs->h_u.vxlan_ip4_spec;
struct ethtool_vxlan4_spec *mask = &fs->m_u.vxlan_ip4_spec;
/* Vni is only 24 bits and must be greater than 0, and it can not be
* masked.
*/
if (!spec->vni || be32_to_cpu(spec->vni) >= VXLAN_N_VID ||
mask->vni != HCLGE_FD_VXLAN_VNI_UNMASK || !unused_tuple)
return -EINVAL;
*unused_tuple |= BIT(INNER_SRC_PORT) | BIT(INNER_DST_PORT);
if (is_zero_ether_addr(spec->src))
*unused_tuple |= BIT(INNER_SRC_MAC);
if (is_zero_ether_addr(spec->dst))
*unused_tuple |= BIT(INNER_DST_MAC);
if (!spec->eth_type)
*unused_tuple |= BIT(INNER_ETH_TYPE);
if (!spec->ip4src)
*unused_tuple |= BIT(INNER_SRC_IP);
if (!spec->ip4dst)
*unused_tuple |= BIT(INNER_DST_IP);
if (!spec->tos)
*unused_tuple |= BIT(INNER_IP_TOS);
if (!spec->l4_proto)
*unused_tuple |= BIT(INNER_IP_PROTO);
return 0;
}
static int hclge_fd_check_tcpip6_tuple(struct ethtool_tcpip6_spec *spec,
u32 *unused_tuple)
{
......@@ -5934,6 +5987,45 @@ static int hclge_fd_check_ip6_tuple(struct ethtool_usrip6_spec *spec,
return 0;
}
static int hclge_fd_check_vxlan6_tuple(struct ethtool_rx_flow_spec *fs,
u32 *unused_tuple)
{
struct ethtool_vxlan6_spec *spec = &fs->h_u.vxlan_ip6_spec;
struct ethtool_vxlan6_spec *mask = &fs->m_u.vxlan_ip6_spec;
/* Vni is only 24 bits and must be greater than 0, and it can not be
* masked.
*/
if (!spec->vni || be32_to_cpu(spec->vni) >= VXLAN_N_VID ||
mask->vni != HCLGE_FD_VXLAN_VNI_UNMASK || !unused_tuple)
return -EINVAL;
*unused_tuple |= BIT(INNER_SRC_PORT) | BIT(INNER_DST_PORT);
if (is_zero_ether_addr(spec->src))
*unused_tuple |= BIT(INNER_SRC_MAC);
if (is_zero_ether_addr(spec->dst))
*unused_tuple |= BIT(INNER_DST_MAC);
if (!spec->eth_type)
*unused_tuple |= BIT(INNER_ETH_TYPE);
if (ipv6_addr_any((struct in6_addr *)spec->ip6src))
*unused_tuple |= BIT(INNER_SRC_IP);
if (ipv6_addr_any((struct in6_addr *)spec->ip6dst))
*unused_tuple |= BIT(INNER_DST_IP);
if (!spec->tclass)
*unused_tuple |= BIT(INNER_IP_TOS);
if (!spec->l4_proto)
*unused_tuple |= BIT(INNER_IP_PROTO);
return 0;
}
static int hclge_fd_check_ether_tuple(struct ethhdr *spec, u32 *unused_tuple)
{
if (!spec || !unused_tuple)
......@@ -6116,6 +6208,9 @@ static int hclge_fd_check_spec(struct hclge_dev *hdev,
ret = hclge_fd_check_ip4_tuple(&fs->h_u.usr_ip4_spec,
unused_tuple);
break;
case VXLAN_V4_FLOW:
ret = hclge_fd_check_vxlan4_tuple(fs, unused_tuple);
break;
case SCTP_V6_FLOW:
case TCP_V6_FLOW:
case UDP_V6_FLOW:
......@@ -6126,6 +6221,9 @@ static int hclge_fd_check_spec(struct hclge_dev *hdev,
ret = hclge_fd_check_ip6_tuple(&fs->h_u.usr_ip6_spec,
unused_tuple);
break;
case VXLAN_V6_FLOW:
ret = hclge_fd_check_vxlan6_tuple(fs, unused_tuple);
break;
case ETHER_FLOW:
if (hdev->fd_cfg.fd_mode !=
HCLGE_FD_MODE_DEPTH_2K_WIDTH_400B_STAGE_1) {
......@@ -6208,6 +6306,37 @@ static void hclge_fd_get_ip4_tuple(struct hclge_dev *hdev,
rule->tuples_mask.ether_proto = 0xFFFF;
}
static void hclge_fd_get_vxlan4_tuple(struct ethtool_rx_flow_spec *fs,
struct hclge_fd_rule *rule)
{
struct ethtool_vxlan4_spec *h = &fs->h_u.vxlan_ip4_spec;
struct ethtool_vxlan4_spec *m = &fs->m_u.vxlan_ip4_spec;
rule->tuples.outer_tun_vni = be32_to_cpu(h->vni);
rule->tuples_mask.outer_tun_vni = be32_to_cpu(m->vni);
ether_addr_copy(rule->tuples.src_mac, h->src);
ether_addr_copy(rule->tuples_mask.src_mac, m->src);
ether_addr_copy(rule->tuples.dst_mac, h->dst);
ether_addr_copy(rule->tuples_mask.dst_mac, m->dst);
rule->tuples.ether_proto = be16_to_cpu(h->eth_type);
rule->tuples_mask.ether_proto = be16_to_cpu(m->eth_type);
rule->tuples.ip_tos = h->tos;
rule->tuples_mask.ip_tos = m->tos;
rule->tuples.ip_proto = h->l4_proto;
rule->tuples_mask.ip_proto = m->l4_proto;
rule->tuples.src_ip[IPV4_INDEX] = be32_to_cpu(h->ip4src);
rule->tuples_mask.src_ip[IPV4_INDEX] = be32_to_cpu(m->ip4src);
rule->tuples.dst_ip[IPV4_INDEX] = be32_to_cpu(h->ip4dst);
rule->tuples_mask.dst_ip[IPV4_INDEX] = be32_to_cpu(m->ip4dst);
}
static void hclge_fd_get_tcpip6_tuple(struct hclge_dev *hdev,
struct ethtool_rx_flow_spec *fs,
struct hclge_fd_rule *rule, u8 ip_proto)
......@@ -6262,6 +6391,37 @@ static void hclge_fd_get_ip6_tuple(struct hclge_dev *hdev,
rule->tuples_mask.ether_proto = 0xFFFF;
}
static void hclge_fd_get_vxlan6_tuple(struct ethtool_rx_flow_spec *fs,
struct hclge_fd_rule *rule)
{
struct ethtool_vxlan6_spec *h = &fs->h_u.vxlan_ip6_spec;
struct ethtool_vxlan6_spec *m = &fs->m_u.vxlan_ip6_spec;
rule->tuples.outer_tun_vni = be32_to_cpu(h->vni);
rule->tuples_mask.outer_tun_vni = be32_to_cpu(m->vni);
ether_addr_copy(rule->tuples.src_mac, h->src);
ether_addr_copy(rule->tuples_mask.src_mac, m->src);
ether_addr_copy(rule->tuples.dst_mac, h->dst);
ether_addr_copy(rule->tuples_mask.dst_mac, m->dst);
rule->tuples.ether_proto = be16_to_cpu(h->eth_type);
rule->tuples_mask.ether_proto = be16_to_cpu(m->eth_type);
rule->tuples.ip_tos = h->tclass;
rule->tuples_mask.ip_tos = m->tclass;
rule->tuples.ip_proto = h->l4_proto;
rule->tuples_mask.ip_proto = m->l4_proto;
be32_to_cpu_array(rule->tuples.src_ip, h->ip6src, IPV6_SIZE);
be32_to_cpu_array(rule->tuples_mask.src_ip, m->ip6src, IPV6_SIZE);
be32_to_cpu_array(rule->tuples.dst_ip, h->ip6dst, IPV6_SIZE);
be32_to_cpu_array(rule->tuples_mask.dst_ip, m->ip6dst, IPV6_SIZE);
}
static void hclge_fd_get_ether_tuple(struct hclge_dev *hdev,
struct ethtool_rx_flow_spec *fs,
struct hclge_fd_rule *rule)
......@@ -6319,6 +6479,9 @@ static int hclge_fd_get_tuple(struct hclge_dev *hdev,
case IP_USER_FLOW:
hclge_fd_get_ip4_tuple(hdev, fs, rule);
break;
case VXLAN_V4_FLOW:
hclge_fd_get_vxlan4_tuple(fs, rule);
break;
case SCTP_V6_FLOW:
hclge_fd_get_tcpip6_tuple(hdev, fs, rule, IPPROTO_SCTP);
break;
......@@ -6331,6 +6494,9 @@ static int hclge_fd_get_tuple(struct hclge_dev *hdev,
case IPV6_USER_FLOW:
hclge_fd_get_ip6_tuple(hdev, fs, rule);
break;
case VXLAN_V6_FLOW:
hclge_fd_get_vxlan6_tuple(fs, rule);
break;
case ETHER_FLOW:
hclge_fd_get_ether_tuple(hdev, fs, rule);
break;
......@@ -6677,6 +6843,48 @@ static void hclge_fd_get_ip4_info(struct hclge_fd_rule *rule,
spec->ip_ver = ETH_RX_NFC_IP4;
}
static void hclge_fd_get_vxlan4_info(struct hclge_fd_rule *rule,
struct ethtool_vxlan4_spec *spec,
struct ethtool_vxlan4_spec *spec_mask)
{
spec->vni = cpu_to_be32(rule->tuples.outer_tun_vni);
spec_mask->vni = rule->unused_tuple & BIT(OUTER_TUN_VNI) ? 0 :
cpu_to_be32(rule->tuples_mask.outer_tun_vni);
ether_addr_copy(spec->src, rule->tuples.src_mac);
ether_addr_copy(spec->dst, rule->tuples.dst_mac);
if (rule->unused_tuple & BIT(INNER_SRC_MAC))
eth_zero_addr(spec_mask->src);
else
ether_addr_copy(spec_mask->src, rule->tuples_mask.src_mac);
if (rule->unused_tuple & BIT(INNER_DST_MAC))
eth_zero_addr(spec_mask->dst);
else
ether_addr_copy(spec_mask->dst, rule->tuples_mask.dst_mac);
spec->eth_type = cpu_to_be16(rule->tuples.ether_proto);
spec_mask->eth_type = rule->unused_tuple & BIT(INNER_ETH_TYPE) ? 0 :
cpu_to_be16(rule->tuples_mask.ether_proto);
spec->tos = rule->tuples.ip_tos;
spec_mask->tos = rule->unused_tuple & BIT(INNER_IP_TOS) ? 0 :
rule->tuples_mask.ip_tos;
spec->l4_proto = rule->tuples.ip_proto;
spec_mask->l4_proto = rule->unused_tuple & BIT(INNER_IP_PROTO) ? 0 :
rule->tuples_mask.ip_proto;
spec->ip4src = cpu_to_be32(rule->tuples.src_ip[IPV4_INDEX]);
spec_mask->ip4src = rule->unused_tuple & BIT(INNER_SRC_IP) ? 0 :
cpu_to_be32(rule->tuples_mask.src_ip[IPV4_INDEX]);
spec->ip4dst = cpu_to_be32(rule->tuples.dst_ip[IPV4_INDEX]);
spec_mask->ip4dst = rule->unused_tuple & BIT(INNER_DST_IP) ? 0 :
cpu_to_be32(rule->tuples_mask.dst_ip[IPV4_INDEX]);
}
static void hclge_fd_get_tcpip6_info(struct hclge_fd_rule *rule,
struct ethtool_tcpip6_spec *spec,
struct ethtool_tcpip6_spec *spec_mask)
......@@ -6737,6 +6945,56 @@ static void hclge_fd_get_ip6_info(struct hclge_fd_rule *rule,
0 : rule->tuples_mask.ip_proto;
}
static void hclge_fd_get_vxlan6_info(struct hclge_fd_rule *rule,
struct ethtool_vxlan6_spec *spec,
struct ethtool_vxlan6_spec *spec_mask)
{
spec->vni = cpu_to_be32(rule->tuples.outer_tun_vni);
spec_mask->vni = rule->unused_tuple & BIT(OUTER_TUN_VNI) ? 0 :
cpu_to_be32(rule->tuples_mask.outer_tun_vni);
ether_addr_copy(spec->src, rule->tuples.src_mac);
ether_addr_copy(spec->dst, rule->tuples.dst_mac);
if (rule->unused_tuple & BIT(INNER_SRC_MAC))
eth_zero_addr(spec_mask->src);
else
ether_addr_copy(spec_mask->src, rule->tuples_mask.src_mac);
if (rule->unused_tuple & BIT(INNER_DST_MAC))
eth_zero_addr(spec_mask->dst);
else
ether_addr_copy(spec_mask->dst, rule->tuples_mask.dst_mac);
spec->eth_type = cpu_to_be16(rule->tuples.ether_proto);
spec_mask->eth_type = rule->unused_tuple & BIT(INNER_ETH_TYPE) ? 0 :
cpu_to_be16(rule->tuples_mask.ether_proto);
spec->tclass = rule->tuples.ip_tos;
spec_mask->tclass = rule->unused_tuple & BIT(INNER_IP_TOS) ? 0 :
rule->tuples_mask.ip_tos;
spec->l4_proto = rule->tuples.ip_proto;
spec_mask->l4_proto = rule->unused_tuple & BIT(INNER_IP_PROTO) ? 0 :
rule->tuples_mask.ip_proto;
cpu_to_be32_array(spec->ip6src,
rule->tuples.src_ip, IPV6_SIZE);
cpu_to_be32_array(spec->ip6dst,
rule->tuples.dst_ip, IPV6_SIZE);
if (rule->unused_tuple & BIT(INNER_SRC_IP))
memset(spec_mask->ip6src, 0, sizeof(spec_mask->ip6src));
else
cpu_to_be32_array(spec_mask->ip6src, rule->tuples_mask.src_ip,
IPV6_SIZE);
if (rule->unused_tuple & BIT(INNER_DST_IP))
memset(spec_mask->ip6dst, 0, sizeof(spec_mask->ip6dst));
else
cpu_to_be32_array(spec_mask->ip6dst, rule->tuples_mask.dst_ip,
IPV6_SIZE);
}
static void hclge_fd_get_ether_info(struct hclge_fd_rule *rule,
struct ethhdr *spec,
struct ethhdr *spec_mask)
......@@ -6863,6 +7121,10 @@ static int hclge_get_fd_rule_info(struct hnae3_handle *handle,
hclge_fd_get_ip4_info(rule, &fs->h_u.usr_ip4_spec,
&fs->m_u.usr_ip4_spec);
break;
case VXLAN_V4_FLOW:
hclge_fd_get_vxlan4_info(rule, &fs->h_u.vxlan_ip4_spec,
&fs->m_u.vxlan_ip4_spec);
break;
case SCTP_V6_FLOW:
case TCP_V6_FLOW:
case UDP_V6_FLOW:
......@@ -6873,6 +7135,10 @@ static int hclge_get_fd_rule_info(struct hnae3_handle *handle,
hclge_fd_get_ip6_info(rule, &fs->h_u.usr_ip6_spec,
&fs->m_u.usr_ip6_spec);
break;
case VXLAN_V6_FLOW:
hclge_fd_get_vxlan6_info(rule, &fs->h_u.vxlan_ip6_spec,
&fs->m_u.vxlan_ip6_spec);
break;
/* The flow type of fd rule has been checked before adding in to rule
* list. As other flow types have been handled, it must be ETHER_FLOW
* for the default case
......
......@@ -595,6 +595,7 @@ 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)
/* assigned by firmware, the real filter number for each pf may be less */
#define MAX_FD_FILTER_NUM 4096
......@@ -688,6 +689,7 @@ struct hclge_fd_rule_tuples {
u32 l4_user_def;
u8 ip_tos;
u8 ip_proto;
u32 outer_tun_vni;
};
struct hclge_fd_rule {
......
......@@ -889,6 +889,28 @@ struct ethtool_usrip4_spec {
__u8 proto;
};
/**
* struct ethtool_vxlan4_spec - general flow specification for VxLAN IPv4
* @vni: VxLAN network identifier
* @dst: Inner destination eth addr
* @src: Inner source eth addr
* @eth_type: Inner ethernet type
* @tos: Inner type-of-service
* @l4_proto: Inner transport protocol number
* @ip4src: Inner source host
* @ip4dst: Inner destination host
*/
struct ethtool_vxlan4_spec {
__be32 vni;
__u8 dst[ETH_ALEN];
__u8 src[ETH_ALEN];
__be16 eth_type;
__u8 tos;
__u8 l4_proto;
__be32 ip4src;
__be32 ip4dst;
};
/**
* struct ethtool_tcpip6_spec - flow specification for TCP/IPv6 etc.
* @ip6src: Source host
......@@ -939,6 +961,28 @@ struct ethtool_usrip6_spec {
__u8 l4_proto;
};
/**
* struct ethtool_vxlan6_spec - general flow specification for VxLAN IPv6
* @vni: VxLAN network identifier
* @dst: Inner destination eth addr
* @src: Inner source eth addr
* @eth_type: Inner ethernet type
* @tclass: Inner traffic Class
* @l4_proto: Inner transport protocol number
* @ip6src: Inner source host
* @ip6dst: Inner destination host
*/
struct ethtool_vxlan6_spec {
__be32 vni;
__u8 dst[ETH_ALEN];
__u8 src[ETH_ALEN];
__be16 eth_type;
__u8 tclass;
__u8 l4_proto;
__be32 ip6src[4];
__be32 ip6dst[4];
};
union ethtool_flow_union {
struct ethtool_tcpip4_spec tcp_ip4_spec;
struct ethtool_tcpip4_spec udp_ip4_spec;
......@@ -954,6 +998,10 @@ union ethtool_flow_union {
struct ethtool_usrip6_spec usr_ip6_spec;
struct ethhdr ether_spec;
__u8 hdata[52];
#ifndef __GENKSYMS__
struct ethtool_vxlan4_spec vxlan_ip4_spec;
struct ethtool_vxlan6_spec vxlan_ip6_spec;
#endif
};
/**
......@@ -1830,6 +1878,8 @@ static inline int ethtool_validate_duplex(__u8 duplex)
#define IPV4_FLOW 0x10 /* hash only */
#define IPV6_FLOW 0x11 /* hash only */
#define ETHER_FLOW 0x12 /* spec only (ether_spec) */
#define VXLAN_V4_FLOW 0x43 /* spec only (vxlan_ip4_spec) */
#define VXLAN_V6_FLOW 0x44 /* spec only (vxlan_ip6_spec) */
/* Flag to enable additional fields in struct ethtool_rx_flow_spec */
#define FLOW_EXT 0x80000000
#define FLOW_MAC_EXT 0x40000000
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册