dpdk: DPDK 20.05 iavf flow director backporting to DPDK 20.02
[vpp.git] / build / external / patches / dpdk_20.02 / 0015-net-iavf-support-generic-flow.patch
1 From 0692e4be875c64c5d26f2e6df80bbb1a24df36a6 Mon Sep 17 00:00:00 2001
2 From: Chenmin Sun <chenmin.sun@intel.com>
3 Date: Fri, 17 Apr 2020 05:02:22 +0800
4 Subject: [DPDK 15/17] net/iavf: support generic flow
5
6 This patch added iavf_flow_create, iavf_flow_destroy,
7 iavf_flow_flush and iavf_flow_validate support,
8 these are used to handle all the generic filters.
9
10 This patch supported basic L2, L3, L4 and GTPU patterns.
11
12 Signed-off-by: Qiming Yang <qiming.yang@intel.com>
13 Acked-by: Qi Zhang <qi.z.zhang@intel.com>
14 Signed-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
27 diff --git a/doc/guides/nics/features/iavf.ini b/doc/guides/nics/features/iavf.ini
28 index 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
39 diff --git a/drivers/net/iavf/Makefile b/drivers/net/iavf/Makefile
40 index 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
51 diff --git a/drivers/net/iavf/iavf.h b/drivers/net/iavf/iavf.h
52 index 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
79 diff --git a/drivers/net/iavf/iavf_ethdev.c b/drivers/net/iavf/iavf_ethdev.c
80 index 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
184 diff --git a/drivers/net/iavf/iavf_generic_flow.c b/drivers/net/iavf/iavf_generic_flow.c
185 new file mode 100644
186 index 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 +}
1198 diff --git a/drivers/net/iavf/iavf_generic_flow.h b/drivers/net/iavf/iavf_generic_flow.h
1199 new file mode 100644
1200 index 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
1517 diff --git a/drivers/net/iavf/meson.build b/drivers/net/iavf/meson.build
1518 index 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 -- 
1530 2.17.1
1531