blob: 61ed8e5e2095e7b88f0704fe550cfd0bd3d06a55 [file] [log] [blame]
Chenmin Sun7f837382020-03-28 00:34:19 +08001From 0692e4be875c64c5d26f2e6df80bbb1a24df36a6 Mon Sep 17 00:00:00 2001
2From: Chenmin Sun <chenmin.sun@intel.com>
3Date: Fri, 17 Apr 2020 05:02:22 +0800
4Subject: [DPDK 15/17] net/iavf: support generic flow
5
6This patch added iavf_flow_create, iavf_flow_destroy,
7iavf_flow_flush and iavf_flow_validate support,
8these are used to handle all the generic filters.
9
10This patch supported basic L2, L3, L4 and GTPU patterns.
11
12Signed-off-by: Qiming Yang <qiming.yang@intel.com>
13Acked-by: Qi Zhang <qi.z.zhang@intel.com>
14Signed-off-by: Chenmin Sun <chenmin.sun@intel.com>
15---
16 doc/guides/nics/features/iavf.ini | 1 +
17 drivers/net/iavf/Makefile | 1 +
18 drivers/net/iavf/iavf.h | 10 +
19 drivers/net/iavf/iavf_ethdev.c | 45 ++
20 drivers/net/iavf/iavf_generic_flow.c | 1008 ++++++++++++++++++++++++++
21 drivers/net/iavf/iavf_generic_flow.h | 313 ++++++++
22 drivers/net/iavf/meson.build | 1 +
23 7 files changed, 1379 insertions(+)
24 create mode 100644 drivers/net/iavf/iavf_generic_flow.c
25 create mode 100644 drivers/net/iavf/iavf_generic_flow.h
26
27diff --git a/doc/guides/nics/features/iavf.ini b/doc/guides/nics/features/iavf.ini
28index 80143059e..3bf368785 100644
29--- a/doc/guides/nics/features/iavf.ini
30+++ b/doc/guides/nics/features/iavf.ini
31@@ -19,6 +19,7 @@ Multicast MAC filter = Y
32 RSS hash = Y
33 RSS key update = Y
34 RSS reta update = Y
35+Flow API = Y
36 VLAN filter = Y
37 CRC offload = Y
38 VLAN offload = Y
39diff --git a/drivers/net/iavf/Makefile b/drivers/net/iavf/Makefile
40index 514073d76..1bf0f26b5 100644
41--- a/drivers/net/iavf/Makefile
42+++ b/drivers/net/iavf/Makefile
43@@ -23,6 +23,7 @@ EXPORT_MAP := rte_pmd_iavf_version.map
44 SRCS-$(CONFIG_RTE_LIBRTE_IAVF_PMD) += iavf_ethdev.c
45 SRCS-$(CONFIG_RTE_LIBRTE_IAVF_PMD) += iavf_vchnl.c
46 SRCS-$(CONFIG_RTE_LIBRTE_IAVF_PMD) += iavf_rxtx.c
47+SRCS-$(CONFIG_RTE_LIBRTE_IAVF_PMD) += iavf_generic_flow.c
48 ifeq ($(CONFIG_RTE_ARCH_X86), y)
49 SRCS-$(CONFIG_RTE_LIBRTE_IAVF_PMD) += iavf_rxtx_vec_sse.c
50 endif
51diff --git a/drivers/net/iavf/iavf.h b/drivers/net/iavf/iavf.h
52index b63efd4e8..78bdaff20 100644
53--- a/drivers/net/iavf/iavf.h
54+++ b/drivers/net/iavf/iavf.h
55@@ -86,6 +86,12 @@ struct iavf_vsi {
56 struct virtchnl_eth_stats eth_stats_offset;
57 };
58
59+struct rte_flow;
60+TAILQ_HEAD(iavf_flow_list, rte_flow);
61+
62+struct iavf_flow_parser_node;
63+TAILQ_HEAD(iavf_parser_list, iavf_flow_parser_node);
64+
65 /* TODO: is that correct to assume the max number to be 16 ?*/
66 #define IAVF_MAX_MSIX_VECTORS 16
67
68@@ -121,6 +127,10 @@ struct iavf_info {
69 uint16_t msix_base; /* msix vector base from */
70 /* queue bitmask for each vector */
71 uint16_t rxq_map[IAVF_MAX_MSIX_VECTORS];
72+ struct iavf_flow_list flow_list;
73+ rte_spinlock_t flow_ops_lock;
74+ struct iavf_parser_list rss_parser_list;
75+ struct iavf_parser_list dist_parser_list;
76 };
77
78 #define IAVF_MAX_PKT_TYPE 1024
79diff --git a/drivers/net/iavf/iavf_ethdev.c b/drivers/net/iavf/iavf_ethdev.c
80index d3a121eac..95ab6e246 100644
81--- a/drivers/net/iavf/iavf_ethdev.c
82+++ b/drivers/net/iavf/iavf_ethdev.c
83@@ -27,6 +27,7 @@
84
85 #include "iavf.h"
86 #include "iavf_rxtx.h"
87+#include "iavf_generic_flow.h"
88
89 static int iavf_dev_configure(struct rte_eth_dev *dev);
90 static int iavf_dev_start(struct rte_eth_dev *dev);
91@@ -67,6 +68,11 @@ static int iavf_dev_rx_queue_intr_enable(struct rte_eth_dev *dev,
92 uint16_t queue_id);
93 static int iavf_dev_rx_queue_intr_disable(struct rte_eth_dev *dev,
94 uint16_t queue_id);
95+static int iavf_dev_filter_ctrl(struct rte_eth_dev *dev,
96+ enum rte_filter_type filter_type,
97+ enum rte_filter_op filter_op,
98+ void *arg);
99+
100
101 int iavf_logtype_init;
102 int iavf_logtype_driver;
103@@ -125,6 +131,7 @@ static const struct eth_dev_ops iavf_eth_dev_ops = {
104 .mtu_set = iavf_dev_mtu_set,
105 .rx_queue_intr_enable = iavf_dev_rx_queue_intr_enable,
106 .rx_queue_intr_disable = iavf_dev_rx_queue_intr_disable,
107+ .filter_ctrl = iavf_dev_filter_ctrl,
108 };
109
110 static int
111@@ -1298,6 +1305,33 @@ iavf_dev_interrupt_handler(void *param)
112 iavf_enable_irq0(hw);
113 }
114
115+static int
116+iavf_dev_filter_ctrl(struct rte_eth_dev *dev,
117+ enum rte_filter_type filter_type,
118+ enum rte_filter_op filter_op,
119+ void *arg)
120+{
121+ int ret = 0;
122+
123+ if (!dev)
124+ return -EINVAL;
125+
126+ switch (filter_type) {
127+ case RTE_ETH_FILTER_GENERIC:
128+ if (filter_op != RTE_ETH_FILTER_GET)
129+ return -EINVAL;
130+ *(const void **)arg = &iavf_flow_ops;
131+ break;
132+ default:
133+ PMD_DRV_LOG(WARNING, "Filter type (%d) not supported",
134+ filter_type);
135+ ret = -EINVAL;
136+ break;
137+ }
138+
139+ return ret;
140+}
141+
142 static int
143 iavf_dev_init(struct rte_eth_dev *eth_dev)
144 {
145@@ -1305,6 +1339,7 @@ iavf_dev_init(struct rte_eth_dev *eth_dev)
146 IAVF_DEV_PRIVATE_TO_ADAPTER(eth_dev->data->dev_private);
147 struct iavf_hw *hw = IAVF_DEV_PRIVATE_TO_HW(adapter);
148 struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(eth_dev);
149+ int ret = 0;
150
151 PMD_INIT_FUNC_TRACE();
152
153@@ -1374,6 +1409,12 @@ iavf_dev_init(struct rte_eth_dev *eth_dev)
154 /* configure and enable device interrupt */
155 iavf_enable_irq0(hw);
156
157+ ret = iavf_flow_init(adapter);
158+ if (ret) {
159+ PMD_INIT_LOG(ERR, "Failed to initialize flow");
160+ return ret;
161+ }
162+
163 return 0;
164 }
165
166@@ -1383,6 +1424,8 @@ iavf_dev_close(struct rte_eth_dev *dev)
167 struct iavf_hw *hw = IAVF_DEV_PRIVATE_TO_HW(dev->data->dev_private);
168 struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(dev);
169 struct rte_intr_handle *intr_handle = &pci_dev->intr_handle;
170+ struct iavf_adapter *adapter =
171+ IAVF_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private);
172
173 iavf_dev_stop(dev);
174 iavf_shutdown_adminq(hw);
175@@ -1393,6 +1436,8 @@ iavf_dev_close(struct rte_eth_dev *dev)
176 rte_intr_callback_unregister(intr_handle,
177 iavf_dev_interrupt_handler, dev);
178 iavf_disable_irq0(hw);
179+
180+ iavf_flow_uninit(adapter);
181 }
182
183 static int
184diff --git a/drivers/net/iavf/iavf_generic_flow.c b/drivers/net/iavf/iavf_generic_flow.c
185new file mode 100644
186index 000000000..98f1626d6
187--- /dev/null
188+++ b/drivers/net/iavf/iavf_generic_flow.c
189@@ -0,0 +1,1008 @@
190+/* SPDX-License-Identifier: BSD-3-Clause
191+ * Copyright(c) 2019 Intel Corporation
192+ */
193+
194+#include <sys/queue.h>
195+#include <stdio.h>
196+#include <errno.h>
197+#include <stdint.h>
198+#include <string.h>
199+#include <unistd.h>
200+#include <stdarg.h>
201+
202+#include <rte_ether.h>
203+#include <rte_ethdev_driver.h>
204+#include <rte_malloc.h>
205+#include <rte_tailq.h>
206+
207+#include "iavf.h"
208+#include "iavf_generic_flow.h"
209+
210+static struct iavf_engine_list engine_list =
211+ TAILQ_HEAD_INITIALIZER(engine_list);
212+
213+static int iavf_flow_validate(struct rte_eth_dev *dev,
214+ const struct rte_flow_attr *attr,
215+ const struct rte_flow_item pattern[],
216+ const struct rte_flow_action actions[],
217+ struct rte_flow_error *error);
218+static struct rte_flow *iavf_flow_create(struct rte_eth_dev *dev,
219+ const struct rte_flow_attr *attr,
220+ const struct rte_flow_item pattern[],
221+ const struct rte_flow_action actions[],
222+ struct rte_flow_error *error);
223+static int iavf_flow_destroy(struct rte_eth_dev *dev,
224+ struct rte_flow *flow,
225+ struct rte_flow_error *error);
226+static int iavf_flow_flush(struct rte_eth_dev *dev,
227+ struct rte_flow_error *error);
228+static int iavf_flow_query(struct rte_eth_dev *dev,
229+ struct rte_flow *flow,
230+ const struct rte_flow_action *actions,
231+ void *data,
232+ struct rte_flow_error *error);
233+
234+const struct rte_flow_ops iavf_flow_ops = {
235+ .validate = iavf_flow_validate,
236+ .create = iavf_flow_create,
237+ .destroy = iavf_flow_destroy,
238+ .flush = iavf_flow_flush,
239+ .query = iavf_flow_query,
240+};
241+
242+/* empty */
243+enum rte_flow_item_type iavf_pattern_empty[] = {
244+ RTE_FLOW_ITEM_TYPE_END,
245+};
246+
247+/* L2 */
248+enum rte_flow_item_type iavf_pattern_ethertype[] = {
249+ RTE_FLOW_ITEM_TYPE_ETH,
250+ RTE_FLOW_ITEM_TYPE_END,
251+};
252+
253+enum rte_flow_item_type iavf_pattern_ethertype_vlan[] = {
254+ RTE_FLOW_ITEM_TYPE_ETH,
255+ RTE_FLOW_ITEM_TYPE_VLAN,
256+ RTE_FLOW_ITEM_TYPE_END,
257+};
258+
259+enum rte_flow_item_type iavf_pattern_ethertype_qinq[] = {
260+ RTE_FLOW_ITEM_TYPE_ETH,
261+ RTE_FLOW_ITEM_TYPE_VLAN,
262+ RTE_FLOW_ITEM_TYPE_VLAN,
263+ RTE_FLOW_ITEM_TYPE_END,
264+};
265+
266+/* ARP */
267+enum rte_flow_item_type iavf_pattern_eth_arp[] = {
268+ RTE_FLOW_ITEM_TYPE_ETH,
269+ RTE_FLOW_ITEM_TYPE_ARP_ETH_IPV4,
270+ RTE_FLOW_ITEM_TYPE_END,
271+};
272+
273+/* non-tunnel IPv4 */
274+enum rte_flow_item_type iavf_pattern_eth_ipv4[] = {
275+ RTE_FLOW_ITEM_TYPE_ETH,
276+ RTE_FLOW_ITEM_TYPE_IPV4,
277+ RTE_FLOW_ITEM_TYPE_END,
278+};
279+
280+enum rte_flow_item_type iavf_pattern_eth_vlan_ipv4[] = {
281+ RTE_FLOW_ITEM_TYPE_ETH,
282+ RTE_FLOW_ITEM_TYPE_VLAN,
283+ RTE_FLOW_ITEM_TYPE_IPV4,
284+ RTE_FLOW_ITEM_TYPE_END,
285+};
286+
287+enum rte_flow_item_type iavf_pattern_eth_qinq_ipv4[] = {
288+ RTE_FLOW_ITEM_TYPE_ETH,
289+ RTE_FLOW_ITEM_TYPE_VLAN,
290+ RTE_FLOW_ITEM_TYPE_VLAN,
291+ RTE_FLOW_ITEM_TYPE_IPV4,
292+ RTE_FLOW_ITEM_TYPE_END,
293+};
294+
295+enum rte_flow_item_type iavf_pattern_eth_ipv4_udp[] = {
296+ RTE_FLOW_ITEM_TYPE_ETH,
297+ RTE_FLOW_ITEM_TYPE_IPV4,
298+ RTE_FLOW_ITEM_TYPE_UDP,
299+ RTE_FLOW_ITEM_TYPE_END,
300+};
301+
302+enum rte_flow_item_type iavf_pattern_eth_vlan_ipv4_udp[] = {
303+ RTE_FLOW_ITEM_TYPE_ETH,
304+ RTE_FLOW_ITEM_TYPE_VLAN,
305+ RTE_FLOW_ITEM_TYPE_IPV4,
306+ RTE_FLOW_ITEM_TYPE_UDP,
307+ RTE_FLOW_ITEM_TYPE_END,
308+};
309+
310+enum rte_flow_item_type iavf_pattern_eth_qinq_ipv4_udp[] = {
311+ RTE_FLOW_ITEM_TYPE_ETH,
312+ RTE_FLOW_ITEM_TYPE_VLAN,
313+ RTE_FLOW_ITEM_TYPE_VLAN,
314+ RTE_FLOW_ITEM_TYPE_IPV4,
315+ RTE_FLOW_ITEM_TYPE_UDP,
316+ RTE_FLOW_ITEM_TYPE_END,
317+};
318+
319+enum rte_flow_item_type iavf_pattern_eth_ipv4_tcp[] = {
320+ RTE_FLOW_ITEM_TYPE_ETH,
321+ RTE_FLOW_ITEM_TYPE_IPV4,
322+ RTE_FLOW_ITEM_TYPE_TCP,
323+ RTE_FLOW_ITEM_TYPE_END,
324+};
325+
326+enum rte_flow_item_type iavf_pattern_eth_vlan_ipv4_tcp[] = {
327+ RTE_FLOW_ITEM_TYPE_ETH,
328+ RTE_FLOW_ITEM_TYPE_VLAN,
329+ RTE_FLOW_ITEM_TYPE_IPV4,
330+ RTE_FLOW_ITEM_TYPE_TCP,
331+ RTE_FLOW_ITEM_TYPE_END,
332+};
333+
334+enum rte_flow_item_type iavf_pattern_eth_qinq_ipv4_tcp[] = {
335+ RTE_FLOW_ITEM_TYPE_ETH,
336+ RTE_FLOW_ITEM_TYPE_VLAN,
337+ RTE_FLOW_ITEM_TYPE_VLAN,
338+ RTE_FLOW_ITEM_TYPE_IPV4,
339+ RTE_FLOW_ITEM_TYPE_TCP,
340+ RTE_FLOW_ITEM_TYPE_END,
341+};
342+
343+enum rte_flow_item_type iavf_pattern_eth_ipv4_sctp[] = {
344+ RTE_FLOW_ITEM_TYPE_ETH,
345+ RTE_FLOW_ITEM_TYPE_IPV4,
346+ RTE_FLOW_ITEM_TYPE_SCTP,
347+ RTE_FLOW_ITEM_TYPE_END,
348+};
349+
350+enum rte_flow_item_type iavf_pattern_eth_vlan_ipv4_sctp[] = {
351+ RTE_FLOW_ITEM_TYPE_ETH,
352+ RTE_FLOW_ITEM_TYPE_VLAN,
353+ RTE_FLOW_ITEM_TYPE_IPV4,
354+ RTE_FLOW_ITEM_TYPE_SCTP,
355+ RTE_FLOW_ITEM_TYPE_END,
356+};
357+
358+enum rte_flow_item_type iavf_pattern_eth_qinq_ipv4_sctp[] = {
359+ RTE_FLOW_ITEM_TYPE_ETH,
360+ RTE_FLOW_ITEM_TYPE_VLAN,
361+ RTE_FLOW_ITEM_TYPE_VLAN,
362+ RTE_FLOW_ITEM_TYPE_IPV4,
363+ RTE_FLOW_ITEM_TYPE_SCTP,
364+ RTE_FLOW_ITEM_TYPE_END,
365+};
366+
367+enum rte_flow_item_type iavf_pattern_eth_ipv4_icmp[] = {
368+ RTE_FLOW_ITEM_TYPE_ETH,
369+ RTE_FLOW_ITEM_TYPE_IPV4,
370+ RTE_FLOW_ITEM_TYPE_ICMP,
371+ RTE_FLOW_ITEM_TYPE_END,
372+};
373+
374+enum rte_flow_item_type iavf_pattern_eth_vlan_ipv4_icmp[] = {
375+ RTE_FLOW_ITEM_TYPE_ETH,
376+ RTE_FLOW_ITEM_TYPE_VLAN,
377+ RTE_FLOW_ITEM_TYPE_IPV4,
378+ RTE_FLOW_ITEM_TYPE_ICMP,
379+ RTE_FLOW_ITEM_TYPE_END,
380+};
381+
382+enum rte_flow_item_type iavf_pattern_eth_qinq_ipv4_icmp[] = {
383+ RTE_FLOW_ITEM_TYPE_ETH,
384+ RTE_FLOW_ITEM_TYPE_VLAN,
385+ RTE_FLOW_ITEM_TYPE_VLAN,
386+ RTE_FLOW_ITEM_TYPE_IPV4,
387+ RTE_FLOW_ITEM_TYPE_ICMP,
388+ RTE_FLOW_ITEM_TYPE_END,
389+};
390+
391+/* non-tunnel IPv6 */
392+enum rte_flow_item_type iavf_pattern_eth_ipv6[] = {
393+ RTE_FLOW_ITEM_TYPE_ETH,
394+ RTE_FLOW_ITEM_TYPE_IPV6,
395+ RTE_FLOW_ITEM_TYPE_END,
396+};
397+
398+enum rte_flow_item_type iavf_pattern_eth_vlan_ipv6[] = {
399+ RTE_FLOW_ITEM_TYPE_ETH,
400+ RTE_FLOW_ITEM_TYPE_VLAN,
401+ RTE_FLOW_ITEM_TYPE_IPV6,
402+ RTE_FLOW_ITEM_TYPE_END,
403+};
404+
405+enum rte_flow_item_type iavf_pattern_eth_qinq_ipv6[] = {
406+ RTE_FLOW_ITEM_TYPE_ETH,
407+ RTE_FLOW_ITEM_TYPE_VLAN,
408+ RTE_FLOW_ITEM_TYPE_VLAN,
409+ RTE_FLOW_ITEM_TYPE_IPV6,
410+ RTE_FLOW_ITEM_TYPE_END,
411+};
412+
413+enum rte_flow_item_type iavf_pattern_eth_ipv6_udp[] = {
414+ RTE_FLOW_ITEM_TYPE_ETH,
415+ RTE_FLOW_ITEM_TYPE_IPV6,
416+ RTE_FLOW_ITEM_TYPE_UDP,
417+ RTE_FLOW_ITEM_TYPE_END,
418+};
419+
420+enum rte_flow_item_type iavf_pattern_eth_vlan_ipv6_udp[] = {
421+ RTE_FLOW_ITEM_TYPE_ETH,
422+ RTE_FLOW_ITEM_TYPE_VLAN,
423+ RTE_FLOW_ITEM_TYPE_IPV6,
424+ RTE_FLOW_ITEM_TYPE_UDP,
425+ RTE_FLOW_ITEM_TYPE_END,
426+};
427+
428+enum rte_flow_item_type iavf_pattern_eth_qinq_ipv6_udp[] = {
429+ RTE_FLOW_ITEM_TYPE_ETH,
430+ RTE_FLOW_ITEM_TYPE_VLAN,
431+ RTE_FLOW_ITEM_TYPE_VLAN,
432+ RTE_FLOW_ITEM_TYPE_IPV6,
433+ RTE_FLOW_ITEM_TYPE_UDP,
434+ RTE_FLOW_ITEM_TYPE_END,
435+};
436+
437+enum rte_flow_item_type iavf_pattern_eth_ipv6_tcp[] = {
438+ RTE_FLOW_ITEM_TYPE_ETH,
439+ RTE_FLOW_ITEM_TYPE_IPV6,
440+ RTE_FLOW_ITEM_TYPE_TCP,
441+ RTE_FLOW_ITEM_TYPE_END,
442+};
443+
444+enum rte_flow_item_type iavf_pattern_eth_vlan_ipv6_tcp[] = {
445+ RTE_FLOW_ITEM_TYPE_ETH,
446+ RTE_FLOW_ITEM_TYPE_VLAN,
447+ RTE_FLOW_ITEM_TYPE_IPV6,
448+ RTE_FLOW_ITEM_TYPE_TCP,
449+ RTE_FLOW_ITEM_TYPE_END,
450+};
451+
452+enum rte_flow_item_type iavf_pattern_eth_qinq_ipv6_tcp[] = {
453+ RTE_FLOW_ITEM_TYPE_ETH,
454+ RTE_FLOW_ITEM_TYPE_VLAN,
455+ RTE_FLOW_ITEM_TYPE_VLAN,
456+ RTE_FLOW_ITEM_TYPE_IPV6,
457+ RTE_FLOW_ITEM_TYPE_TCP,
458+ RTE_FLOW_ITEM_TYPE_END,
459+};
460+
461+enum rte_flow_item_type iavf_pattern_eth_ipv6_sctp[] = {
462+ RTE_FLOW_ITEM_TYPE_ETH,
463+ RTE_FLOW_ITEM_TYPE_IPV6,
464+ RTE_FLOW_ITEM_TYPE_SCTP,
465+ RTE_FLOW_ITEM_TYPE_END,
466+};
467+
468+enum rte_flow_item_type iavf_pattern_eth_vlan_ipv6_sctp[] = {
469+ RTE_FLOW_ITEM_TYPE_ETH,
470+ RTE_FLOW_ITEM_TYPE_VLAN,
471+ RTE_FLOW_ITEM_TYPE_IPV6,
472+ RTE_FLOW_ITEM_TYPE_SCTP,
473+ RTE_FLOW_ITEM_TYPE_END,
474+};
475+
476+enum rte_flow_item_type iavf_pattern_eth_qinq_ipv6_sctp[] = {
477+ RTE_FLOW_ITEM_TYPE_ETH,
478+ RTE_FLOW_ITEM_TYPE_VLAN,
479+ RTE_FLOW_ITEM_TYPE_VLAN,
480+ RTE_FLOW_ITEM_TYPE_IPV6,
481+ RTE_FLOW_ITEM_TYPE_SCTP,
482+ RTE_FLOW_ITEM_TYPE_END,
483+};
484+
485+enum rte_flow_item_type iavf_pattern_eth_ipv6_icmp6[] = {
486+ RTE_FLOW_ITEM_TYPE_ETH,
487+ RTE_FLOW_ITEM_TYPE_IPV6,
488+ RTE_FLOW_ITEM_TYPE_ICMP6,
489+ RTE_FLOW_ITEM_TYPE_END,
490+};
491+
492+enum rte_flow_item_type iavf_pattern_eth_vlan_ipv6_icmp6[] = {
493+ RTE_FLOW_ITEM_TYPE_ETH,
494+ RTE_FLOW_ITEM_TYPE_VLAN,
495+ RTE_FLOW_ITEM_TYPE_IPV6,
496+ RTE_FLOW_ITEM_TYPE_ICMP6,
497+ RTE_FLOW_ITEM_TYPE_END,
498+};
499+
500+enum rte_flow_item_type iavf_pattern_eth_qinq_ipv6_icmp6[] = {
501+ RTE_FLOW_ITEM_TYPE_ETH,
502+ RTE_FLOW_ITEM_TYPE_VLAN,
503+ RTE_FLOW_ITEM_TYPE_VLAN,
504+ RTE_FLOW_ITEM_TYPE_IPV6,
505+ RTE_FLOW_ITEM_TYPE_ICMP6,
506+ RTE_FLOW_ITEM_TYPE_END,
507+};
508+
509+/* GTPU */
510+enum rte_flow_item_type iavf_pattern_eth_ipv4_gtpu[] = {
511+ RTE_FLOW_ITEM_TYPE_ETH,
512+ RTE_FLOW_ITEM_TYPE_IPV4,
513+ RTE_FLOW_ITEM_TYPE_UDP,
514+ RTE_FLOW_ITEM_TYPE_GTPU,
515+ RTE_FLOW_ITEM_TYPE_END,
516+};
517+
518+enum rte_flow_item_type iavf_pattern_eth_ipv4_gtpu_eh[] = {
519+ RTE_FLOW_ITEM_TYPE_ETH,
520+ RTE_FLOW_ITEM_TYPE_IPV4,
521+ RTE_FLOW_ITEM_TYPE_UDP,
522+ RTE_FLOW_ITEM_TYPE_GTPU,
523+ RTE_FLOW_ITEM_TYPE_GTP_PSC,
524+ RTE_FLOW_ITEM_TYPE_END,
525+};
526+
527+enum rte_flow_item_type iavf_pattern_eth_ipv4_gtpu_ipv4[] = {
528+ RTE_FLOW_ITEM_TYPE_ETH,
529+ RTE_FLOW_ITEM_TYPE_IPV4,
530+ RTE_FLOW_ITEM_TYPE_UDP,
531+ RTE_FLOW_ITEM_TYPE_GTPU,
532+ RTE_FLOW_ITEM_TYPE_IPV4,
533+ RTE_FLOW_ITEM_TYPE_END,
534+};
535+
536+enum rte_flow_item_type iavf_pattern_eth_ipv4_gtpu_eh_ipv4[] = {
537+ RTE_FLOW_ITEM_TYPE_ETH,
538+ RTE_FLOW_ITEM_TYPE_IPV4,
539+ RTE_FLOW_ITEM_TYPE_UDP,
540+ RTE_FLOW_ITEM_TYPE_GTPU,
541+ RTE_FLOW_ITEM_TYPE_GTP_PSC,
542+ RTE_FLOW_ITEM_TYPE_IPV4,
543+ RTE_FLOW_ITEM_TYPE_END,
544+};
545+
546+enum rte_flow_item_type iavf_pattern_eth_ipv4_gtpu_eh_ipv4_udp[] = {
547+ RTE_FLOW_ITEM_TYPE_ETH,
548+ RTE_FLOW_ITEM_TYPE_IPV4,
549+ RTE_FLOW_ITEM_TYPE_UDP,
550+ RTE_FLOW_ITEM_TYPE_GTPU,
551+ RTE_FLOW_ITEM_TYPE_GTP_PSC,
552+ RTE_FLOW_ITEM_TYPE_IPV4,
553+ RTE_FLOW_ITEM_TYPE_UDP,
554+ RTE_FLOW_ITEM_TYPE_END,
555+};
556+
557+enum rte_flow_item_type iavf_pattern_eth_ipv4_gtpu_eh_ipv4_tcp[] = {
558+ RTE_FLOW_ITEM_TYPE_ETH,
559+ RTE_FLOW_ITEM_TYPE_IPV4,
560+ RTE_FLOW_ITEM_TYPE_UDP,
561+ RTE_FLOW_ITEM_TYPE_GTPU,
562+ RTE_FLOW_ITEM_TYPE_GTP_PSC,
563+ RTE_FLOW_ITEM_TYPE_IPV4,
564+ RTE_FLOW_ITEM_TYPE_TCP,
565+ RTE_FLOW_ITEM_TYPE_END,
566+
567+};
568+
569+enum rte_flow_item_type iavf_pattern_eth_ipv4_gtpu_eh_ipv4_icmp[] = {
570+ RTE_FLOW_ITEM_TYPE_ETH,
571+ RTE_FLOW_ITEM_TYPE_IPV4,
572+ RTE_FLOW_ITEM_TYPE_UDP,
573+ RTE_FLOW_ITEM_TYPE_GTPU,
574+ RTE_FLOW_ITEM_TYPE_GTP_PSC,
575+ RTE_FLOW_ITEM_TYPE_IPV4,
576+ RTE_FLOW_ITEM_TYPE_ICMP,
577+ RTE_FLOW_ITEM_TYPE_END,
578+};
579+
580+/* ESP */
581+enum rte_flow_item_type iavf_pattern_eth_ipv4_esp[] = {
582+ RTE_FLOW_ITEM_TYPE_ETH,
583+ RTE_FLOW_ITEM_TYPE_IPV4,
584+ RTE_FLOW_ITEM_TYPE_ESP,
585+ RTE_FLOW_ITEM_TYPE_END,
586+};
587+
588+enum rte_flow_item_type iavf_pattern_eth_ipv4_udp_esp[] = {
589+ RTE_FLOW_ITEM_TYPE_ETH,
590+ RTE_FLOW_ITEM_TYPE_IPV4,
591+ RTE_FLOW_ITEM_TYPE_UDP,
592+ RTE_FLOW_ITEM_TYPE_ESP,
593+ RTE_FLOW_ITEM_TYPE_END,
594+};
595+
596+enum rte_flow_item_type iavf_pattern_eth_ipv6_esp[] = {
597+ RTE_FLOW_ITEM_TYPE_ETH,
598+ RTE_FLOW_ITEM_TYPE_IPV6,
599+ RTE_FLOW_ITEM_TYPE_ESP,
600+ RTE_FLOW_ITEM_TYPE_END,
601+};
602+
603+enum rte_flow_item_type iavf_pattern_eth_ipv6_udp_esp[] = {
604+ RTE_FLOW_ITEM_TYPE_ETH,
605+ RTE_FLOW_ITEM_TYPE_IPV6,
606+ RTE_FLOW_ITEM_TYPE_UDP,
607+ RTE_FLOW_ITEM_TYPE_ESP,
608+ RTE_FLOW_ITEM_TYPE_END,
609+};
610+
611+/* AH */
612+enum rte_flow_item_type iavf_pattern_eth_ipv4_ah[] = {
613+ RTE_FLOW_ITEM_TYPE_ETH,
614+ RTE_FLOW_ITEM_TYPE_IPV4,
615+ RTE_FLOW_ITEM_TYPE_AH,
616+ RTE_FLOW_ITEM_TYPE_END,
617+};
618+
619+enum rte_flow_item_type iavf_pattern_eth_ipv6_ah[] = {
620+ RTE_FLOW_ITEM_TYPE_ETH,
621+ RTE_FLOW_ITEM_TYPE_IPV6,
622+ RTE_FLOW_ITEM_TYPE_AH,
623+ RTE_FLOW_ITEM_TYPE_END,
624+};
625+
626+/* L2TPV3 */
627+enum rte_flow_item_type iavf_pattern_eth_ipv4_l2tpv3[] = {
628+ RTE_FLOW_ITEM_TYPE_ETH,
629+ RTE_FLOW_ITEM_TYPE_IPV4,
630+ RTE_FLOW_ITEM_TYPE_L2TPV3OIP,
631+ RTE_FLOW_ITEM_TYPE_END,
632+};
633+
634+enum rte_flow_item_type iavf_pattern_eth_ipv6_l2tpv3[] = {
635+ RTE_FLOW_ITEM_TYPE_ETH,
636+ RTE_FLOW_ITEM_TYPE_IPV6,
637+ RTE_FLOW_ITEM_TYPE_L2TPV3OIP,
638+ RTE_FLOW_ITEM_TYPE_END,
639+};
640+
641+typedef struct iavf_flow_engine * (*parse_engine_t)(struct iavf_adapter *ad,
642+ struct rte_flow *flow,
643+ struct iavf_parser_list *parser_list,
644+ const struct rte_flow_item pattern[],
645+ const struct rte_flow_action actions[],
646+ struct rte_flow_error *error);
647+
648+void
649+iavf_register_flow_engine(struct iavf_flow_engine *engine)
650+{
651+ TAILQ_INSERT_TAIL(&engine_list, engine, node);
652+}
653+
654+int
655+iavf_flow_init(struct iavf_adapter *ad)
656+{
657+ int ret;
658+ struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(ad);
659+ void *temp;
660+ struct iavf_flow_engine *engine;
661+
662+ TAILQ_INIT(&vf->flow_list);
663+ TAILQ_INIT(&vf->rss_parser_list);
664+ TAILQ_INIT(&vf->dist_parser_list);
665+ rte_spinlock_init(&vf->flow_ops_lock);
666+
667+ TAILQ_FOREACH_SAFE(engine, &engine_list, node, temp) {
668+ if (engine->init == NULL) {
669+ PMD_INIT_LOG(ERR, "Invalid engine type (%d)",
670+ engine->type);
671+ return -ENOTSUP;
672+ }
673+
674+ ret = engine->init(ad);
675+ if (ret && ret != -ENOTSUP) {
676+ PMD_INIT_LOG(ERR, "Failed to initialize engine %d",
677+ engine->type);
678+ return ret;
679+ }
680+ }
681+ return 0;
682+}
683+
684+void
685+iavf_flow_uninit(struct iavf_adapter *ad)
686+{
687+ struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(ad);
688+ struct iavf_flow_engine *engine;
689+ struct rte_flow *p_flow;
690+ struct iavf_flow_parser_node *p_parser;
691+ void *temp;
692+
693+ TAILQ_FOREACH_SAFE(engine, &engine_list, node, temp) {
694+ if (engine->uninit)
695+ engine->uninit(ad);
696+ }
697+
698+ /* Remove all flows */
699+ while ((p_flow = TAILQ_FIRST(&vf->flow_list))) {
700+ TAILQ_REMOVE(&vf->flow_list, p_flow, node);
701+ if (p_flow->engine->free)
702+ p_flow->engine->free(p_flow);
703+ rte_free(p_flow);
704+ }
705+
706+ /* Cleanup parser list */
707+ while ((p_parser = TAILQ_FIRST(&vf->rss_parser_list))) {
708+ TAILQ_REMOVE(&vf->rss_parser_list, p_parser, node);
709+ rte_free(p_parser);
710+ }
711+
712+ while ((p_parser = TAILQ_FIRST(&vf->dist_parser_list))) {
713+ TAILQ_REMOVE(&vf->dist_parser_list, p_parser, node);
714+ rte_free(p_parser);
715+ }
716+}
717+
718+int
719+iavf_register_parser(struct iavf_flow_parser *parser,
720+ struct iavf_adapter *ad)
721+{
722+ struct iavf_parser_list *list = NULL;
723+ struct iavf_flow_parser_node *parser_node;
724+ struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(ad);
725+
726+ parser_node = rte_zmalloc("iavf_parser", sizeof(*parser_node), 0);
727+ if (parser_node == NULL) {
728+ PMD_DRV_LOG(ERR, "Failed to allocate memory.");
729+ return -ENOMEM;
730+ }
731+ parser_node->parser = parser;
732+
733+ if (parser->engine->type == IAVF_FLOW_ENGINE_HASH) {
734+ list = &vf->rss_parser_list;
735+ TAILQ_INSERT_TAIL(list, parser_node, node);
736+ } else if (parser->engine->type == IAVF_FLOW_ENGINE_FDIR) {
737+ list = &vf->dist_parser_list;
738+ TAILQ_INSERT_HEAD(list, parser_node, node);
739+ } else {
740+ return -EINVAL;
741+ }
742+
743+ return 0;
744+}
745+
746+void
747+iavf_unregister_parser(struct iavf_flow_parser *parser,
748+ struct iavf_adapter *ad)
749+{
750+ struct iavf_parser_list *list = NULL;
751+ struct iavf_flow_parser_node *p_parser;
752+ struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(ad);
753+ void *temp;
754+
755+ if (parser->engine->type == IAVF_FLOW_ENGINE_HASH)
756+ list = &vf->rss_parser_list;
757+ else if (parser->engine->type == IAVF_FLOW_ENGINE_FDIR)
758+ list = &vf->dist_parser_list;
759+
760+ if (list == NULL)
761+ return;
762+
763+ TAILQ_FOREACH_SAFE(p_parser, list, node, temp) {
764+ if (p_parser->parser->engine->type == parser->engine->type) {
765+ TAILQ_REMOVE(list, p_parser, node);
766+ rte_free(p_parser);
767+ }
768+ }
769+}
770+
771+static int
772+iavf_flow_valid_attr(const struct rte_flow_attr *attr,
773+ struct rte_flow_error *error)
774+{
775+ /* Must be input direction */
776+ if (!attr->ingress) {
777+ rte_flow_error_set(error, EINVAL,
778+ RTE_FLOW_ERROR_TYPE_ATTR_INGRESS,
779+ attr, "Only support ingress.");
780+ return -rte_errno;
781+ }
782+
783+ /* Not supported */
784+ if (attr->egress) {
785+ rte_flow_error_set(error, EINVAL,
786+ RTE_FLOW_ERROR_TYPE_ATTR_EGRESS,
787+ attr, "Not support egress.");
788+ return -rte_errno;
789+ }
790+
791+ /* Not supported */
792+ if (attr->priority) {
793+ rte_flow_error_set(error, EINVAL,
794+ RTE_FLOW_ERROR_TYPE_ATTR_PRIORITY,
795+ attr, "Not support priority.");
796+ return -rte_errno;
797+ }
798+
799+ /* Not supported */
800+ if (attr->group) {
801+ rte_flow_error_set(error, EINVAL,
802+ RTE_FLOW_ERROR_TYPE_ATTR_GROUP,
803+ attr, "Not support group.");
804+ return -rte_errno;
805+ }
806+
807+ return 0;
808+}
809+
810+/* Find the first VOID or non-VOID item pointer */
811+static const struct rte_flow_item *
812+iavf_find_first_item(const struct rte_flow_item *item, bool is_void)
813+{
814+ bool is_find;
815+
816+ while (item->type != RTE_FLOW_ITEM_TYPE_END) {
817+ if (is_void)
818+ is_find = item->type == RTE_FLOW_ITEM_TYPE_VOID;
819+ else
820+ is_find = item->type != RTE_FLOW_ITEM_TYPE_VOID;
821+ if (is_find)
822+ break;
823+ item++;
824+ }
825+ return item;
826+}
827+
828+/* Skip all VOID items of the pattern */
829+static void
830+iavf_pattern_skip_void_item(struct rte_flow_item *items,
831+ const struct rte_flow_item *pattern)
832+{
833+ uint32_t cpy_count = 0;
834+ const struct rte_flow_item *pb = pattern, *pe = pattern;
835+
836+ for (;;) {
837+ /* Find a non-void item first */
838+ pb = iavf_find_first_item(pb, false);
839+ if (pb->type == RTE_FLOW_ITEM_TYPE_END) {
840+ pe = pb;
841+ break;
842+ }
843+
844+ /* Find a void item */
845+ pe = iavf_find_first_item(pb + 1, true);
846+
847+ cpy_count = pe - pb;
848+ rte_memcpy(items, pb, sizeof(struct rte_flow_item) * cpy_count);
849+
850+ items += cpy_count;
851+
852+ if (pe->type == RTE_FLOW_ITEM_TYPE_END)
853+ break;
854+
855+ pb = pe + 1;
856+ }
857+ /* Copy the END item. */
858+ rte_memcpy(items, pe, sizeof(struct rte_flow_item));
859+}
860+
861+/* Check if the pattern matches a supported item type array */
862+static bool
863+iavf_match_pattern(enum rte_flow_item_type *item_array,
864+ const struct rte_flow_item *pattern)
865+{
866+ const struct rte_flow_item *item = pattern;
867+
868+ while ((*item_array == item->type) &&
869+ (*item_array != RTE_FLOW_ITEM_TYPE_END)) {
870+ item_array++;
871+ item++;
872+ }
873+
874+ return (*item_array == RTE_FLOW_ITEM_TYPE_END &&
875+ item->type == RTE_FLOW_ITEM_TYPE_END);
876+}
877+
878+struct iavf_pattern_match_item *
879+iavf_search_pattern_match_item(const struct rte_flow_item pattern[],
880+ struct iavf_pattern_match_item *array,
881+ uint32_t array_len,
882+ struct rte_flow_error *error)
883+{
884+ uint16_t i = 0;
885+ struct iavf_pattern_match_item *pattern_match_item;
886+ /* need free by each filter */
887+ struct rte_flow_item *items; /* used for pattern without VOID items */
888+ uint32_t item_num = 0; /* non-void item number */
889+
890+ /* Get the non-void item number of pattern */
891+ while ((pattern + i)->type != RTE_FLOW_ITEM_TYPE_END) {
892+ if ((pattern + i)->type != RTE_FLOW_ITEM_TYPE_VOID)
893+ item_num++;
894+ i++;
895+ }
896+ item_num++;
897+
898+ items = rte_zmalloc("iavf_pattern",
899+ item_num * sizeof(struct rte_flow_item), 0);
900+ if (!items) {
901+ rte_flow_error_set(error, ENOMEM, RTE_FLOW_ERROR_TYPE_ITEM_NUM,
902+ NULL, "No memory for PMD internal items.");
903+ return NULL;
904+ }
905+ pattern_match_item = rte_zmalloc("iavf_pattern_match_item",
906+ sizeof(struct iavf_pattern_match_item), 0);
907+ if (!pattern_match_item) {
908+ rte_flow_error_set(error, ENOMEM, RTE_FLOW_ERROR_TYPE_HANDLE,
909+ NULL, "Failed to allocate memory.");
910+ return NULL;
911+ }
912+
913+ iavf_pattern_skip_void_item(items, pattern);
914+
915+ for (i = 0; i < array_len; i++)
916+ if (iavf_match_pattern(array[i].pattern_list,
917+ items)) {
918+ pattern_match_item->input_set_mask =
919+ array[i].input_set_mask;
920+ pattern_match_item->pattern_list =
921+ array[i].pattern_list;
922+ pattern_match_item->meta = array[i].meta;
923+ rte_free(items);
924+ return pattern_match_item;
925+ }
926+ rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_ITEM,
927+ pattern, "Unsupported pattern");
928+
929+ rte_free(items);
930+ rte_free(pattern_match_item);
931+ return NULL;
932+}
933+
934+static struct iavf_flow_engine *
935+iavf_parse_engine_create(struct iavf_adapter *ad,
936+ struct rte_flow *flow,
937+ struct iavf_parser_list *parser_list,
938+ const struct rte_flow_item pattern[],
939+ const struct rte_flow_action actions[],
940+ struct rte_flow_error *error)
941+{
942+ struct iavf_flow_engine *engine = NULL;
943+ struct iavf_flow_parser_node *parser_node;
944+ void *temp;
945+ void *meta = NULL;
946+
947+ TAILQ_FOREACH_SAFE(parser_node, parser_list, node, temp) {
948+ if (parser_node->parser->parse_pattern_action(ad,
949+ parser_node->parser->array,
950+ parser_node->parser->array_len,
951+ pattern, actions, &meta, error) < 0)
952+ continue;
953+
954+ engine = parser_node->parser->engine;
955+
956+ RTE_ASSERT(engine->create != NULL);
957+ if (!(engine->create(ad, flow, meta, error)))
958+ return engine;
959+ }
960+ return NULL;
961+}
962+
963+static struct iavf_flow_engine *
964+iavf_parse_engine_validate(struct iavf_adapter *ad,
965+ struct rte_flow *flow,
966+ struct iavf_parser_list *parser_list,
967+ const struct rte_flow_item pattern[],
968+ const struct rte_flow_action actions[],
969+ struct rte_flow_error *error)
970+{
971+ struct iavf_flow_engine *engine = NULL;
972+ struct iavf_flow_parser_node *parser_node;
973+ void *temp;
974+ void *meta = NULL;
975+
976+ TAILQ_FOREACH_SAFE(parser_node, parser_list, node, temp) {
977+ if (parser_node->parser->parse_pattern_action(ad,
978+ parser_node->parser->array,
979+ parser_node->parser->array_len,
980+ pattern, actions, &meta, error) < 0)
981+ continue;
982+
983+ engine = parser_node->parser->engine;
984+ if (engine->validation == NULL) {
985+ rte_flow_error_set(error, EINVAL,
986+ RTE_FLOW_ERROR_TYPE_HANDLE,
987+ NULL, "Validation not support");
988+ continue;
989+ }
990+
991+ if (engine->validation(ad, flow, meta, error)) {
992+ rte_flow_error_set(error, EINVAL,
993+ RTE_FLOW_ERROR_TYPE_HANDLE,
994+ NULL, "Validation failed");
995+ break;
996+ }
997+ }
998+ return engine;
999+}
1000+
1001+
1002+static int
1003+iavf_flow_process_filter(struct rte_eth_dev *dev,
1004+ struct rte_flow *flow,
1005+ const struct rte_flow_attr *attr,
1006+ const struct rte_flow_item pattern[],
1007+ const struct rte_flow_action actions[],
1008+ struct iavf_flow_engine **engine,
1009+ parse_engine_t iavf_parse_engine,
1010+ struct rte_flow_error *error)
1011+{
1012+ int ret = IAVF_ERR_CONFIG;
1013+ struct iavf_adapter *ad =
1014+ IAVF_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private);
1015+ struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(ad);
1016+
1017+ if (!pattern) {
1018+ rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_ITEM_NUM,
1019+ NULL, "NULL pattern.");
1020+ return -rte_errno;
1021+ }
1022+
1023+ if (!actions) {
1024+ rte_flow_error_set(error, EINVAL,
1025+ RTE_FLOW_ERROR_TYPE_ACTION_NUM,
1026+ NULL, "NULL action.");
1027+ return -rte_errno;
1028+ }
1029+
1030+ if (!attr) {
1031+ rte_flow_error_set(error, EINVAL,
1032+ RTE_FLOW_ERROR_TYPE_ATTR,
1033+ NULL, "NULL attribute.");
1034+ return -rte_errno;
1035+ }
1036+
1037+ ret = iavf_flow_valid_attr(attr, error);
1038+ if (ret)
1039+ return ret;
1040+
1041+ *engine = iavf_parse_engine(ad, flow, &vf->rss_parser_list, pattern,
1042+ actions, error);
1043+ if (*engine != NULL)
1044+ return 0;
1045+
1046+ *engine = iavf_parse_engine(ad, flow, &vf->dist_parser_list, pattern,
1047+ actions, error);
1048+
1049+ if (*engine == NULL)
1050+ return -EINVAL;
1051+
1052+ return 0;
1053+}
1054+
1055+static int
1056+iavf_flow_validate(struct rte_eth_dev *dev,
1057+ const struct rte_flow_attr *attr,
1058+ const struct rte_flow_item pattern[],
1059+ const struct rte_flow_action actions[],
1060+ struct rte_flow_error *error)
1061+{
1062+ struct iavf_flow_engine *engine;
1063+
1064+ return iavf_flow_process_filter(dev, NULL, attr, pattern, actions,
1065+ &engine, iavf_parse_engine_validate, error);
1066+}
1067+
1068+static struct rte_flow *
1069+iavf_flow_create(struct rte_eth_dev *dev,
1070+ const struct rte_flow_attr *attr,
1071+ const struct rte_flow_item pattern[],
1072+ const struct rte_flow_action actions[],
1073+ struct rte_flow_error *error)
1074+{
1075+ struct iavf_adapter *ad =
1076+ IAVF_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private);
1077+ struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(ad);
1078+ struct iavf_flow_engine *engine = NULL;
1079+ struct rte_flow *flow = NULL;
1080+ int ret;
1081+
1082+ flow = rte_zmalloc("iavf_flow", sizeof(struct rte_flow), 0);
1083+ if (!flow) {
1084+ rte_flow_error_set(error, ENOMEM,
1085+ RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
1086+ "Failed to allocate memory");
1087+ return flow;
1088+ }
1089+
1090+ ret = iavf_flow_process_filter(dev, flow, attr, pattern, actions,
1091+ &engine, iavf_parse_engine_create, error);
1092+ if (ret < 0) {
1093+ PMD_DRV_LOG(ERR, "Failed to create flow");
1094+ rte_free(flow);
1095+ flow = NULL;
1096+ goto free_flow;
1097+ }
1098+
1099+ flow->engine = engine;
1100+ TAILQ_INSERT_TAIL(&vf->flow_list, flow, node);
1101+ PMD_DRV_LOG(INFO, "Succeeded to create (%d) flow", engine->type);
1102+
1103+free_flow:
1104+ rte_spinlock_unlock(&vf->flow_ops_lock);
1105+ return flow;
1106+}
1107+
1108+static int
1109+iavf_flow_destroy(struct rte_eth_dev *dev,
1110+ struct rte_flow *flow,
1111+ struct rte_flow_error *error)
1112+{
1113+ struct iavf_adapter *ad =
1114+ IAVF_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private);
1115+ struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(ad);
1116+ int ret = 0;
1117+
1118+ if (!flow || !flow->engine || !flow->engine->destroy) {
1119+ rte_flow_error_set(error, EINVAL,
1120+ RTE_FLOW_ERROR_TYPE_HANDLE,
1121+ NULL, "Invalid flow");
1122+ return -rte_errno;
1123+ }
1124+
1125+ rte_spinlock_lock(&vf->flow_ops_lock);
1126+
1127+ ret = flow->engine->destroy(ad, flow, error);
1128+
1129+ if (!ret) {
1130+ TAILQ_REMOVE(&vf->flow_list, flow, node);
1131+ rte_free(flow);
1132+ } else {
1133+ PMD_DRV_LOG(ERR, "Failed to destroy flow");
1134+ }
1135+
1136+ rte_spinlock_unlock(&vf->flow_ops_lock);
1137+
1138+ return ret;
1139+}
1140+
1141+static int
1142+iavf_flow_flush(struct rte_eth_dev *dev,
1143+ struct rte_flow_error *error)
1144+{
1145+ struct iavf_adapter *ad =
1146+ IAVF_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private);
1147+ struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(ad);
1148+ struct rte_flow *p_flow;
1149+ void *temp;
1150+ int ret = 0;
1151+
1152+ TAILQ_FOREACH_SAFE(p_flow, &vf->flow_list, node, temp) {
1153+ ret = iavf_flow_destroy(dev, p_flow, error);
1154+ if (ret) {
1155+ PMD_DRV_LOG(ERR, "Failed to flush flows");
1156+ return -EINVAL;
1157+ }
1158+ }
1159+
1160+ return ret;
1161+}
1162+
1163+static int
1164+iavf_flow_query(struct rte_eth_dev *dev,
1165+ struct rte_flow *flow,
1166+ const struct rte_flow_action *actions,
1167+ void *data,
1168+ struct rte_flow_error *error)
1169+{
1170+ int ret = -EINVAL;
1171+ struct iavf_adapter *ad =
1172+ IAVF_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private);
1173+ struct rte_flow_query_count *count = data;
1174+
1175+ if (!flow || !flow->engine || !flow->engine->query_count) {
1176+ rte_flow_error_set(error, EINVAL,
1177+ RTE_FLOW_ERROR_TYPE_HANDLE,
1178+ NULL, "Invalid flow");
1179+ return -rte_errno;
1180+ }
1181+
1182+ for (; actions->type != RTE_FLOW_ACTION_TYPE_END; actions++) {
1183+ switch (actions->type) {
1184+ case RTE_FLOW_ACTION_TYPE_VOID:
1185+ break;
1186+ case RTE_FLOW_ACTION_TYPE_COUNT:
1187+ ret = flow->engine->query_count(ad, flow, count, error);
1188+ break;
1189+ default:
1190+ return rte_flow_error_set(error, ENOTSUP,
1191+ RTE_FLOW_ERROR_TYPE_ACTION,
1192+ actions,
1193+ "action not supported");
1194+ }
1195+ }
1196+ return ret;
1197+}
1198diff --git a/drivers/net/iavf/iavf_generic_flow.h b/drivers/net/iavf/iavf_generic_flow.h
1199new file mode 100644
1200index 000000000..f4906b43a
1201--- /dev/null
1202+++ b/drivers/net/iavf/iavf_generic_flow.h
1203@@ -0,0 +1,313 @@
1204+/* SPDX-License-Identifier: BSD-3-Clause
1205+ * Copyright(c) 2019 Intel Corporation
1206+ */
1207+
1208+#ifndef _IAVF_GENERIC_FLOW_H_
1209+#define _IAVF_GENERIC_FLOW_H_
1210+
1211+#include <rte_flow_driver.h>
1212+
1213+/* protocol */
1214+
1215+#define IAVF_PROT_MAC_INNER (1ULL << 1)
1216+#define IAVF_PROT_MAC_OUTER (1ULL << 2)
1217+#define IAVF_PROT_VLAN_INNER (1ULL << 3)
1218+#define IAVF_PROT_VLAN_OUTER (1ULL << 4)
1219+#define IAVF_PROT_IPV4_INNER (1ULL << 5)
1220+#define IAVF_PROT_IPV4_OUTER (1ULL << 6)
1221+#define IAVF_PROT_IPV6_INNER (1ULL << 7)
1222+#define IAVF_PROT_IPV6_OUTER (1ULL << 8)
1223+#define IAVF_PROT_TCP_INNER (1ULL << 9)
1224+#define IAVF_PROT_TCP_OUTER (1ULL << 10)
1225+#define IAVF_PROT_UDP_INNER (1ULL << 11)
1226+#define IAVF_PROT_UDP_OUTER (1ULL << 12)
1227+#define IAVF_PROT_SCTP_INNER (1ULL << 13)
1228+#define IAVF_PROT_SCTP_OUTER (1ULL << 14)
1229+#define IAVF_PROT_ICMP4_INNER (1ULL << 15)
1230+#define IAVF_PROT_ICMP4_OUTER (1ULL << 16)
1231+#define IAVF_PROT_ICMP6_INNER (1ULL << 17)
1232+#define IAVF_PROT_ICMP6_OUTER (1ULL << 18)
1233+#define IAVF_PROT_VXLAN (1ULL << 19)
1234+#define IAVF_PROT_NVGRE (1ULL << 20)
1235+#define IAVF_PROT_GTPU (1ULL << 21)
1236+#define IAVF_PROT_ESP (1ULL << 22)
1237+#define IAVF_PROT_AH (1ULL << 23)
1238+#define IAVF_PROT_L2TPV3OIP (1ULL << 24)
1239+#define IAVF_PROT_PFCP (1ULL << 25)
1240+
1241+
1242+/* field */
1243+
1244+#define IAVF_SMAC (1ULL << 63)
1245+#define IAVF_DMAC (1ULL << 62)
1246+#define IAVF_ETHERTYPE (1ULL << 61)
1247+#define IAVF_IP_SRC (1ULL << 60)
1248+#define IAVF_IP_DST (1ULL << 59)
1249+#define IAVF_IP_PROTO (1ULL << 58)
1250+#define IAVF_IP_TTL (1ULL << 57)
1251+#define IAVF_IP_TOS (1ULL << 56)
1252+#define IAVF_SPORT (1ULL << 55)
1253+#define IAVF_DPORT (1ULL << 54)
1254+#define IAVF_ICMP_TYPE (1ULL << 53)
1255+#define IAVF_ICMP_CODE (1ULL << 52)
1256+#define IAVF_VXLAN_VNI (1ULL << 51)
1257+#define IAVF_NVGRE_TNI (1ULL << 50)
1258+#define IAVF_GTPU_TEID (1ULL << 49)
1259+#define IAVF_GTPU_QFI (1ULL << 48)
1260+#define IAVF_ESP_SPI (1ULL << 47)
1261+#define IAVF_AH_SPI (1ULL << 46)
1262+#define IAVF_L2TPV3OIP_SESSION_ID (1ULL << 45)
1263+#define IAVF_PFCP_S_FIELD (1ULL << 44)
1264+#define IAVF_PFCP_SEID (1ULL << 43)
1265+
1266+/* input set */
1267+
1268+#define IAVF_INSET_NONE 0ULL
1269+
1270+/* non-tunnel */
1271+
1272+#define IAVF_INSET_SMAC (IAVF_PROT_MAC_OUTER | IAVF_SMAC)
1273+#define IAVF_INSET_DMAC (IAVF_PROT_MAC_OUTER | IAVF_DMAC)
1274+#define IAVF_INSET_VLAN_INNER (IAVF_PROT_VLAN_INNER)
1275+#define IAVF_INSET_VLAN_OUTER (IAVF_PROT_VLAN_OUTER)
1276+#define IAVF_INSET_ETHERTYPE (IAVF_ETHERTYPE)
1277+
1278+#define IAVF_INSET_IPV4_SRC \
1279+ (IAVF_PROT_IPV4_OUTER | IAVF_IP_SRC)
1280+#define IAVF_INSET_IPV4_DST \
1281+ (IAVF_PROT_IPV4_OUTER | IAVF_IP_DST)
1282+#define IAVF_INSET_IPV4_TOS \
1283+ (IAVF_PROT_IPV4_OUTER | IAVF_IP_TOS)
1284+#define IAVF_INSET_IPV4_PROTO \
1285+ (IAVF_PROT_IPV4_OUTER | IAVF_IP_PROTO)
1286+#define IAVF_INSET_IPV4_TTL \
1287+ (IAVF_PROT_IPV4_OUTER | IAVF_IP_TTL)
1288+#define IAVF_INSET_IPV6_SRC \
1289+ (IAVF_PROT_IPV6_OUTER | IAVF_IP_SRC)
1290+#define IAVF_INSET_IPV6_DST \
1291+ (IAVF_PROT_IPV6_OUTER | IAVF_IP_DST)
1292+#define IAVF_INSET_IPV6_NEXT_HDR \
1293+ (IAVF_PROT_IPV6_OUTER | IAVF_IP_PROTO)
1294+#define IAVF_INSET_IPV6_HOP_LIMIT \
1295+ (IAVF_PROT_IPV6_OUTER | IAVF_IP_TTL)
1296+#define IAVF_INSET_IPV6_TC \
1297+ (IAVF_PROT_IPV6_OUTER | IAVF_IP_TOS)
1298+
1299+#define IAVF_INSET_TCP_SRC_PORT \
1300+ (IAVF_PROT_TCP_OUTER | IAVF_SPORT)
1301+#define IAVF_INSET_TCP_DST_PORT \
1302+ (IAVF_PROT_TCP_OUTER | IAVF_DPORT)
1303+#define IAVF_INSET_UDP_SRC_PORT \
1304+ (IAVF_PROT_UDP_OUTER | IAVF_SPORT)
1305+#define IAVF_INSET_UDP_DST_PORT \
1306+ (IAVF_PROT_UDP_OUTER | IAVF_DPORT)
1307+#define IAVF_INSET_SCTP_SRC_PORT \
1308+ (IAVF_PROT_SCTP_OUTER | IAVF_SPORT)
1309+#define IAVF_INSET_SCTP_DST_PORT \
1310+ (IAVF_PROT_SCTP_OUTER | IAVF_DPORT)
1311+#define IAVF_INSET_ICMP4_SRC_PORT \
1312+ (IAVF_PROT_ICMP4_OUTER | IAVF_SPORT)
1313+#define IAVF_INSET_ICMP4_DST_PORT \
1314+ (IAVF_PROT_ICMP4_OUTER | IAVF_DPORT)
1315+#define IAVF_INSET_ICMP6_SRC_PORT \
1316+ (IAVF_PROT_ICMP6_OUTER | IAVF_SPORT)
1317+#define IAVF_INSET_ICMP6_DST_PORT \
1318+ (IAVF_PROT_ICMP6_OUTER | IAVF_DPORT)
1319+#define IAVF_INSET_ICMP4_TYPE \
1320+ (IAVF_PROT_ICMP4_OUTER | IAVF_ICMP_TYPE)
1321+#define IAVF_INSET_ICMP4_CODE \
1322+ (IAVF_PROT_ICMP4_OUTER | IAVF_ICMP_CODE)
1323+#define IAVF_INSET_ICMP6_TYPE \
1324+ (IAVF_PROT_ICMP6_OUTER | IAVF_ICMP_TYPE)
1325+#define IAVF_INSET_ICMP6_CODE \
1326+ (IAVF_PROT_ICMP6_OUTER | IAVF_ICMP_CODE)
1327+#define IAVF_INSET_GTPU_TEID \
1328+ (IAVF_PROT_GTPU | IAVF_GTPU_TEID)
1329+#define IAVF_INSET_GTPU_QFI \
1330+ (IAVF_PROT_GTPU | IAVF_GTPU_QFI)
1331+#define IAVF_INSET_ESP_SPI \
1332+ (IAVF_PROT_ESP | IAVF_ESP_SPI)
1333+#define IAVF_INSET_AH_SPI \
1334+ (IAVF_PROT_AH | IAVF_AH_SPI)
1335+#define IAVF_INSET_L2TPV3OIP_SESSION_ID \
1336+ (IAVF_PROT_L2TPV3OIP | IAVF_L2TPV3OIP_SESSION_ID)
1337+#define IAVF_INSET_PFCP_S_FIELD \
1338+ (IAVF_PROT_PFCP | IAVF_PFCP_S_FIELD)
1339+#define IAVF_INSET_PFCP_SEID \
1340+ (IAVF_PROT_PFCP | IAVF_PFCP_S_FIELD | IAVF_PFCP_SEID)
1341+
1342+
1343+/* empty pattern */
1344+extern enum rte_flow_item_type iavf_pattern_empty[];
1345+
1346+/* L2 */
1347+extern enum rte_flow_item_type iavf_pattern_ethertype[];
1348+extern enum rte_flow_item_type iavf_pattern_ethertype_vlan[];
1349+extern enum rte_flow_item_type iavf_pattern_ethertype_qinq[];
1350+
1351+/* ARP */
1352+extern enum rte_flow_item_type iavf_pattern_eth_arp[];
1353+
1354+/* non-tunnel IPv4 */
1355+extern enum rte_flow_item_type iavf_pattern_eth_ipv4[];
1356+extern enum rte_flow_item_type iavf_pattern_eth_vlan_ipv4[];
1357+extern enum rte_flow_item_type iavf_pattern_eth_qinq_ipv4[];
1358+extern enum rte_flow_item_type iavf_pattern_eth_ipv4_udp[];
1359+extern enum rte_flow_item_type iavf_pattern_eth_vlan_ipv4_udp[];
1360+extern enum rte_flow_item_type iavf_pattern_eth_qinq_ipv4_udp[];
1361+extern enum rte_flow_item_type iavf_pattern_eth_ipv4_tcp[];
1362+extern enum rte_flow_item_type iavf_pattern_eth_vlan_ipv4_tcp[];
1363+extern enum rte_flow_item_type iavf_pattern_eth_qinq_ipv4_tcp[];
1364+extern enum rte_flow_item_type iavf_pattern_eth_ipv4_sctp[];
1365+extern enum rte_flow_item_type iavf_pattern_eth_vlan_ipv4_sctp[];
1366+extern enum rte_flow_item_type iavf_pattern_eth_qinq_ipv4_sctp[];
1367+extern enum rte_flow_item_type iavf_pattern_eth_ipv4_icmp[];
1368+extern enum rte_flow_item_type iavf_pattern_eth_vlan_ipv4_icmp[];
1369+extern enum rte_flow_item_type iavf_pattern_eth_qinq_ipv4_icmp[];
1370+
1371+/* non-tunnel IPv6 */
1372+extern enum rte_flow_item_type iavf_pattern_eth_ipv6[];
1373+extern enum rte_flow_item_type iavf_pattern_eth_vlan_ipv6[];
1374+extern enum rte_flow_item_type iavf_pattern_eth_qinq_ipv6[];
1375+extern enum rte_flow_item_type iavf_pattern_eth_ipv6_udp[];
1376+extern enum rte_flow_item_type iavf_pattern_eth_vlan_ipv6_udp[];
1377+extern enum rte_flow_item_type iavf_pattern_eth_qinq_ipv6_udp[];
1378+extern enum rte_flow_item_type iavf_pattern_eth_ipv6_tcp[];
1379+extern enum rte_flow_item_type iavf_pattern_eth_vlan_ipv6_tcp[];
1380+extern enum rte_flow_item_type iavf_pattern_eth_qinq_ipv6_tcp[];
1381+extern enum rte_flow_item_type iavf_pattern_eth_ipv6_sctp[];
1382+extern enum rte_flow_item_type iavf_pattern_eth_vlan_ipv6_sctp[];
1383+extern enum rte_flow_item_type iavf_pattern_eth_qinq_ipv6_sctp[];
1384+extern enum rte_flow_item_type iavf_pattern_eth_ipv6_icmp6[];
1385+extern enum rte_flow_item_type iavf_pattern_eth_vlan_ipv6_icmp6[];
1386+extern enum rte_flow_item_type iavf_pattern_eth_qinq_ipv6_icmp6[];
1387+
1388+/* GTPU */
1389+extern enum rte_flow_item_type iavf_pattern_eth_ipv4_gtpu[];
1390+extern enum rte_flow_item_type iavf_pattern_eth_ipv4_gtpu_ipv4[];
1391+extern enum rte_flow_item_type iavf_pattern_eth_ipv4_gtpu_eh[];
1392+extern enum rte_flow_item_type iavf_pattern_eth_ipv4_gtpu_eh_ipv4[];
1393+extern enum rte_flow_item_type iavf_pattern_eth_ipv4_gtpu_eh_ipv4_udp[];
1394+extern enum rte_flow_item_type iavf_pattern_eth_ipv4_gtpu_eh_ipv4_tcp[];
1395+extern enum rte_flow_item_type iavf_pattern_eth_ipv4_gtpu_eh_ipv4_icmp[];
1396+
1397+/* ESP */
1398+extern enum rte_flow_item_type iavf_pattern_eth_ipv4_esp[];
1399+extern enum rte_flow_item_type iavf_pattern_eth_ipv4_udp_esp[];
1400+extern enum rte_flow_item_type iavf_pattern_eth_ipv6_esp[];
1401+extern enum rte_flow_item_type iavf_pattern_eth_ipv6_udp_esp[];
1402+
1403+/* AH */
1404+extern enum rte_flow_item_type iavf_pattern_eth_ipv4_ah[];
1405+extern enum rte_flow_item_type iavf_pattern_eth_ipv6_ah[];
1406+
1407+/* L2TPV3 */
1408+extern enum rte_flow_item_type iavf_pattern_eth_ipv4_l2tpv3[];
1409+extern enum rte_flow_item_type iavf_pattern_eth_ipv6_l2tpv3[];
1410+
1411+extern const struct rte_flow_ops iavf_flow_ops;
1412+
1413+/* pattern structure */
1414+struct iavf_pattern_match_item {
1415+ enum rte_flow_item_type *pattern_list;
1416+ /* pattern_list must end with RTE_FLOW_ITEM_TYPE_END */
1417+ uint64_t input_set_mask;
1418+ void *meta;
1419+};
1420+
1421+typedef int (*engine_init_t)(struct iavf_adapter *ad);
1422+typedef void (*engine_uninit_t)(struct iavf_adapter *ad);
1423+typedef int (*engine_validation_t)(struct iavf_adapter *ad,
1424+ struct rte_flow *flow,
1425+ void *meta,
1426+ struct rte_flow_error *error);
1427+typedef int (*engine_create_t)(struct iavf_adapter *ad,
1428+ struct rte_flow *flow,
1429+ void *meta,
1430+ struct rte_flow_error *error);
1431+typedef int (*engine_destroy_t)(struct iavf_adapter *ad,
1432+ struct rte_flow *flow,
1433+ struct rte_flow_error *error);
1434+typedef int (*engine_query_t)(struct iavf_adapter *ad,
1435+ struct rte_flow *flow,
1436+ struct rte_flow_query_count *count,
1437+ struct rte_flow_error *error);
1438+typedef void (*engine_free_t) (struct rte_flow *flow);
1439+typedef int (*parse_pattern_action_t)(struct iavf_adapter *ad,
1440+ struct iavf_pattern_match_item *array,
1441+ uint32_t array_len,
1442+ const struct rte_flow_item pattern[],
1443+ const struct rte_flow_action actions[],
1444+ void **meta,
1445+ struct rte_flow_error *error);
1446+
1447+/* engine types. */
1448+enum iavf_flow_engine_type {
1449+ IAVF_FLOW_ENGINE_NONE = 0,
1450+ IAVF_FLOW_ENGINE_FDIR,
1451+ IAVF_FLOW_ENGINE_HASH,
1452+ IAVF_FLOW_ENGINE_MAX,
1453+};
1454+
1455+/**
1456+ * classification stages.
1457+ * for non-pipeline mode, we have two classification stages: Distributor/RSS
1458+ * for pipeline-mode we have three classification stages:
1459+ * Permission/Distributor/RSS
1460+ */
1461+enum iavf_flow_classification_stage {
1462+ IAVF_FLOW_STAGE_NONE = 0,
1463+ IAVF_FLOW_STAGE_RSS,
1464+ IAVF_FLOW_STAGE_DISTRIBUTOR,
1465+ IAVF_FLOW_STAGE_MAX,
1466+};
1467+
1468+/* Struct to store engine created. */
1469+struct iavf_flow_engine {
1470+ TAILQ_ENTRY(iavf_flow_engine) node;
1471+ engine_init_t init;
1472+ engine_uninit_t uninit;
1473+ engine_validation_t validation;
1474+ engine_create_t create;
1475+ engine_destroy_t destroy;
1476+ engine_query_t query_count;
1477+ engine_free_t free;
1478+ enum iavf_flow_engine_type type;
1479+};
1480+
1481+TAILQ_HEAD(iavf_engine_list, iavf_flow_engine);
1482+
1483+/* Struct to store flow created. */
1484+struct rte_flow {
1485+ TAILQ_ENTRY(rte_flow) node;
1486+ struct iavf_flow_engine *engine;
1487+ void *rule;
1488+};
1489+
1490+struct iavf_flow_parser {
1491+ struct iavf_flow_engine *engine;
1492+ struct iavf_pattern_match_item *array;
1493+ uint32_t array_len;
1494+ parse_pattern_action_t parse_pattern_action;
1495+ enum iavf_flow_classification_stage stage;
1496+};
1497+
1498+/* Struct to store parser created. */
1499+struct iavf_flow_parser_node {
1500+ TAILQ_ENTRY(iavf_flow_parser_node) node;
1501+ struct iavf_flow_parser *parser;
1502+};
1503+
1504+void iavf_register_flow_engine(struct iavf_flow_engine *engine);
1505+int iavf_flow_init(struct iavf_adapter *ad);
1506+void iavf_flow_uninit(struct iavf_adapter *ad);
1507+int iavf_register_parser(struct iavf_flow_parser *parser,
1508+ struct iavf_adapter *ad);
1509+void iavf_unregister_parser(struct iavf_flow_parser *parser,
1510+ struct iavf_adapter *ad);
1511+struct iavf_pattern_match_item *
1512+iavf_search_pattern_match_item(const struct rte_flow_item pattern[],
1513+ struct iavf_pattern_match_item *array,
1514+ uint32_t array_len,
1515+ struct rte_flow_error *error);
1516+#endif
1517diff --git a/drivers/net/iavf/meson.build b/drivers/net/iavf/meson.build
1518index dbd0b01db..32eabca4b 100644
1519--- a/drivers/net/iavf/meson.build
1520+++ b/drivers/net/iavf/meson.build
1521@@ -12,6 +12,7 @@ sources = files(
1522 'iavf_ethdev.c',
1523 'iavf_rxtx.c',
1524 'iavf_vchnl.c',
1525+ 'iavf_generic_flow.c',
1526 )
1527
1528 if arch_subdir == 'x86'
1529--
15302.17.1
1531