forked from iqiyi/dpvs
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
single worker rte_flow invalid process bugfix patch
- Loading branch information
huangyichen
committed
Jun 29, 2021
1 parent
5e23cc9
commit 291f4a4
Showing
5 changed files
with
85 additions
and
63 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +1,7 @@ | ||
From fc25cda5bab943feac5455779fb6a6f00ee2a87d Mon Sep 17 00:00:00 2001 | ||
From: wencyu <yuwenchao@qiyi.com> | ||
Date: Thu, 17 Jun 2021 20:39:55 +0800 | ||
Subject: [PATCH 1/5] kni: use netlink event for multicast (driver part) | ||
From db292243dcd6ef371fc6268e54b9ec16116a9d87 Mon Sep 17 00:00:00 2001 | ||
From: huangyichen <huangyichen@qiyi.com> | ||
Date: Tue, 29 Jun 2021 11:19:12 +0800 | ||
Subject: [PATCH 1/5] kni: use netlink event for multicast | ||
|
||
Kni driver sends netlink event every time hw-multicast list updated by | ||
kernel, the user kni app should capture the event and update multicast | ||
|
@@ -10,8 +10,6 @@ to kni device. | |
Original way is using rte_kni_request to pass hw-multicast to user kni | ||
module. That method works but finally memory corruption found, which is | ||
not easy to address. That's why we use netlink event instead. | ||
|
||
Signed-off-by: wencyu <[email protected]> | ||
--- | ||
kernel/linux/kni/kni_net.c | 76 ++++++++++++++++++++++++++++++++++++++++++++++ | ||
1 file changed, 76 insertions(+) | ||
|
@@ -29,15 +27,15 @@ index 4b75208..cde565e 100644 | |
|
||
#include <rte_kni_common.h> | ||
#include <kni_fifo.h> | ||
@@ -128,6 +130,7 @@ | ||
@@ -128,6 +130,7 @@ kni_net_process_request(struct kni_dev *kni, struct rte_kni_request *req) | ||
ret_val = wait_event_interruptible_timeout(kni->wq, | ||
kni_fifo_count(kni->resp_q), 3 * HZ); | ||
if (signal_pending(current) || ret_val <= 0) { | ||
+ pr_err("%s: wait_event_interruptible timeout\n", __func__); | ||
ret = -ETIME; | ||
goto fail; | ||
} | ||
@@ -657,6 +660,77 @@ void kni_net_release_fifo_phy(struct kni_dev *kni) | ||
@@ -657,6 +660,77 @@ kni_net_change_mtu(struct net_device *dev, int new_mtu) | ||
return (ret == 0) ? req.result : ret; | ||
} | ||
|
||
|
@@ -115,15 +113,15 @@ index 4b75208..cde565e 100644 | |
static void | ||
kni_net_change_rx_flags(struct net_device *netdev, int flags) | ||
{ | ||
@@ -757,6 +831,7 @@ void kni_net_release_fifo_phy(struct kni_dev *kni) | ||
@@ -757,6 +831,7 @@ kni_net_set_mac(struct net_device *netdev, void *p) | ||
kni = netdev_priv(netdev); | ||
ret = kni_net_process_request(kni, &req); | ||
|
||
+ pr_info("%s request returns %d!\n", __func__, ret); | ||
return (ret == 0 ? req.result : ret); | ||
} | ||
|
||
@@ -788,6 +863,7 @@ void kni_net_release_fifo_phy(struct kni_dev *kni) | ||
@@ -788,6 +863,7 @@ static const struct net_device_ops kni_net_netdev_ops = { | ||
.ndo_change_rx_flags = kni_net_change_rx_flags, | ||
.ndo_start_xmit = kni_net_tx, | ||
.ndo_change_mtu = kni_net_change_mtu, | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,9 +1,8 @@ | ||
From 6a99af8a3f9067a18211d15b4a65bcafa9430875 Mon Sep 17 00:00:00 2001 | ||
From: wencyu <yuwenchao@qiyi.com> | ||
Date: Fri, 18 Jun 2021 10:20:45 +0800 | ||
Subject: [PATCH 2/5] pdump: change dpdk-pdump tool for dpvs | ||
From fad87988c197755a353f113613d8f3b96be7025a Mon Sep 17 00:00:00 2001 | ||
From: huangyichen <huangyichen@qiyi.com> | ||
Date: Tue, 29 Jun 2021 11:22:43 +0800 | ||
Subject: [PATCH 2/5] change dpdk-pdump tool for dpvs | ||
|
||
Signed-off-by: wencyu <[email protected]> | ||
--- | ||
app/pdump/main.c | 167 ++++++++++++++++++++++++++++++++++++++++--- | ||
lib/librte_pdump/rte_pdump.c | 145 +++++++++++++++++++++++++++++++++++-- | ||
|
@@ -37,7 +36,7 @@ index b34bf33..9d14474 100644 | |
#define VDEV_NAME_FMT "net_pcap_%s_%d" | ||
#define VDEV_PCAP_ARGS_FMT "tx_pcap=%s" | ||
#define VDEV_IFACE_ARGS_FMT "tx_iface=%s" | ||
@@ -97,6 +106,13 @@ enum pdump_by { | ||
@@ -97,6 +106,13 @@ static const char * const valid_pdump_arguments[] = { | ||
PDUMP_RING_SIZE_ARG, | ||
PDUMP_MSIZE_ARG, | ||
PDUMP_NUM_MBUFS_ARG, | ||
|
@@ -59,7 +58,7 @@ index b34bf33..9d14474 100644 | |
|
||
/* stats */ | ||
struct pdump_stats stats; | ||
@@ -158,6 +175,11 @@ struct parse_val { | ||
@@ -158,6 +175,11 @@ pdump_usage(const char *prgname) | ||
"(queue=<queue_id>)," | ||
"(rx-dev=<iface or pcap file> |" | ||
" tx-dev=<iface or pcap file>," | ||
|
@@ -71,7 +70,7 @@ index b34bf33..9d14474 100644 | |
"[ring-size=<ring size>default:16384]," | ||
"[mbuf-size=<mbuf data size>default:2176]," | ||
"[total-num-mbufs=<number of mbufs>default:65535]'\n", | ||
@@ -244,6 +266,64 @@ struct parse_val { | ||
@@ -244,6 +266,64 @@ parse_uint_value(const char *key, const char *value, void *extra_args) | ||
} | ||
|
||
static int | ||
|
@@ -136,7 +135,7 @@ index b34bf33..9d14474 100644 | |
parse_pdump(const char *optarg) | ||
{ | ||
struct rte_kvargs *kvlist; | ||
@@ -370,6 +450,75 @@ struct parse_val { | ||
@@ -370,6 +450,75 @@ parse_pdump(const char *optarg) | ||
} else | ||
pt->total_num_mbufs = MBUFS_PER_POOL; | ||
|
||
|
@@ -212,7 +211,7 @@ index b34bf33..9d14474 100644 | |
num_tuples++; | ||
|
||
free_kvlist: | ||
@@ -510,6 +659,8 @@ struct parse_val { | ||
@@ -510,6 +659,8 @@ cleanup_rings(void) | ||
rte_ring_free(pt->rx_ring); | ||
if (pt->tx_ring) | ||
rte_ring_free(pt->tx_ring); | ||
|
@@ -221,7 +220,7 @@ index b34bf33..9d14474 100644 | |
} | ||
} | ||
|
||
@@ -837,20 +988,20 @@ struct parse_val { | ||
@@ -837,20 +988,20 @@ enable_pdump(void) | ||
pt->queue, | ||
RTE_PDUMP_FLAG_RX, | ||
pt->rx_ring, | ||
|
@@ -246,7 +245,7 @@ index b34bf33..9d14474 100644 | |
} | ||
} else if (pt->dir == RTE_PDUMP_FLAG_RX) { | ||
if (pt->dump_by_type == DEVICE_ID) | ||
@@ -858,22 +1009,22 @@ struct parse_val { | ||
@@ -858,22 +1009,22 @@ enable_pdump(void) | ||
pt->device_id, | ||
pt->queue, | ||
pt->dir, pt->rx_ring, | ||
|
@@ -288,7 +287,7 @@ index b3c8d5c..b73fb8f 100644 | |
|
||
#include "rte_pdump.h" | ||
|
||
@@ -69,6 +73,132 @@ struct pdump_response { | ||
@@ -69,6 +73,132 @@ static struct pdump_rxtx_cbs { | ||
} rx_cbs[RTE_MAX_ETHPORTS][RTE_MAX_QUEUES_PER_PORT], | ||
tx_cbs[RTE_MAX_ETHPORTS][RTE_MAX_QUEUES_PER_PORT]; | ||
|
||
|
@@ -421,7 +420,7 @@ index b3c8d5c..b73fb8f 100644 | |
|
||
static inline void | ||
pdump_copy(struct rte_mbuf **pkts, uint16_t nb_pkts, void *user_params) | ||
@@ -86,6 +216,8 @@ struct pdump_response { | ||
@@ -86,6 +216,8 @@ pdump_copy(struct rte_mbuf **pkts, uint16_t nb_pkts, void *user_params) | ||
ring = cbs->ring; | ||
mp = cbs->mp; | ||
for (i = 0; i < nb_pkts; i++) { | ||
|
@@ -430,7 +429,7 @@ index b3c8d5c..b73fb8f 100644 | |
p = rte_pktmbuf_copy(pkts[i], mp, 0, UINT32_MAX); | ||
if (p) | ||
dup_bufs[d_pkts++] = p; | ||
@@ -122,7 +254,7 @@ struct pdump_response { | ||
@@ -122,7 +254,7 @@ pdump_tx(uint16_t port __rte_unused, uint16_t qidx __rte_unused, | ||
static int | ||
pdump_register_rx_callbacks(uint16_t end_q, uint16_t port, uint16_t queue, | ||
struct rte_ring *ring, struct rte_mempool *mp, | ||
|
@@ -439,15 +438,15 @@ index b3c8d5c..b73fb8f 100644 | |
{ | ||
uint16_t qid; | ||
struct pdump_rxtx_cbs *cbs = NULL; | ||
@@ -140,6 +272,7 @@ struct pdump_response { | ||
@@ -140,6 +272,7 @@ pdump_register_rx_callbacks(uint16_t end_q, uint16_t port, uint16_t queue, | ||
} | ||
cbs->ring = ring; | ||
cbs->mp = mp; | ||
+ cbs->filter = filter; | ||
cbs->cb = rte_eth_add_first_rx_callback(port, qid, | ||
pdump_rx, cbs); | ||
if (cbs->cb == NULL) { | ||
@@ -176,7 +309,7 @@ struct pdump_response { | ||
@@ -176,7 +309,7 @@ pdump_register_rx_callbacks(uint16_t end_q, uint16_t port, uint16_t queue, | ||
static int | ||
pdump_register_tx_callbacks(uint16_t end_q, uint16_t port, uint16_t queue, | ||
struct rte_ring *ring, struct rte_mempool *mp, | ||
|
@@ -456,39 +455,39 @@ index b3c8d5c..b73fb8f 100644 | |
{ | ||
|
||
uint16_t qid; | ||
@@ -195,6 +328,7 @@ struct pdump_response { | ||
@@ -195,6 +328,7 @@ pdump_register_tx_callbacks(uint16_t end_q, uint16_t port, uint16_t queue, | ||
} | ||
cbs->ring = ring; | ||
cbs->mp = mp; | ||
+ cbs->filter = filter; | ||
cbs->cb = rte_eth_add_tx_callback(port, qid, pdump_tx, | ||
cbs); | ||
if (cbs->cb == NULL) { | ||
@@ -238,6 +372,7 @@ struct pdump_response { | ||
@@ -238,6 +372,7 @@ set_pdump_rxtx_cbs(const struct pdump_request *p) | ||
uint16_t operation; | ||
struct rte_ring *ring; | ||
struct rte_mempool *mp; | ||
+ struct pdump_filter *filter; | ||
|
||
flags = p->flags; | ||
operation = p->op; | ||
@@ -253,6 +388,7 @@ struct pdump_response { | ||
@@ -253,6 +388,7 @@ set_pdump_rxtx_cbs(const struct pdump_request *p) | ||
queue = p->data.en_v1.queue; | ||
ring = p->data.en_v1.ring; | ||
mp = p->data.en_v1.mp; | ||
+ filter = p->data.en_v1.filter; | ||
} else { | ||
ret = rte_eth_dev_get_port_by_name(p->data.dis_v1.device, | ||
&port); | ||
@@ -265,6 +401,7 @@ struct pdump_response { | ||
@@ -265,6 +401,7 @@ set_pdump_rxtx_cbs(const struct pdump_request *p) | ||
queue = p->data.dis_v1.queue; | ||
ring = p->data.dis_v1.ring; | ||
mp = p->data.dis_v1.mp; | ||
+ filter = p->data.dis_v1.filter; | ||
} | ||
|
||
/* validation if packet capture is for all queues */ | ||
@@ -303,7 +440,7 @@ struct pdump_response { | ||
@@ -303,7 +440,7 @@ set_pdump_rxtx_cbs(const struct pdump_request *p) | ||
if (flags & RTE_PDUMP_FLAG_RX) { | ||
end_q = (queue == RTE_PDUMP_ALL_QUEUES) ? nb_rx_q : queue + 1; | ||
ret = pdump_register_rx_callbacks(end_q, port, queue, ring, mp, | ||
|
@@ -497,7 +496,7 @@ index b3c8d5c..b73fb8f 100644 | |
if (ret < 0) | ||
return ret; | ||
} | ||
@@ -312,7 +449,7 @@ struct pdump_response { | ||
@@ -312,7 +449,7 @@ set_pdump_rxtx_cbs(const struct pdump_request *p) | ||
if (flags & RTE_PDUMP_FLAG_TX) { | ||
end_q = (queue == RTE_PDUMP_ALL_QUEUES) ? nb_tx_q : queue + 1; | ||
ret = pdump_register_tx_callbacks(end_q, port, queue, ring, mp, | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,15 +1,13 @@ | ||
From 906f4690d1f3cadca260b23fd1c839d12db9e629 Mon Sep 17 00:00:00 2001 | ||
From: wencyu <yuwenchao@qiyi.com> | ||
Date: Fri, 18 Jun 2021 11:43:07 +0800 | ||
From 02aa011332843b7b6b349ffe1845a8e2bb9a1c7f Mon Sep 17 00:00:00 2001 | ||
From: huangyichen <huangyichen@qiyi.com> | ||
Date: Tue, 29 Jun 2021 11:23:44 +0800 | ||
Subject: [PATCH 3/5] [for debug only] enable dpdk eal memory debug | ||
|
||
The patch is used for memory debug. To use the patch, configure meson with option | ||
-Dc_args="-DRTE_MALLOC_DEBUG" when building dpdk. For example, | ||
|
||
meson -Dc_args="-DRTE_MALLOC_DEBUG" -Dbuildtype=debug -Dprefix=$(pwd)/dpdklib dpdkbuild | ||
ninja -C dpdkbuild | ||
|
||
Signed-off-by: wencyu <[email protected]> | ||
--- | ||
lib/librte_eal/common/rte_malloc.c | 4 ++++ | ||
lib/librte_eal/include/rte_malloc.h | 15 +++++++++++++++ | ||
|
@@ -34,7 +32,7 @@ diff --git a/lib/librte_eal/include/rte_malloc.h b/lib/librte_eal/include/rte_ma | |
index 3af64f8..671e4f2 100644 | ||
--- a/lib/librte_eal/include/rte_malloc.h | ||
+++ b/lib/librte_eal/include/rte_malloc.h | ||
@@ -248,6 +248,21 @@ struct rte_malloc_socket_stats { | ||
@@ -248,6 +248,21 @@ rte_calloc_socket(const char *type, size_t num, size_t size, unsigned align, int | ||
__rte_alloc_size(2, 3); | ||
|
||
/** | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,23 +1,52 @@ | ||
From 83ba9cf5e6eb111f8becc1e9c05301fabb40e16b Mon Sep 17 00:00:00 2001 | ||
From: wencyu <yuwenchao@qiyi.com> | ||
Date: Fri, 18 Jun 2021 14:00:24 +0800 | ||
From 9636cd6bd00d8de7dde8ec969647f4afb0343102 Mon Sep 17 00:00:00 2001 | ||
From: huangyichen <huangyichen@qiyi.com> | ||
Date: Tue, 29 Jun 2021 11:27:21 +0800 | ||
Subject: [PATCH 4/5] ixgbe_flow: patch ixgbe fdir rte_flow for dpvs | ||
|
||
1. Ignore fdir flow rule priority attribute. | ||
2. Use different fdir soft-id for flow rules configured for the same queue. | ||
3. Disable fdir mask settings by rte_flow. | ||
4. Allow IPv6 to pass flow rule ETH item validation. | ||
|
||
Signed-off-by: wencyu <[email protected]> | ||
5. TCP & UDP flow item dest port = 0 is invalid of ixgbe_parse_ntuple_filter() | ||
--- | ||
drivers/net/ixgbe/ixgbe_flow.c | 62 ++++++++++++++++++++++++++++++++++-------- | ||
1 file changed, 51 insertions(+), 11 deletions(-) | ||
drivers/net/ixgbe/ixgbe_flow.c | 78 ++++++++++++++++++++++++++++++++++++------ | ||
1 file changed, 67 insertions(+), 11 deletions(-) | ||
|
||
diff --git a/drivers/net/ixgbe/ixgbe_flow.c b/drivers/net/ixgbe/ixgbe_flow.c | ||
index 9aeb2e4..97d5ca0 100644 | ||
index 9aeb2e4..c16ddad 100644 | ||
--- a/drivers/net/ixgbe/ixgbe_flow.c | ||
+++ b/drivers/net/ixgbe/ixgbe_flow.c | ||
@@ -1419,11 +1419,8 @@ const struct rte_flow_action *next_no_void_action( | ||
@@ -468,6 +468,14 @@ cons_parse_ntuple_filter(const struct rte_flow_attr *attr, | ||
} | ||
|
||
tcp_spec = item->spec; | ||
+ if (tcp_spec->hdr.dst_port == 0 && | ||
+ tcp_mask->hdr.dst_port == 0) { | ||
+ memset(filter, 0, sizeof(struct rte_eth_ntuple_filter)); | ||
+ rte_flow_error_set(error, EINVAL, | ||
+ RTE_FLOW_ERROR_TYPE_ITEM, | ||
+ item, "Not supported by ntuple filter"); | ||
+ return -rte_errno; | ||
+ } | ||
filter->dst_port = tcp_spec->hdr.dst_port; | ||
filter->src_port = tcp_spec->hdr.src_port; | ||
filter->tcp_flags = tcp_spec->hdr.tcp_flags; | ||
@@ -501,6 +509,14 @@ cons_parse_ntuple_filter(const struct rte_flow_attr *attr, | ||
filter->src_port_mask = udp_mask->hdr.src_port; | ||
|
||
udp_spec = item->spec; | ||
+ if (udp_spec->hdr.dst_port == 0 && | ||
+ udp_mask->hdr.dst_port == 0) { | ||
+ memset(filter, 0, sizeof(struct rte_eth_ntuple_filter)); | ||
+ rte_flow_error_set(error, EINVAL, | ||
+ RTE_FLOW_ERROR_TYPE_ITEM, | ||
+ item, "Not supported by ntuple filter"); | ||
+ return -rte_errno; | ||
+ } | ||
filter->dst_port = udp_spec->hdr.dst_port; | ||
filter->src_port = udp_spec->hdr.src_port; | ||
} else if (item->type == RTE_FLOW_ITEM_TYPE_SCTP) { | ||
@@ -1419,11 +1435,8 @@ ixgbe_parse_fdir_act_attr(const struct rte_flow_attr *attr, | ||
|
||
/* not supported */ | ||
if (attr->priority) { | ||
|
@@ -31,7 +60,7 @@ index 9aeb2e4..97d5ca0 100644 | |
} | ||
|
||
/* check if the first not void action is QUEUE or DROP. */ | ||
@@ -1642,7 +1639,7 @@ static inline uint8_t signature_match(const struct rte_flow_item pattern[]) | ||
@@ -1642,7 +1655,7 @@ ixgbe_parse_fdir_filter_normal(struct rte_eth_dev *dev, | ||
* value. So, we need not do anything for the not provided fields later. | ||
*/ | ||
memset(rule, 0, sizeof(struct ixgbe_fdir_rule)); | ||
|
@@ -40,7 +69,7 @@ index 9aeb2e4..97d5ca0 100644 | |
rule->mask.vlan_tci_mask = 0; | ||
rule->mask.flex_bytes_mask = 0; | ||
|
||
@@ -1760,6 +1757,8 @@ static inline uint8_t signature_match(const struct rte_flow_item pattern[]) | ||
@@ -1760,6 +1773,8 @@ ixgbe_parse_fdir_filter_normal(struct rte_eth_dev *dev, | ||
} | ||
} else { | ||
if (item->type != RTE_FLOW_ITEM_TYPE_IPV4 && | ||
|
@@ -49,7 +78,7 @@ index 9aeb2e4..97d5ca0 100644 | |
item->type != RTE_FLOW_ITEM_TYPE_VLAN) { | ||
memset(rule, 0, sizeof(struct ixgbe_fdir_rule)); | ||
rte_flow_error_set(error, EINVAL, | ||
@@ -1888,6 +1887,9 @@ static inline uint8_t signature_match(const struct rte_flow_item pattern[]) | ||
@@ -1888,6 +1903,9 @@ ixgbe_parse_fdir_filter_normal(struct rte_eth_dev *dev, | ||
rule->ixgbe_fdir.formatted.flow_type = | ||
IXGBE_ATR_FLOW_TYPE_IPV6; | ||
|
||
|
@@ -59,7 +88,7 @@ index 9aeb2e4..97d5ca0 100644 | |
/** | ||
* 1. must signature match | ||
* 2. not support last | ||
@@ -2748,12 +2750,45 @@ static inline uint8_t signature_match(const struct rte_flow_item pattern[]) | ||
@@ -2748,12 +2766,45 @@ ixgbe_parse_fdir_filter_tunnel(const struct rte_flow_attr *attr, | ||
return ixgbe_parse_fdir_act_attr(attr, actions, rule, error); | ||
} | ||
|
||
|
@@ -106,7 +135,7 @@ index 9aeb2e4..97d5ca0 100644 | |
struct rte_flow_error *error) | ||
{ | ||
int ret; | ||
@@ -2787,13 +2822,18 @@ static inline uint8_t signature_match(const struct rte_flow_item pattern[]) | ||
@@ -2787,13 +2838,18 @@ step_next: | ||
rule->ixgbe_fdir.formatted.dst_port != 0)) | ||
return -ENOTSUP; | ||
|
||
|
@@ -127,7 +156,7 @@ index 9aeb2e4..97d5ca0 100644 | |
return ret; | ||
} | ||
|
||
@@ -3128,7 +3168,7 @@ static inline uint8_t signature_match(const struct rte_flow_item pattern[]) | ||
@@ -3128,7 +3184,7 @@ ixgbe_flow_create(struct rte_eth_dev *dev, | ||
|
||
memset(&fdir_rule, 0, sizeof(struct ixgbe_fdir_rule)); | ||
ret = ixgbe_parse_fdir_filter(dev, attr, pattern, | ||
|
@@ -136,7 +165,7 @@ index 9aeb2e4..97d5ca0 100644 | |
if (!ret) { | ||
/* A mask cannot be deleted. */ | ||
if (fdir_rule.b_mask) { | ||
@@ -3299,7 +3339,7 @@ static inline uint8_t signature_match(const struct rte_flow_item pattern[]) | ||
@@ -3299,7 +3355,7 @@ ixgbe_flow_validate(struct rte_eth_dev *dev, | ||
|
||
memset(&fdir_rule, 0, sizeof(struct ixgbe_fdir_rule)); | ||
ret = ixgbe_parse_fdir_filter(dev, attr, pattern, | ||
|
Oops, something went wrong.