eal: set name when creating a control thread
[dpdk.git] / drivers / net / e1000 / igb_flow.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2010-2016 Intel Corporation
3  */
4
5 #include <sys/queue.h>
6 #include <stdio.h>
7 #include <errno.h>
8 #include <stdint.h>
9 #include <stdarg.h>
10
11 #include <rte_common.h>
12 #include <rte_interrupts.h>
13 #include <rte_byteorder.h>
14 #include <rte_log.h>
15 #include <rte_debug.h>
16 #include <rte_pci.h>
17 #include <rte_ether.h>
18 #include <rte_ethdev_driver.h>
19 #include <rte_ethdev_pci.h>
20 #include <rte_memory.h>
21 #include <rte_eal.h>
22 #include <rte_atomic.h>
23 #include <rte_malloc.h>
24 #include <rte_dev.h>
25 #include <rte_flow.h>
26 #include <rte_flow_driver.h>
27
28 #include "e1000_logs.h"
29 #include "base/e1000_api.h"
30 #include "e1000_ethdev.h"
31
32 #define NEXT_ITEM_OF_PATTERN(item, pattern, index)              \
33         do {                                                    \
34                 item = (pattern) + (index);                     \
35                 while (item->type == RTE_FLOW_ITEM_TYPE_VOID) { \
36                 (index)++;                                      \
37                 item = (pattern) + (index);                     \
38                 }                                               \
39         } while (0)
40
41 #define NEXT_ITEM_OF_ACTION(act, actions, index)                \
42         do {                                                    \
43                 act = (actions) + (index);                      \
44                 while (act->type == RTE_FLOW_ACTION_TYPE_VOID) {\
45                 (index)++;                                      \
46                 act = (actions) + (index);                      \
47                 }                                               \
48         } while (0)
49
50 #define IGB_FLEX_RAW_NUM        12
51
52 /**
53  * Please aware there's an asumption for all the parsers.
54  * rte_flow_item is using big endian, rte_flow_attr and
55  * rte_flow_action are using CPU order.
56  * Because the pattern is used to describe the packets,
57  * normally the packets should use network order.
58  */
59
60 /**
61  * Parse the rule to see if it is a n-tuple rule.
62  * And get the n-tuple filter info BTW.
63  * pattern:
64  * The first not void item can be ETH or IPV4.
65  * The second not void item must be IPV4 if the first one is ETH.
66  * The third not void item must be UDP or TCP or SCTP
67  * The next not void item must be END.
68  * action:
69  * The first not void action should be QUEUE.
70  * The next not void action should be END.
71  * pattern example:
72  * ITEM         Spec                    Mask
73  * ETH          NULL                    NULL
74  * IPV4         src_addr 192.168.1.20   0xFFFFFFFF
75  *                      dst_addr 192.167.3.50   0xFFFFFFFF
76  *                      next_proto_id   17      0xFF
77  * UDP/TCP/     src_port        80      0xFFFF
78  * SCTP         dst_port        80      0xFFFF
79  * END
80  * other members in mask and spec should set to 0x00.
81  * item->last should be NULL.
82  */
83 static int
84 cons_parse_ntuple_filter(const struct rte_flow_attr *attr,
85                          const struct rte_flow_item pattern[],
86                          const struct rte_flow_action actions[],
87                          struct rte_eth_ntuple_filter *filter,
88                          struct rte_flow_error *error)
89 {
90         const struct rte_flow_item *item;
91         const struct rte_flow_action *act;
92         const struct rte_flow_item_ipv4 *ipv4_spec;
93         const struct rte_flow_item_ipv4 *ipv4_mask;
94         const struct rte_flow_item_tcp *tcp_spec;
95         const struct rte_flow_item_tcp *tcp_mask;
96         const struct rte_flow_item_udp *udp_spec;
97         const struct rte_flow_item_udp *udp_mask;
98         const struct rte_flow_item_sctp *sctp_spec;
99         const struct rte_flow_item_sctp *sctp_mask;
100         uint32_t index;
101
102         if (!pattern) {
103                 rte_flow_error_set(error,
104                         EINVAL, RTE_FLOW_ERROR_TYPE_ITEM_NUM,
105                         NULL, "NULL pattern.");
106                 return -rte_errno;
107         }
108
109         if (!actions) {
110                 rte_flow_error_set(error, EINVAL,
111                                    RTE_FLOW_ERROR_TYPE_ACTION_NUM,
112                                    NULL, "NULL action.");
113                 return -rte_errno;
114         }
115         if (!attr) {
116                 rte_flow_error_set(error, EINVAL,
117                                    RTE_FLOW_ERROR_TYPE_ATTR,
118                                    NULL, "NULL attribute.");
119                 return -rte_errno;
120         }
121
122         /* parse pattern */
123         index = 0;
124
125         /* the first not void item can be MAC or IPv4 */
126         NEXT_ITEM_OF_PATTERN(item, pattern, index);
127
128         if (item->type != RTE_FLOW_ITEM_TYPE_ETH &&
129             item->type != RTE_FLOW_ITEM_TYPE_IPV4) {
130                 rte_flow_error_set(error, EINVAL,
131                         RTE_FLOW_ERROR_TYPE_ITEM,
132                         item, "Not supported by ntuple filter");
133                 return -rte_errno;
134         }
135         /* Skip Ethernet */
136         if (item->type == RTE_FLOW_ITEM_TYPE_ETH) {
137                 /*Not supported last point for range*/
138                 if (item->last) {
139                         rte_flow_error_set(error,
140                           EINVAL,
141                           RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
142                           item, "Not supported last point for range");
143                         return -rte_errno;
144                 }
145                 /* if the first item is MAC, the content should be NULL */
146                 if (item->spec || item->mask) {
147                         rte_flow_error_set(error, EINVAL,
148                                 RTE_FLOW_ERROR_TYPE_ITEM,
149                                 item, "Not supported by ntuple filter");
150                         return -rte_errno;
151                 }
152                 /* check if the next not void item is IPv4 */
153                 index++;
154                 NEXT_ITEM_OF_PATTERN(item, pattern, index);
155                 if (item->type != RTE_FLOW_ITEM_TYPE_IPV4) {
156                         rte_flow_error_set(error,
157                           EINVAL, RTE_FLOW_ERROR_TYPE_ITEM,
158                           item, "Not supported by ntuple filter");
159                         return -rte_errno;
160                 }
161         }
162
163         /* get the IPv4 info */
164         if (!item->spec || !item->mask) {
165                 rte_flow_error_set(error, EINVAL,
166                         RTE_FLOW_ERROR_TYPE_ITEM,
167                         item, "Invalid ntuple mask");
168                 return -rte_errno;
169         }
170         /* Not supported last point for range */
171         if (item->last) {
172                 rte_flow_error_set(error, EINVAL,
173                         RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
174                         item, "Not supported last point for range");
175                 return -rte_errno;
176         }
177
178         ipv4_mask = item->mask;
179         /**
180          * Only support src & dst addresses, protocol,
181          * others should be masked.
182          */
183
184         if (ipv4_mask->hdr.version_ihl ||
185                 ipv4_mask->hdr.type_of_service ||
186                 ipv4_mask->hdr.total_length ||
187                 ipv4_mask->hdr.packet_id ||
188                 ipv4_mask->hdr.fragment_offset ||
189                 ipv4_mask->hdr.time_to_live ||
190                 ipv4_mask->hdr.hdr_checksum) {
191                 rte_flow_error_set(error,
192                         EINVAL, RTE_FLOW_ERROR_TYPE_ITEM,
193                         item, "Not supported by ntuple filter");
194                 return -rte_errno;
195         }
196
197         filter->dst_ip_mask = ipv4_mask->hdr.dst_addr;
198         filter->src_ip_mask = ipv4_mask->hdr.src_addr;
199         filter->proto_mask  = ipv4_mask->hdr.next_proto_id;
200
201         ipv4_spec = item->spec;
202         filter->dst_ip = ipv4_spec->hdr.dst_addr;
203         filter->src_ip = ipv4_spec->hdr.src_addr;
204         filter->proto  = ipv4_spec->hdr.next_proto_id;
205
206         /* check if the next not void item is TCP or UDP or SCTP */
207         index++;
208         NEXT_ITEM_OF_PATTERN(item, pattern, index);
209         if (item->type != RTE_FLOW_ITEM_TYPE_TCP &&
210             item->type != RTE_FLOW_ITEM_TYPE_UDP &&
211             item->type != RTE_FLOW_ITEM_TYPE_SCTP) {
212                 memset(filter, 0, sizeof(struct rte_eth_ntuple_filter));
213                 rte_flow_error_set(error, EINVAL,
214                         RTE_FLOW_ERROR_TYPE_ITEM,
215                         item, "Not supported by ntuple filter");
216                 return -rte_errno;
217         }
218
219         /* Not supported last point for range */
220         if (item->last) {
221                 memset(filter, 0, sizeof(struct rte_eth_ntuple_filter));
222                 rte_flow_error_set(error, EINVAL,
223                         RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
224                         item, "Not supported last point for range");
225                 return -rte_errno;
226         }
227
228         /* get the TCP/UDP/SCTP info */
229         if (item->type == RTE_FLOW_ITEM_TYPE_TCP) {
230                 if (item->spec && item->mask) {
231                         tcp_mask = item->mask;
232
233                         /**
234                          * Only support src & dst ports, tcp flags,
235                          * others should be masked.
236                          */
237                         if (tcp_mask->hdr.sent_seq ||
238                                 tcp_mask->hdr.recv_ack ||
239                                 tcp_mask->hdr.data_off ||
240                                 tcp_mask->hdr.rx_win ||
241                                 tcp_mask->hdr.cksum ||
242                                 tcp_mask->hdr.tcp_urp) {
243                                 memset(filter, 0,
244                                         sizeof(struct rte_eth_ntuple_filter));
245                                 rte_flow_error_set(error, EINVAL,
246                                         RTE_FLOW_ERROR_TYPE_ITEM,
247                                         item, "Not supported by ntuple filter");
248                                 return -rte_errno;
249                         }
250
251                         filter->dst_port_mask  = tcp_mask->hdr.dst_port;
252                         filter->src_port_mask  = tcp_mask->hdr.src_port;
253                         if (tcp_mask->hdr.tcp_flags == 0xFF) {
254                                 filter->flags |= RTE_NTUPLE_FLAGS_TCP_FLAG;
255                         } else if (!tcp_mask->hdr.tcp_flags) {
256                                 filter->flags &= ~RTE_NTUPLE_FLAGS_TCP_FLAG;
257                         } else {
258                                 memset(filter, 0,
259                                         sizeof(struct rte_eth_ntuple_filter));
260                                 rte_flow_error_set(error, EINVAL,
261                                         RTE_FLOW_ERROR_TYPE_ITEM,
262                                         item, "Not supported by ntuple filter");
263                                 return -rte_errno;
264                         }
265
266                         tcp_spec = item->spec;
267                         filter->dst_port  = tcp_spec->hdr.dst_port;
268                         filter->src_port  = tcp_spec->hdr.src_port;
269                         filter->tcp_flags = tcp_spec->hdr.tcp_flags;
270                 }
271         } else if (item->type == RTE_FLOW_ITEM_TYPE_UDP) {
272                 if (item->spec && item->mask) {
273                         udp_mask = item->mask;
274
275                         /**
276                          * Only support src & dst ports,
277                          * others should be masked.
278                          */
279                         if (udp_mask->hdr.dgram_len ||
280                             udp_mask->hdr.dgram_cksum) {
281                                 memset(filter, 0,
282                                         sizeof(struct rte_eth_ntuple_filter));
283                                 rte_flow_error_set(error, EINVAL,
284                                         RTE_FLOW_ERROR_TYPE_ITEM,
285                                         item, "Not supported by ntuple filter");
286                                 return -rte_errno;
287                         }
288
289                         filter->dst_port_mask = udp_mask->hdr.dst_port;
290                         filter->src_port_mask = udp_mask->hdr.src_port;
291
292                         udp_spec = item->spec;
293                         filter->dst_port = udp_spec->hdr.dst_port;
294                         filter->src_port = udp_spec->hdr.src_port;
295                 }
296         } else {
297                 if (item->spec && item->mask) {
298                         sctp_mask = item->mask;
299
300                         /**
301                          * Only support src & dst ports,
302                          * others should be masked.
303                          */
304                         if (sctp_mask->hdr.tag ||
305                             sctp_mask->hdr.cksum) {
306                                 memset(filter, 0,
307                                         sizeof(struct rte_eth_ntuple_filter));
308                                 rte_flow_error_set(error, EINVAL,
309                                         RTE_FLOW_ERROR_TYPE_ITEM,
310                                         item, "Not supported by ntuple filter");
311                                 return -rte_errno;
312                         }
313
314                         filter->dst_port_mask = sctp_mask->hdr.dst_port;
315                         filter->src_port_mask = sctp_mask->hdr.src_port;
316
317                         sctp_spec = (const struct rte_flow_item_sctp *)
318                                         item->spec;
319                         filter->dst_port = sctp_spec->hdr.dst_port;
320                         filter->src_port = sctp_spec->hdr.src_port;
321                 }
322         }
323         /* check if the next not void item is END */
324         index++;
325         NEXT_ITEM_OF_PATTERN(item, pattern, index);
326         if (item->type != RTE_FLOW_ITEM_TYPE_END) {
327                 memset(filter, 0, sizeof(struct rte_eth_ntuple_filter));
328                 rte_flow_error_set(error, EINVAL,
329                         RTE_FLOW_ERROR_TYPE_ITEM,
330                         item, "Not supported by ntuple filter");
331                 return -rte_errno;
332         }
333
334         /* parse action */
335         index = 0;
336
337         /**
338          * n-tuple only supports forwarding,
339          * check if the first not void action is QUEUE.
340          */
341         NEXT_ITEM_OF_ACTION(act, actions, index);
342         if (act->type != RTE_FLOW_ACTION_TYPE_QUEUE) {
343                 memset(filter, 0, sizeof(struct rte_eth_ntuple_filter));
344                 rte_flow_error_set(error, EINVAL,
345                         RTE_FLOW_ERROR_TYPE_ACTION,
346                         item, "Not supported action.");
347                 return -rte_errno;
348         }
349         filter->queue =
350                 ((const struct rte_flow_action_queue *)act->conf)->index;
351
352         /* check if the next not void item is END */
353         index++;
354         NEXT_ITEM_OF_ACTION(act, actions, index);
355         if (act->type != RTE_FLOW_ACTION_TYPE_END) {
356                 memset(filter, 0, sizeof(struct rte_eth_ntuple_filter));
357                 rte_flow_error_set(error, EINVAL,
358                         RTE_FLOW_ERROR_TYPE_ACTION,
359                         act, "Not supported action.");
360                 return -rte_errno;
361         }
362
363         /* parse attr */
364         /* must be input direction */
365         if (!attr->ingress) {
366                 memset(filter, 0, sizeof(struct rte_eth_ntuple_filter));
367                 rte_flow_error_set(error, EINVAL,
368                                    RTE_FLOW_ERROR_TYPE_ATTR_INGRESS,
369                                    attr, "Only support ingress.");
370                 return -rte_errno;
371         }
372
373         /* not supported */
374         if (attr->egress) {
375                 memset(filter, 0, sizeof(struct rte_eth_ntuple_filter));
376                 rte_flow_error_set(error, EINVAL,
377                                    RTE_FLOW_ERROR_TYPE_ATTR_EGRESS,
378                                    attr, "Not support egress.");
379                 return -rte_errno;
380         }
381
382         if (attr->priority > 0xFFFF) {
383                 memset(filter, 0, sizeof(struct rte_eth_ntuple_filter));
384                 rte_flow_error_set(error, EINVAL,
385                                    RTE_FLOW_ERROR_TYPE_ATTR_PRIORITY,
386                                    attr, "Error priority.");
387                 return -rte_errno;
388         }
389         filter->priority = (uint16_t)attr->priority;
390
391         return 0;
392 }
393
394 /* a specific function for igb because the flags is specific */
395 static int
396 igb_parse_ntuple_filter(struct rte_eth_dev *dev,
397                           const struct rte_flow_attr *attr,
398                           const struct rte_flow_item pattern[],
399                           const struct rte_flow_action actions[],
400                           struct rte_eth_ntuple_filter *filter,
401                           struct rte_flow_error *error)
402 {
403         struct e1000_hw *hw = E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);
404         int ret;
405
406         MAC_TYPE_FILTER_SUP(hw->mac.type);
407
408         ret = cons_parse_ntuple_filter(attr, pattern, actions, filter, error);
409
410         if (ret)
411                 return ret;
412
413         /* Igb doesn't support many priorities. */
414         if (filter->priority > E1000_2TUPLE_MAX_PRI) {
415                 memset(filter, 0, sizeof(struct rte_eth_ntuple_filter));
416                 rte_flow_error_set(error, EINVAL,
417                         RTE_FLOW_ERROR_TYPE_ITEM,
418                         NULL, "Priority not supported by ntuple filter");
419                 return -rte_errno;
420         }
421
422         if (hw->mac.type == e1000_82576) {
423                 if (filter->queue >= IGB_MAX_RX_QUEUE_NUM_82576) {
424                         memset(filter, 0, sizeof(struct rte_eth_ntuple_filter));
425                         rte_flow_error_set(error, EINVAL,
426                                 RTE_FLOW_ERROR_TYPE_ITEM,
427                                 NULL, "queue number not "
428                                 "supported by ntuple filter");
429                         return -rte_errno;
430                 }
431                 filter->flags |= RTE_5TUPLE_FLAGS;
432         } else {
433                 if (filter->src_ip_mask || filter->dst_ip_mask ||
434                         filter->src_port_mask) {
435                         memset(filter, 0, sizeof(struct rte_eth_ntuple_filter));
436                         rte_flow_error_set(error, EINVAL,
437                                 RTE_FLOW_ERROR_TYPE_ITEM,
438                                 NULL, "only two tuple are "
439                                 "supported by this filter");
440                         return -rte_errno;
441                 }
442                 if (filter->queue >= IGB_MAX_RX_QUEUE_NUM) {
443                         memset(filter, 0, sizeof(struct rte_eth_ntuple_filter));
444                         rte_flow_error_set(error, EINVAL,
445                                 RTE_FLOW_ERROR_TYPE_ITEM,
446                                 NULL, "queue number not "
447                                 "supported by ntuple filter");
448                         return -rte_errno;
449                 }
450                 filter->flags |= RTE_2TUPLE_FLAGS;
451         }
452
453         return 0;
454 }
455
456 /**
457  * Parse the rule to see if it is a ethertype rule.
458  * And get the ethertype filter info BTW.
459  * pattern:
460  * The first not void item can be ETH.
461  * The next not void item must be END.
462  * action:
463  * The first not void action should be QUEUE.
464  * The next not void action should be END.
465  * pattern example:
466  * ITEM         Spec                    Mask
467  * ETH          type    0x0807          0xFFFF
468  * END
469  * other members in mask and spec should set to 0x00.
470  * item->last should be NULL.
471  */
472 static int
473 cons_parse_ethertype_filter(const struct rte_flow_attr *attr,
474                             const struct rte_flow_item *pattern,
475                             const struct rte_flow_action *actions,
476                             struct rte_eth_ethertype_filter *filter,
477                             struct rte_flow_error *error)
478 {
479         const struct rte_flow_item *item;
480         const struct rte_flow_action *act;
481         const struct rte_flow_item_eth *eth_spec;
482         const struct rte_flow_item_eth *eth_mask;
483         const struct rte_flow_action_queue *act_q;
484         uint32_t index;
485
486         if (!pattern) {
487                 rte_flow_error_set(error, EINVAL,
488                                 RTE_FLOW_ERROR_TYPE_ITEM_NUM,
489                                 NULL, "NULL pattern.");
490                 return -rte_errno;
491         }
492
493         if (!actions) {
494                 rte_flow_error_set(error, EINVAL,
495                                 RTE_FLOW_ERROR_TYPE_ACTION_NUM,
496                                 NULL, "NULL action.");
497                 return -rte_errno;
498         }
499
500         if (!attr) {
501                 rte_flow_error_set(error, EINVAL,
502                                    RTE_FLOW_ERROR_TYPE_ATTR,
503                                    NULL, "NULL attribute.");
504                 return -rte_errno;
505         }
506
507         /* Parse pattern */
508         index = 0;
509
510         /* The first non-void item should be MAC. */
511         NEXT_ITEM_OF_PATTERN(item, pattern, index);
512         if (item->type != RTE_FLOW_ITEM_TYPE_ETH) {
513                 rte_flow_error_set(error, EINVAL,
514                         RTE_FLOW_ERROR_TYPE_ITEM,
515                         item, "Not supported by ethertype filter");
516                 return -rte_errno;
517         }
518
519         /*Not supported last point for range*/
520         if (item->last) {
521                 rte_flow_error_set(error, EINVAL,
522                         RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
523                         item, "Not supported last point for range");
524                 return -rte_errno;
525         }
526
527         /* Get the MAC info. */
528         if (!item->spec || !item->mask) {
529                 rte_flow_error_set(error, EINVAL,
530                                 RTE_FLOW_ERROR_TYPE_ITEM,
531                                 item, "Not supported by ethertype filter");
532                 return -rte_errno;
533         }
534
535         eth_spec = item->spec;
536         eth_mask = item->mask;
537
538         /* Mask bits of source MAC address must be full of 0.
539          * Mask bits of destination MAC address must be full
540          * of 1 or full of 0.
541          */
542         if (!is_zero_ether_addr(&eth_mask->src) ||
543             (!is_zero_ether_addr(&eth_mask->dst) &&
544              !is_broadcast_ether_addr(&eth_mask->dst))) {
545                 rte_flow_error_set(error, EINVAL,
546                                 RTE_FLOW_ERROR_TYPE_ITEM,
547                                 item, "Invalid ether address mask");
548                 return -rte_errno;
549         }
550
551         if ((eth_mask->type & UINT16_MAX) != UINT16_MAX) {
552                 rte_flow_error_set(error, EINVAL,
553                                 RTE_FLOW_ERROR_TYPE_ITEM,
554                                 item, "Invalid ethertype mask");
555                 return -rte_errno;
556         }
557
558         /* If mask bits of destination MAC address
559          * are full of 1, set RTE_ETHTYPE_FLAGS_MAC.
560          */
561         if (is_broadcast_ether_addr(&eth_mask->dst)) {
562                 filter->mac_addr = eth_spec->dst;
563                 filter->flags |= RTE_ETHTYPE_FLAGS_MAC;
564         } else {
565                 filter->flags &= ~RTE_ETHTYPE_FLAGS_MAC;
566         }
567         filter->ether_type = rte_be_to_cpu_16(eth_spec->type);
568
569         /* Check if the next non-void item is END. */
570         index++;
571         NEXT_ITEM_OF_PATTERN(item, pattern, index);
572         if (item->type != RTE_FLOW_ITEM_TYPE_END) {
573                 rte_flow_error_set(error, EINVAL,
574                                 RTE_FLOW_ERROR_TYPE_ITEM,
575                                 item, "Not supported by ethertype filter.");
576                 return -rte_errno;
577         }
578
579         /* Parse action */
580
581         index = 0;
582         /* Check if the first non-void action is QUEUE or DROP. */
583         NEXT_ITEM_OF_ACTION(act, actions, index);
584         if (act->type != RTE_FLOW_ACTION_TYPE_QUEUE &&
585             act->type != RTE_FLOW_ACTION_TYPE_DROP) {
586                 rte_flow_error_set(error, EINVAL,
587                                 RTE_FLOW_ERROR_TYPE_ACTION,
588                                 act, "Not supported action.");
589                 return -rte_errno;
590         }
591
592         if (act->type == RTE_FLOW_ACTION_TYPE_QUEUE) {
593                 act_q = (const struct rte_flow_action_queue *)act->conf;
594                 filter->queue = act_q->index;
595         } else {
596                 filter->flags |= RTE_ETHTYPE_FLAGS_DROP;
597         }
598
599         /* Check if the next non-void item is END */
600         index++;
601         NEXT_ITEM_OF_ACTION(act, actions, index);
602         if (act->type != RTE_FLOW_ACTION_TYPE_END) {
603                 rte_flow_error_set(error, EINVAL,
604                                 RTE_FLOW_ERROR_TYPE_ACTION,
605                                 act, "Not supported action.");
606                 return -rte_errno;
607         }
608
609         /* Parse attr */
610         /* Must be input direction */
611         if (!attr->ingress) {
612                 rte_flow_error_set(error, EINVAL,
613                                 RTE_FLOW_ERROR_TYPE_ATTR_INGRESS,
614                                 attr, "Only support ingress.");
615                 return -rte_errno;
616         }
617
618         /* Not supported */
619         if (attr->egress) {
620                 rte_flow_error_set(error, EINVAL,
621                                 RTE_FLOW_ERROR_TYPE_ATTR_EGRESS,
622                                 attr, "Not support egress.");
623                 return -rte_errno;
624         }
625
626         /* Not supported */
627         if (attr->priority) {
628                 rte_flow_error_set(error, EINVAL,
629                                 RTE_FLOW_ERROR_TYPE_ATTR_PRIORITY,
630                                 attr, "Not support priority.");
631                 return -rte_errno;
632         }
633
634         /* Not supported */
635         if (attr->group) {
636                 rte_flow_error_set(error, EINVAL,
637                                 RTE_FLOW_ERROR_TYPE_ATTR_GROUP,
638                                 attr, "Not support group.");
639                 return -rte_errno;
640         }
641
642         return 0;
643 }
644
645 static int
646 igb_parse_ethertype_filter(struct rte_eth_dev *dev,
647                                  const struct rte_flow_attr *attr,
648                              const struct rte_flow_item pattern[],
649                              const struct rte_flow_action actions[],
650                              struct rte_eth_ethertype_filter *filter,
651                              struct rte_flow_error *error)
652 {
653         struct e1000_hw *hw = E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);
654         int ret;
655
656         MAC_TYPE_FILTER_SUP(hw->mac.type);
657
658         ret = cons_parse_ethertype_filter(attr, pattern,
659                                         actions, filter, error);
660
661         if (ret)
662                 return ret;
663
664         if (hw->mac.type == e1000_82576) {
665                 if (filter->queue >= IGB_MAX_RX_QUEUE_NUM_82576) {
666                         memset(filter, 0, sizeof(
667                                         struct rte_eth_ethertype_filter));
668                         rte_flow_error_set(error, EINVAL,
669                                 RTE_FLOW_ERROR_TYPE_ITEM,
670                                 NULL, "queue number not supported "
671                                         "by ethertype filter");
672                         return -rte_errno;
673                 }
674         } else {
675                 if (filter->queue >= IGB_MAX_RX_QUEUE_NUM) {
676                         memset(filter, 0, sizeof(
677                                         struct rte_eth_ethertype_filter));
678                         rte_flow_error_set(error, EINVAL,
679                                 RTE_FLOW_ERROR_TYPE_ITEM,
680                                 NULL, "queue number not supported "
681                                         "by ethertype filter");
682                         return -rte_errno;
683                 }
684         }
685
686         if (filter->ether_type == ETHER_TYPE_IPv4 ||
687                 filter->ether_type == ETHER_TYPE_IPv6) {
688                 memset(filter, 0, sizeof(struct rte_eth_ethertype_filter));
689                 rte_flow_error_set(error, EINVAL,
690                         RTE_FLOW_ERROR_TYPE_ITEM,
691                         NULL, "IPv4/IPv6 not supported by ethertype filter");
692                 return -rte_errno;
693         }
694
695         if (filter->flags & RTE_ETHTYPE_FLAGS_MAC) {
696                 memset(filter, 0, sizeof(struct rte_eth_ethertype_filter));
697                 rte_flow_error_set(error, EINVAL,
698                         RTE_FLOW_ERROR_TYPE_ITEM,
699                         NULL, "mac compare is unsupported");
700                 return -rte_errno;
701         }
702
703         if (filter->flags & RTE_ETHTYPE_FLAGS_DROP) {
704                 memset(filter, 0, sizeof(struct rte_eth_ethertype_filter));
705                 rte_flow_error_set(error, EINVAL,
706                         RTE_FLOW_ERROR_TYPE_ITEM,
707                         NULL, "drop option is unsupported");
708                 return -rte_errno;
709         }
710
711         return 0;
712 }
713
714 /**
715  * Parse the rule to see if it is a TCP SYN rule.
716  * And get the TCP SYN filter info BTW.
717  * pattern:
718  * The first not void item must be ETH.
719  * The second not void item must be IPV4 or IPV6.
720  * The third not void item must be TCP.
721  * The next not void item must be END.
722  * action:
723  * The first not void action should be QUEUE.
724  * The next not void action should be END.
725  * pattern example:
726  * ITEM         Spec                    Mask
727  * ETH          NULL                    NULL
728  * IPV4/IPV6    NULL                    NULL
729  * TCP          tcp_flags       0x02    0xFF
730  * END
731  * other members in mask and spec should set to 0x00.
732  * item->last should be NULL.
733  */
734 static int
735 cons_parse_syn_filter(const struct rte_flow_attr *attr,
736                                 const struct rte_flow_item pattern[],
737                                 const struct rte_flow_action actions[],
738                                 struct rte_eth_syn_filter *filter,
739                                 struct rte_flow_error *error)
740 {
741         const struct rte_flow_item *item;
742         const struct rte_flow_action *act;
743         const struct rte_flow_item_tcp *tcp_spec;
744         const struct rte_flow_item_tcp *tcp_mask;
745         const struct rte_flow_action_queue *act_q;
746         uint32_t index;
747
748         if (!pattern) {
749                 rte_flow_error_set(error, EINVAL,
750                                 RTE_FLOW_ERROR_TYPE_ITEM_NUM,
751                                 NULL, "NULL pattern.");
752                 return -rte_errno;
753         }
754
755         if (!actions) {
756                 rte_flow_error_set(error, EINVAL,
757                                 RTE_FLOW_ERROR_TYPE_ACTION_NUM,
758                                 NULL, "NULL action.");
759                 return -rte_errno;
760         }
761
762         if (!attr) {
763                 rte_flow_error_set(error, EINVAL,
764                                    RTE_FLOW_ERROR_TYPE_ATTR,
765                                    NULL, "NULL attribute.");
766                 return -rte_errno;
767         }
768
769         /* parse pattern */
770         index = 0;
771
772         /* the first not void item should be MAC or IPv4 or IPv6 or TCP */
773         NEXT_ITEM_OF_PATTERN(item, pattern, index);
774         if (item->type != RTE_FLOW_ITEM_TYPE_ETH &&
775             item->type != RTE_FLOW_ITEM_TYPE_IPV4 &&
776             item->type != RTE_FLOW_ITEM_TYPE_IPV6 &&
777             item->type != RTE_FLOW_ITEM_TYPE_TCP) {
778                 rte_flow_error_set(error, EINVAL,
779                                 RTE_FLOW_ERROR_TYPE_ITEM,
780                                 item, "Not supported by syn filter");
781                 return -rte_errno;
782         }
783                 /*Not supported last point for range*/
784         if (item->last) {
785                 rte_flow_error_set(error, EINVAL,
786                         RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
787                         item, "Not supported last point for range");
788                 return -rte_errno;
789         }
790
791         /* Skip Ethernet */
792         if (item->type == RTE_FLOW_ITEM_TYPE_ETH) {
793                 /* if the item is MAC, the content should be NULL */
794                 if (item->spec || item->mask) {
795                         rte_flow_error_set(error, EINVAL,
796                                 RTE_FLOW_ERROR_TYPE_ITEM,
797                                 item, "Invalid SYN address mask");
798                         return -rte_errno;
799                 }
800
801                 /* check if the next not void item is IPv4 or IPv6 */
802                 index++;
803                 NEXT_ITEM_OF_PATTERN(item, pattern, index);
804                 if (item->type != RTE_FLOW_ITEM_TYPE_IPV4 &&
805                     item->type != RTE_FLOW_ITEM_TYPE_IPV6) {
806                         rte_flow_error_set(error, EINVAL,
807                                 RTE_FLOW_ERROR_TYPE_ITEM,
808                                 item, "Not supported by syn filter");
809                         return -rte_errno;
810                 }
811         }
812
813         /* Skip IP */
814         if (item->type == RTE_FLOW_ITEM_TYPE_IPV4 ||
815             item->type == RTE_FLOW_ITEM_TYPE_IPV6) {
816                 /* if the item is IP, the content should be NULL */
817                 if (item->spec || item->mask) {
818                         rte_flow_error_set(error, EINVAL,
819                                 RTE_FLOW_ERROR_TYPE_ITEM,
820                                 item, "Invalid SYN mask");
821                         return -rte_errno;
822                 }
823
824                 /* check if the next not void item is TCP */
825                 index++;
826                 NEXT_ITEM_OF_PATTERN(item, pattern, index);
827                 if (item->type != RTE_FLOW_ITEM_TYPE_TCP) {
828                         rte_flow_error_set(error, EINVAL,
829                                 RTE_FLOW_ERROR_TYPE_ITEM,
830                                 item, "Not supported by syn filter");
831                         return -rte_errno;
832                 }
833         }
834
835         /* Get the TCP info. Only support SYN. */
836         if (!item->spec || !item->mask) {
837                 rte_flow_error_set(error, EINVAL,
838                                 RTE_FLOW_ERROR_TYPE_ITEM,
839                                 item, "Invalid SYN mask");
840                 return -rte_errno;
841         }
842         /*Not supported last point for range*/
843         if (item->last) {
844                 rte_flow_error_set(error, EINVAL,
845                         RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
846                         item, "Not supported last point for range");
847                 return -rte_errno;
848         }
849
850         tcp_spec = item->spec;
851         tcp_mask = item->mask;
852         if (!(tcp_spec->hdr.tcp_flags & TCP_SYN_FLAG) ||
853             tcp_mask->hdr.src_port ||
854             tcp_mask->hdr.dst_port ||
855             tcp_mask->hdr.sent_seq ||
856             tcp_mask->hdr.recv_ack ||
857             tcp_mask->hdr.data_off ||
858             tcp_mask->hdr.tcp_flags != TCP_SYN_FLAG ||
859             tcp_mask->hdr.rx_win ||
860             tcp_mask->hdr.cksum ||
861             tcp_mask->hdr.tcp_urp) {
862                 memset(filter, 0, sizeof(struct rte_eth_syn_filter));
863                 rte_flow_error_set(error, EINVAL,
864                                 RTE_FLOW_ERROR_TYPE_ITEM,
865                                 item, "Not supported by syn filter");
866                 return -rte_errno;
867         }
868
869         /* check if the next not void item is END */
870         index++;
871         NEXT_ITEM_OF_PATTERN(item, pattern, index);
872         if (item->type != RTE_FLOW_ITEM_TYPE_END) {
873                 memset(filter, 0, sizeof(struct rte_eth_syn_filter));
874                 rte_flow_error_set(error, EINVAL,
875                                 RTE_FLOW_ERROR_TYPE_ITEM,
876                                 item, "Not supported by syn filter");
877                 return -rte_errno;
878         }
879
880         /* parse action */
881         index = 0;
882
883         /* check if the first not void action is QUEUE. */
884         NEXT_ITEM_OF_ACTION(act, actions, index);
885         if (act->type != RTE_FLOW_ACTION_TYPE_QUEUE) {
886                 memset(filter, 0, sizeof(struct rte_eth_syn_filter));
887                 rte_flow_error_set(error, EINVAL,
888                                 RTE_FLOW_ERROR_TYPE_ACTION,
889                                 act, "Not supported action.");
890                 return -rte_errno;
891         }
892
893         act_q = (const struct rte_flow_action_queue *)act->conf;
894         filter->queue = act_q->index;
895
896         /* check if the next not void item is END */
897         index++;
898         NEXT_ITEM_OF_ACTION(act, actions, index);
899         if (act->type != RTE_FLOW_ACTION_TYPE_END) {
900                 memset(filter, 0, sizeof(struct rte_eth_syn_filter));
901                 rte_flow_error_set(error, EINVAL,
902                                 RTE_FLOW_ERROR_TYPE_ACTION,
903                                 act, "Not supported action.");
904                 return -rte_errno;
905         }
906
907         /* parse attr */
908         /* must be input direction */
909         if (!attr->ingress) {
910                 memset(filter, 0, sizeof(struct rte_eth_syn_filter));
911                 rte_flow_error_set(error, EINVAL,
912                         RTE_FLOW_ERROR_TYPE_ATTR_INGRESS,
913                         attr, "Only support ingress.");
914                 return -rte_errno;
915         }
916
917         /* not supported */
918         if (attr->egress) {
919                 memset(filter, 0, sizeof(struct rte_eth_syn_filter));
920                 rte_flow_error_set(error, EINVAL,
921                         RTE_FLOW_ERROR_TYPE_ATTR_EGRESS,
922                         attr, "Not support egress.");
923                 return -rte_errno;
924         }
925
926         /* Support 2 priorities, the lowest or highest. */
927         if (!attr->priority) {
928                 filter->hig_pri = 0;
929         } else if (attr->priority == (uint32_t)~0U) {
930                 filter->hig_pri = 1;
931         } else {
932                 memset(filter, 0, sizeof(struct rte_eth_syn_filter));
933                 rte_flow_error_set(error, EINVAL,
934                         RTE_FLOW_ERROR_TYPE_ATTR_PRIORITY,
935                         attr, "Not support priority.");
936                 return -rte_errno;
937         }
938
939         return 0;
940 }
941
942 static int
943 igb_parse_syn_filter(struct rte_eth_dev *dev,
944                                  const struct rte_flow_attr *attr,
945                              const struct rte_flow_item pattern[],
946                              const struct rte_flow_action actions[],
947                              struct rte_eth_syn_filter *filter,
948                              struct rte_flow_error *error)
949 {
950         struct e1000_hw *hw = E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);
951         int ret;
952
953         MAC_TYPE_FILTER_SUP(hw->mac.type);
954
955         ret = cons_parse_syn_filter(attr, pattern,
956                                         actions, filter, error);
957
958         if (hw->mac.type == e1000_82576) {
959                 if (filter->queue >= IGB_MAX_RX_QUEUE_NUM_82576) {
960                         memset(filter, 0, sizeof(struct rte_eth_syn_filter));
961                         rte_flow_error_set(error, EINVAL,
962                                 RTE_FLOW_ERROR_TYPE_ITEM,
963                                 NULL, "queue number not "
964                                         "supported by syn filter");
965                         return -rte_errno;
966                 }
967         } else {
968                 if (filter->queue >= IGB_MAX_RX_QUEUE_NUM) {
969                         memset(filter, 0, sizeof(struct rte_eth_syn_filter));
970                         rte_flow_error_set(error, EINVAL,
971                                 RTE_FLOW_ERROR_TYPE_ITEM,
972                                 NULL, "queue number not "
973                                         "supported by syn filter");
974                         return -rte_errno;
975                 }
976         }
977
978         if (ret)
979                 return ret;
980
981         return 0;
982 }
983
984 /**
985  * Parse the rule to see if it is a flex byte rule.
986  * And get the flex byte filter info BTW.
987  * pattern:
988  * The first not void item must be RAW.
989  * The second not void item can be RAW or END.
990  * The third not void item can be RAW or END.
991  * The last not void item must be END.
992  * action:
993  * The first not void action should be QUEUE.
994  * The next not void action should be END.
995  * pattern example:
996  * ITEM         Spec                    Mask
997  * RAW          relative        0               0x1
998  *                      offset  0               0xFFFFFFFF
999  *                      pattern {0x08, 0x06}            {0xFF, 0xFF}
1000  * RAW          relative        1               0x1
1001  *                      offset  100             0xFFFFFFFF
1002  *                      pattern {0x11, 0x22, 0x33}      {0xFF, 0xFF, 0xFF}
1003  * END
1004  * other members in mask and spec should set to 0x00.
1005  * item->last should be NULL.
1006  */
1007 static int
1008 cons_parse_flex_filter(const struct rte_flow_attr *attr,
1009                                 const struct rte_flow_item pattern[],
1010                                 const struct rte_flow_action actions[],
1011                                 struct rte_eth_flex_filter *filter,
1012                                 struct rte_flow_error *error)
1013 {
1014         const struct rte_flow_item *item;
1015         const struct rte_flow_action *act;
1016         const struct rte_flow_item_raw *raw_spec;
1017         const struct rte_flow_item_raw *raw_mask;
1018         const struct rte_flow_action_queue *act_q;
1019         uint32_t index, i, offset, total_offset;
1020         uint32_t max_offset = 0;
1021         int32_t shift, j, raw_index = 0;
1022         int32_t relative[IGB_FLEX_RAW_NUM] = {0};
1023         int32_t raw_offset[IGB_FLEX_RAW_NUM] = {0};
1024
1025         if (!pattern) {
1026                 rte_flow_error_set(error, EINVAL,
1027                                 RTE_FLOW_ERROR_TYPE_ITEM_NUM,
1028                                 NULL, "NULL pattern.");
1029                 return -rte_errno;
1030         }
1031
1032         if (!actions) {
1033                 rte_flow_error_set(error, EINVAL,
1034                                 RTE_FLOW_ERROR_TYPE_ACTION_NUM,
1035                                 NULL, "NULL action.");
1036                 return -rte_errno;
1037         }
1038
1039         if (!attr) {
1040                 rte_flow_error_set(error, EINVAL,
1041                                    RTE_FLOW_ERROR_TYPE_ATTR,
1042                                    NULL, "NULL attribute.");
1043                 return -rte_errno;
1044         }
1045
1046         /* parse pattern */
1047         index = 0;
1048
1049 item_loop:
1050
1051         /* the first not void item should be RAW */
1052         NEXT_ITEM_OF_PATTERN(item, pattern, index);
1053         if (item->type != RTE_FLOW_ITEM_TYPE_RAW) {
1054                 rte_flow_error_set(error, EINVAL,
1055                                 RTE_FLOW_ERROR_TYPE_ITEM,
1056                                 item, "Not supported by flex filter");
1057                 return -rte_errno;
1058         }
1059                 /*Not supported last point for range*/
1060         if (item->last) {
1061                 rte_flow_error_set(error, EINVAL,
1062                         RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
1063                         item, "Not supported last point for range");
1064                 return -rte_errno;
1065         }
1066
1067         raw_spec = item->spec;
1068         raw_mask = item->mask;
1069
1070         if (!raw_mask->length ||
1071             !raw_mask->relative) {
1072                 memset(filter, 0, sizeof(struct rte_eth_flex_filter));
1073                 rte_flow_error_set(error, EINVAL,
1074                                 RTE_FLOW_ERROR_TYPE_ITEM,
1075                                 item, "Not supported by flex filter");
1076                 return -rte_errno;
1077         }
1078
1079         if (raw_mask->offset)
1080                 offset = raw_spec->offset;
1081         else
1082                 offset = 0;
1083
1084         for (j = 0; j < raw_spec->length; j++) {
1085                 if (raw_mask->pattern[j] != 0xFF) {
1086                         memset(filter, 0, sizeof(struct rte_eth_flex_filter));
1087                         rte_flow_error_set(error, EINVAL,
1088                                         RTE_FLOW_ERROR_TYPE_ITEM,
1089                                         item, "Not supported by flex filter");
1090                         return -rte_errno;
1091                 }
1092         }
1093
1094         total_offset = 0;
1095
1096         if (raw_spec->relative) {
1097                 for (j = raw_index; j > 0; j--) {
1098                         total_offset += raw_offset[j - 1];
1099                         if (!relative[j - 1])
1100                                 break;
1101                 }
1102                 if (total_offset + raw_spec->length + offset > max_offset)
1103                         max_offset = total_offset + raw_spec->length + offset;
1104         } else {
1105                 if (raw_spec->length + offset > max_offset)
1106                         max_offset = raw_spec->length + offset;
1107         }
1108
1109         if ((raw_spec->length + offset + total_offset) >
1110                         RTE_FLEX_FILTER_MAXLEN) {
1111                 memset(filter, 0, sizeof(struct rte_eth_flex_filter));
1112                 rte_flow_error_set(error, EINVAL,
1113                                 RTE_FLOW_ERROR_TYPE_ITEM,
1114                                 item, "Not supported by flex filter");
1115                 return -rte_errno;
1116         }
1117
1118         if (raw_spec->relative == 0) {
1119                 for (j = 0; j < raw_spec->length; j++)
1120                         filter->bytes[offset + j] =
1121                         raw_spec->pattern[j];
1122                 j = offset / CHAR_BIT;
1123                 shift = offset % CHAR_BIT;
1124         } else {
1125                 for (j = 0; j < raw_spec->length; j++)
1126                         filter->bytes[total_offset + offset + j] =
1127                                 raw_spec->pattern[j];
1128                 j = (total_offset + offset) / CHAR_BIT;
1129                 shift = (total_offset + offset) % CHAR_BIT;
1130         }
1131
1132         i = 0;
1133
1134         for ( ; shift < CHAR_BIT; shift++) {
1135                 filter->mask[j] |= (0x80 >> shift);
1136                 i++;
1137                 if (i == raw_spec->length)
1138                         break;
1139                 if (shift == (CHAR_BIT - 1)) {
1140                         j++;
1141                         shift = -1;
1142                 }
1143         }
1144
1145         relative[raw_index] = raw_spec->relative;
1146         raw_offset[raw_index] = offset + raw_spec->length;
1147         raw_index++;
1148
1149         /* check if the next not void item is RAW */
1150         index++;
1151         NEXT_ITEM_OF_PATTERN(item, pattern, index);
1152         if (item->type != RTE_FLOW_ITEM_TYPE_RAW &&
1153                 item->type != RTE_FLOW_ITEM_TYPE_END) {
1154                 rte_flow_error_set(error, EINVAL,
1155                                 RTE_FLOW_ERROR_TYPE_ITEM,
1156                                 item, "Not supported by flex filter");
1157                 return -rte_errno;
1158         }
1159
1160         /* go back to parser */
1161         if (item->type == RTE_FLOW_ITEM_TYPE_RAW) {
1162                 /* if the item is RAW, the content should be parse */
1163                 goto item_loop;
1164         }
1165
1166         filter->len = RTE_ALIGN(max_offset, 8);
1167
1168         /* parse action */
1169         index = 0;
1170
1171         /* check if the first not void action is QUEUE. */
1172         NEXT_ITEM_OF_ACTION(act, actions, index);
1173         if (act->type != RTE_FLOW_ACTION_TYPE_QUEUE) {
1174                 memset(filter, 0, sizeof(struct rte_eth_flex_filter));
1175                 rte_flow_error_set(error, EINVAL,
1176                                 RTE_FLOW_ERROR_TYPE_ACTION,
1177                                 act, "Not supported action.");
1178                 return -rte_errno;
1179         }
1180
1181         act_q = (const struct rte_flow_action_queue *)act->conf;
1182         filter->queue = act_q->index;
1183
1184         /* check if the next not void item is END */
1185         index++;
1186         NEXT_ITEM_OF_ACTION(act, actions, index);
1187         if (act->type != RTE_FLOW_ACTION_TYPE_END) {
1188                 memset(filter, 0, sizeof(struct rte_eth_flex_filter));
1189                 rte_flow_error_set(error, EINVAL,
1190                                 RTE_FLOW_ERROR_TYPE_ACTION,
1191                                 act, "Not supported action.");
1192                 return -rte_errno;
1193         }
1194
1195         /* parse attr */
1196         /* must be input direction */
1197         if (!attr->ingress) {
1198                 memset(filter, 0, sizeof(struct rte_eth_flex_filter));
1199                 rte_flow_error_set(error, EINVAL,
1200                         RTE_FLOW_ERROR_TYPE_ATTR_INGRESS,
1201                         attr, "Only support ingress.");
1202                 return -rte_errno;
1203         }
1204
1205         /* not supported */
1206         if (attr->egress) {
1207                 memset(filter, 0, sizeof(struct rte_eth_flex_filter));
1208                 rte_flow_error_set(error, EINVAL,
1209                         RTE_FLOW_ERROR_TYPE_ATTR_EGRESS,
1210                         attr, "Not support egress.");
1211                 return -rte_errno;
1212         }
1213
1214         if (attr->priority > 0xFFFF) {
1215                 memset(filter, 0, sizeof(struct rte_eth_flex_filter));
1216                 rte_flow_error_set(error, EINVAL,
1217                                    RTE_FLOW_ERROR_TYPE_ATTR_PRIORITY,
1218                                    attr, "Error priority.");
1219                 return -rte_errno;
1220         }
1221
1222         filter->priority = (uint16_t)attr->priority;
1223
1224         return 0;
1225 }
1226
1227 static int
1228 igb_parse_flex_filter(struct rte_eth_dev *dev,
1229                                  const struct rte_flow_attr *attr,
1230                              const struct rte_flow_item pattern[],
1231                              const struct rte_flow_action actions[],
1232                              struct rte_eth_flex_filter *filter,
1233                              struct rte_flow_error *error)
1234 {
1235         struct e1000_hw *hw = E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);
1236         int ret;
1237
1238         MAC_TYPE_FILTER_SUP_EXT(hw->mac.type);
1239
1240         ret = cons_parse_flex_filter(attr, pattern,
1241                                         actions, filter, error);
1242
1243         if (filter->queue >= IGB_MAX_RX_QUEUE_NUM) {
1244                 memset(filter, 0, sizeof(struct rte_eth_flex_filter));
1245                 rte_flow_error_set(error, EINVAL,
1246                         RTE_FLOW_ERROR_TYPE_ITEM,
1247                         NULL, "queue number not supported by flex filter");
1248                 return -rte_errno;
1249         }
1250
1251         if (filter->len == 0 || filter->len > E1000_MAX_FLEX_FILTER_LEN ||
1252                 filter->len % sizeof(uint64_t) != 0) {
1253                 PMD_DRV_LOG(ERR, "filter's length is out of range");
1254                 return -EINVAL;
1255         }
1256
1257         if (filter->priority > E1000_MAX_FLEX_FILTER_PRI) {
1258                 PMD_DRV_LOG(ERR, "filter's priority is out of range");
1259                 return -EINVAL;
1260         }
1261
1262         if (ret)
1263                 return ret;
1264
1265         return 0;
1266 }
1267
1268 static int
1269 igb_parse_rss_filter(struct rte_eth_dev *dev,
1270                         const struct rte_flow_attr *attr,
1271                         const struct rte_flow_action actions[],
1272                         struct igb_rte_flow_rss_conf *rss_conf,
1273                         struct rte_flow_error *error)
1274 {
1275         const struct rte_flow_action *act;
1276         const struct rte_flow_action_rss *rss;
1277         uint16_t n, index;
1278
1279         /**
1280          * rss only supports forwarding,
1281          * check if the first not void action is RSS.
1282          */
1283         index = 0;
1284         NEXT_ITEM_OF_ACTION(act, actions, index);
1285         if (act->type != RTE_FLOW_ACTION_TYPE_RSS) {
1286                 memset(rss_conf, 0, sizeof(struct igb_rte_flow_rss_conf));
1287                 rte_flow_error_set(error, EINVAL,
1288                         RTE_FLOW_ERROR_TYPE_ACTION,
1289                         act, "Not supported action.");
1290                 return -rte_errno;
1291         }
1292
1293         rss = (const struct rte_flow_action_rss *)act->conf;
1294
1295         if (!rss || !rss->num) {
1296                 rte_flow_error_set(error, EINVAL,
1297                                 RTE_FLOW_ERROR_TYPE_ACTION,
1298                                 act,
1299                            "no valid queues");
1300                 return -rte_errno;
1301         }
1302
1303         for (n = 0; n < rss->num; n++) {
1304                 if (rss->queue[n] >= dev->data->nb_rx_queues) {
1305                         rte_flow_error_set(error, EINVAL,
1306                                    RTE_FLOW_ERROR_TYPE_ACTION,
1307                                    act,
1308                                    "queue id > max number of queues");
1309                         return -rte_errno;
1310                 }
1311         }
1312
1313         if (rss->rss_conf)
1314                 rss_conf->rss_conf = *rss->rss_conf;
1315         else
1316                 rss_conf->rss_conf.rss_hf = IGB_RSS_OFFLOAD_ALL;
1317
1318         for (n = 0; n < rss->num; ++n)
1319                 rss_conf->queue[n] = rss->queue[n];
1320         rss_conf->num = rss->num;
1321
1322         /* check if the next not void item is END */
1323         index++;
1324         NEXT_ITEM_OF_ACTION(act, actions, index);
1325         if (act->type != RTE_FLOW_ACTION_TYPE_END) {
1326                 memset(rss_conf, 0, sizeof(struct rte_eth_rss_conf));
1327                 rte_flow_error_set(error, EINVAL,
1328                         RTE_FLOW_ERROR_TYPE_ACTION,
1329                         act, "Not supported action.");
1330                 return -rte_errno;
1331         }
1332
1333         /* parse attr */
1334         /* must be input direction */
1335         if (!attr->ingress) {
1336                 memset(rss_conf, 0, sizeof(struct igb_rte_flow_rss_conf));
1337                 rte_flow_error_set(error, EINVAL,
1338                                    RTE_FLOW_ERROR_TYPE_ATTR_INGRESS,
1339                                    attr, "Only support ingress.");
1340                 return -rte_errno;
1341         }
1342
1343         /* not supported */
1344         if (attr->egress) {
1345                 memset(rss_conf, 0, sizeof(struct igb_rte_flow_rss_conf));
1346                 rte_flow_error_set(error, EINVAL,
1347                                    RTE_FLOW_ERROR_TYPE_ATTR_EGRESS,
1348                                    attr, "Not support egress.");
1349                 return -rte_errno;
1350         }
1351
1352         if (attr->priority > 0xFFFF) {
1353                 memset(rss_conf, 0, sizeof(struct igb_rte_flow_rss_conf));
1354                 rte_flow_error_set(error, EINVAL,
1355                                    RTE_FLOW_ERROR_TYPE_ATTR_PRIORITY,
1356                                    attr, "Error priority.");
1357                 return -rte_errno;
1358         }
1359
1360         return 0;
1361 }
1362
1363 /**
1364  * Create a flow rule.
1365  * Theorically one rule can match more than one filters.
1366  * We will let it use the filter which it hitt first.
1367  * So, the sequence matters.
1368  */
1369 static struct rte_flow *
1370 igb_flow_create(struct rte_eth_dev *dev,
1371                   const struct rte_flow_attr *attr,
1372                   const struct rte_flow_item pattern[],
1373                   const struct rte_flow_action actions[],
1374                   struct rte_flow_error *error)
1375 {
1376         int ret;
1377         struct rte_eth_ntuple_filter ntuple_filter;
1378         struct rte_eth_ethertype_filter ethertype_filter;
1379         struct rte_eth_syn_filter syn_filter;
1380         struct rte_eth_flex_filter flex_filter;
1381         struct igb_rte_flow_rss_conf rss_conf;
1382         struct rte_flow *flow = NULL;
1383         struct igb_ntuple_filter_ele *ntuple_filter_ptr;
1384         struct igb_ethertype_filter_ele *ethertype_filter_ptr;
1385         struct igb_eth_syn_filter_ele *syn_filter_ptr;
1386         struct igb_flex_filter_ele *flex_filter_ptr;
1387         struct igb_rss_conf_ele *rss_filter_ptr;
1388         struct igb_flow_mem *igb_flow_mem_ptr;
1389
1390         flow = rte_zmalloc("igb_rte_flow", sizeof(struct rte_flow), 0);
1391         if (!flow) {
1392                 PMD_DRV_LOG(ERR, "failed to allocate memory");
1393                 return (struct rte_flow *)flow;
1394         }
1395         igb_flow_mem_ptr = rte_zmalloc("igb_flow_mem",
1396                         sizeof(struct igb_flow_mem), 0);
1397         if (!igb_flow_mem_ptr) {
1398                 PMD_DRV_LOG(ERR, "failed to allocate memory");
1399                 rte_free(flow);
1400                 return NULL;
1401         }
1402         igb_flow_mem_ptr->flow = flow;
1403         igb_flow_mem_ptr->dev = dev;
1404         TAILQ_INSERT_TAIL(&igb_flow_list,
1405                                 igb_flow_mem_ptr, entries);
1406
1407         memset(&ntuple_filter, 0, sizeof(struct rte_eth_ntuple_filter));
1408         ret = igb_parse_ntuple_filter(dev, attr, pattern,
1409                         actions, &ntuple_filter, error);
1410         if (!ret) {
1411                 ret = igb_add_del_ntuple_filter(dev, &ntuple_filter, TRUE);
1412                 if (!ret) {
1413                         ntuple_filter_ptr = rte_zmalloc("igb_ntuple_filter",
1414                                 sizeof(struct igb_ntuple_filter_ele), 0);
1415                         if (!ntuple_filter_ptr) {
1416                                 PMD_DRV_LOG(ERR, "failed to allocate memory");
1417                                 goto out;
1418                         }
1419
1420                         rte_memcpy(&ntuple_filter_ptr->filter_info,
1421                                 &ntuple_filter,
1422                                 sizeof(struct rte_eth_ntuple_filter));
1423                         TAILQ_INSERT_TAIL(&igb_filter_ntuple_list,
1424                                 ntuple_filter_ptr, entries);
1425                         flow->rule = ntuple_filter_ptr;
1426                         flow->filter_type = RTE_ETH_FILTER_NTUPLE;
1427                         return flow;
1428                 }
1429                 goto out;
1430         }
1431
1432         memset(&ethertype_filter, 0, sizeof(struct rte_eth_ethertype_filter));
1433         ret = igb_parse_ethertype_filter(dev, attr, pattern,
1434                                 actions, &ethertype_filter, error);
1435         if (!ret) {
1436                 ret = igb_add_del_ethertype_filter(dev,
1437                                 &ethertype_filter, TRUE);
1438                 if (!ret) {
1439                         ethertype_filter_ptr = rte_zmalloc(
1440                                 "igb_ethertype_filter",
1441                                 sizeof(struct igb_ethertype_filter_ele), 0);
1442                         if (!ethertype_filter_ptr) {
1443                                 PMD_DRV_LOG(ERR, "failed to allocate memory");
1444                                 goto out;
1445                         }
1446
1447                         rte_memcpy(&ethertype_filter_ptr->filter_info,
1448                                 &ethertype_filter,
1449                                 sizeof(struct rte_eth_ethertype_filter));
1450                         TAILQ_INSERT_TAIL(&igb_filter_ethertype_list,
1451                                 ethertype_filter_ptr, entries);
1452                         flow->rule = ethertype_filter_ptr;
1453                         flow->filter_type = RTE_ETH_FILTER_ETHERTYPE;
1454                         return flow;
1455                 }
1456                 goto out;
1457         }
1458
1459         memset(&syn_filter, 0, sizeof(struct rte_eth_syn_filter));
1460         ret = igb_parse_syn_filter(dev, attr, pattern,
1461                                 actions, &syn_filter, error);
1462         if (!ret) {
1463                 ret = eth_igb_syn_filter_set(dev, &syn_filter, TRUE);
1464                 if (!ret) {
1465                         syn_filter_ptr = rte_zmalloc("igb_syn_filter",
1466                                 sizeof(struct igb_eth_syn_filter_ele), 0);
1467                         if (!syn_filter_ptr) {
1468                                 PMD_DRV_LOG(ERR, "failed to allocate memory");
1469                                 goto out;
1470                         }
1471
1472                         rte_memcpy(&syn_filter_ptr->filter_info,
1473                                 &syn_filter,
1474                                 sizeof(struct rte_eth_syn_filter));
1475                         TAILQ_INSERT_TAIL(&igb_filter_syn_list,
1476                                 syn_filter_ptr,
1477                                 entries);
1478                         flow->rule = syn_filter_ptr;
1479                         flow->filter_type = RTE_ETH_FILTER_SYN;
1480                         return flow;
1481                 }
1482                 goto out;
1483         }
1484
1485         memset(&flex_filter, 0, sizeof(struct rte_eth_flex_filter));
1486         ret = igb_parse_flex_filter(dev, attr, pattern,
1487                                         actions, &flex_filter, error);
1488         if (!ret) {
1489                 ret = eth_igb_add_del_flex_filter(dev, &flex_filter, TRUE);
1490                 if (!ret) {
1491                         flex_filter_ptr = rte_zmalloc("igb_flex_filter",
1492                                 sizeof(struct igb_flex_filter_ele), 0);
1493                         if (!flex_filter_ptr) {
1494                                 PMD_DRV_LOG(ERR, "failed to allocate memory");
1495                                 goto out;
1496                         }
1497
1498                         rte_memcpy(&flex_filter_ptr->filter_info,
1499                                 &flex_filter,
1500                                 sizeof(struct rte_eth_flex_filter));
1501                         TAILQ_INSERT_TAIL(&igb_filter_flex_list,
1502                                 flex_filter_ptr, entries);
1503                         flow->rule = flex_filter_ptr;
1504                         flow->filter_type = RTE_ETH_FILTER_FLEXIBLE;
1505                         return flow;
1506                 }
1507         }
1508
1509         memset(&rss_conf, 0, sizeof(struct igb_rte_flow_rss_conf));
1510         ret = igb_parse_rss_filter(dev, attr,
1511                                         actions, &rss_conf, error);
1512         if (!ret) {
1513                 ret = igb_config_rss_filter(dev, &rss_conf, TRUE);
1514                 if (!ret) {
1515                         rss_filter_ptr = rte_zmalloc("igb_rss_filter",
1516                                 sizeof(struct igb_rss_conf_ele), 0);
1517                         if (!rss_filter_ptr) {
1518                                 PMD_DRV_LOG(ERR, "failed to allocate memory");
1519                                 goto out;
1520                         }
1521                         rte_memcpy(&rss_filter_ptr->filter_info,
1522                                 &rss_conf,
1523                                 sizeof(struct igb_rte_flow_rss_conf));
1524                         TAILQ_INSERT_TAIL(&igb_filter_rss_list,
1525                                 rss_filter_ptr, entries);
1526                         flow->rule = rss_filter_ptr;
1527                         flow->filter_type = RTE_ETH_FILTER_HASH;
1528                         return flow;
1529                 }
1530         }
1531
1532 out:
1533         TAILQ_REMOVE(&igb_flow_list,
1534                 igb_flow_mem_ptr, entries);
1535         rte_flow_error_set(error, -ret,
1536                            RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
1537                            "Failed to create flow.");
1538         rte_free(igb_flow_mem_ptr);
1539         rte_free(flow);
1540         return NULL;
1541 }
1542
1543 /**
1544  * Check if the flow rule is supported by igb.
1545  * It only checkes the format. Don't guarantee the rule can be programmed into
1546  * the HW. Because there can be no enough room for the rule.
1547  */
1548 static int
1549 igb_flow_validate(__rte_unused struct rte_eth_dev *dev,
1550                 const struct rte_flow_attr *attr,
1551                 const struct rte_flow_item pattern[],
1552                 const struct rte_flow_action actions[],
1553                 struct rte_flow_error *error)
1554 {
1555         struct rte_eth_ntuple_filter ntuple_filter;
1556         struct rte_eth_ethertype_filter ethertype_filter;
1557         struct rte_eth_syn_filter syn_filter;
1558         struct rte_eth_flex_filter flex_filter;
1559         struct igb_rte_flow_rss_conf rss_conf;
1560         int ret;
1561
1562         memset(&ntuple_filter, 0, sizeof(struct rte_eth_ntuple_filter));
1563         ret = igb_parse_ntuple_filter(dev, attr, pattern,
1564                                 actions, &ntuple_filter, error);
1565         if (!ret)
1566                 return 0;
1567
1568         memset(&ethertype_filter, 0, sizeof(struct rte_eth_ethertype_filter));
1569         ret = igb_parse_ethertype_filter(dev, attr, pattern,
1570                                 actions, &ethertype_filter, error);
1571         if (!ret)
1572                 return 0;
1573
1574         memset(&syn_filter, 0, sizeof(struct rte_eth_syn_filter));
1575         ret = igb_parse_syn_filter(dev, attr, pattern,
1576                                 actions, &syn_filter, error);
1577         if (!ret)
1578                 return 0;
1579
1580         memset(&flex_filter, 0, sizeof(struct rte_eth_flex_filter));
1581         ret = igb_parse_flex_filter(dev, attr, pattern,
1582                                 actions, &flex_filter, error);
1583         if (!ret)
1584                 return 0;
1585
1586         memset(&rss_conf, 0, sizeof(struct igb_rte_flow_rss_conf));
1587         ret = igb_parse_rss_filter(dev, attr,
1588                                         actions, &rss_conf, error);
1589
1590         return ret;
1591 }
1592
1593 /* Destroy a flow rule on igb. */
1594 static int
1595 igb_flow_destroy(struct rte_eth_dev *dev,
1596                 struct rte_flow *flow,
1597                 struct rte_flow_error *error)
1598 {
1599         int ret;
1600         struct rte_flow *pmd_flow = flow;
1601         enum rte_filter_type filter_type = pmd_flow->filter_type;
1602         struct igb_ntuple_filter_ele *ntuple_filter_ptr;
1603         struct igb_ethertype_filter_ele *ethertype_filter_ptr;
1604         struct igb_eth_syn_filter_ele *syn_filter_ptr;
1605         struct igb_flex_filter_ele *flex_filter_ptr;
1606         struct igb_flow_mem *igb_flow_mem_ptr;
1607         struct igb_rss_conf_ele *rss_filter_ptr;
1608
1609         switch (filter_type) {
1610         case RTE_ETH_FILTER_NTUPLE:
1611                 ntuple_filter_ptr = (struct igb_ntuple_filter_ele *)
1612                                         pmd_flow->rule;
1613                 ret = igb_add_del_ntuple_filter(dev,
1614                                 &ntuple_filter_ptr->filter_info, FALSE);
1615                 if (!ret) {
1616                         TAILQ_REMOVE(&igb_filter_ntuple_list,
1617                         ntuple_filter_ptr, entries);
1618                         rte_free(ntuple_filter_ptr);
1619                 }
1620                 break;
1621         case RTE_ETH_FILTER_ETHERTYPE:
1622                 ethertype_filter_ptr = (struct igb_ethertype_filter_ele *)
1623                                         pmd_flow->rule;
1624                 ret = igb_add_del_ethertype_filter(dev,
1625                                 &ethertype_filter_ptr->filter_info, FALSE);
1626                 if (!ret) {
1627                         TAILQ_REMOVE(&igb_filter_ethertype_list,
1628                                 ethertype_filter_ptr, entries);
1629                         rte_free(ethertype_filter_ptr);
1630                 }
1631                 break;
1632         case RTE_ETH_FILTER_SYN:
1633                 syn_filter_ptr = (struct igb_eth_syn_filter_ele *)
1634                                 pmd_flow->rule;
1635                 ret = eth_igb_syn_filter_set(dev,
1636                                 &syn_filter_ptr->filter_info, FALSE);
1637                 if (!ret) {
1638                         TAILQ_REMOVE(&igb_filter_syn_list,
1639                                 syn_filter_ptr, entries);
1640                         rte_free(syn_filter_ptr);
1641                 }
1642                 break;
1643         case RTE_ETH_FILTER_FLEXIBLE:
1644                 flex_filter_ptr = (struct igb_flex_filter_ele *)
1645                                 pmd_flow->rule;
1646                 ret = eth_igb_add_del_flex_filter(dev,
1647                                 &flex_filter_ptr->filter_info, FALSE);
1648                 if (!ret) {
1649                         TAILQ_REMOVE(&igb_filter_flex_list,
1650                                 flex_filter_ptr, entries);
1651                         rte_free(flex_filter_ptr);
1652                 }
1653                 break;
1654         case RTE_ETH_FILTER_HASH:
1655                 rss_filter_ptr = (struct igb_rss_conf_ele *)
1656                                 pmd_flow->rule;
1657                 ret = igb_config_rss_filter(dev,
1658                                         &rss_filter_ptr->filter_info, FALSE);
1659                 if (!ret) {
1660                         TAILQ_REMOVE(&igb_filter_rss_list,
1661                                 rss_filter_ptr, entries);
1662                         rte_free(rss_filter_ptr);
1663                 }
1664                 break;
1665         default:
1666                 PMD_DRV_LOG(WARNING, "Filter type (%d) not supported",
1667                             filter_type);
1668                 ret = -EINVAL;
1669                 break;
1670         }
1671
1672         if (ret) {
1673                 rte_flow_error_set(error, EINVAL,
1674                                 RTE_FLOW_ERROR_TYPE_HANDLE,
1675                                 NULL, "Failed to destroy flow");
1676                 return ret;
1677         }
1678
1679         TAILQ_FOREACH(igb_flow_mem_ptr, &igb_flow_list, entries) {
1680                 if (igb_flow_mem_ptr->flow == pmd_flow) {
1681                         TAILQ_REMOVE(&igb_flow_list,
1682                                 igb_flow_mem_ptr, entries);
1683                         rte_free(igb_flow_mem_ptr);
1684                 }
1685         }
1686         rte_free(flow);
1687
1688         return ret;
1689 }
1690
1691 /* remove all the n-tuple filters */
1692 static void
1693 igb_clear_all_ntuple_filter(struct rte_eth_dev *dev)
1694 {
1695         struct e1000_filter_info *filter_info =
1696                 E1000_DEV_PRIVATE_TO_FILTER_INFO(dev->data->dev_private);
1697         struct e1000_5tuple_filter *p_5tuple;
1698         struct e1000_2tuple_filter *p_2tuple;
1699
1700         while ((p_5tuple = TAILQ_FIRST(&filter_info->fivetuple_list)))
1701                 igb_delete_5tuple_filter_82576(dev, p_5tuple);
1702
1703         while ((p_2tuple = TAILQ_FIRST(&filter_info->twotuple_list)))
1704                 igb_delete_2tuple_filter(dev, p_2tuple);
1705 }
1706
1707 /* remove all the ether type filters */
1708 static void
1709 igb_clear_all_ethertype_filter(struct rte_eth_dev *dev)
1710 {
1711         struct e1000_hw *hw = E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);
1712         struct e1000_filter_info *filter_info =
1713                 E1000_DEV_PRIVATE_TO_FILTER_INFO(dev->data->dev_private);
1714         int i;
1715
1716         for (i = 0; i < E1000_MAX_ETQF_FILTERS; i++) {
1717                 if (filter_info->ethertype_mask & (1 << i)) {
1718                         (void)igb_ethertype_filter_remove(filter_info,
1719                                                             (uint8_t)i);
1720                         E1000_WRITE_REG(hw, E1000_ETQF(i), 0);
1721                         E1000_WRITE_FLUSH(hw);
1722                 }
1723         }
1724 }
1725
1726 /* remove the SYN filter */
1727 static void
1728 igb_clear_syn_filter(struct rte_eth_dev *dev)
1729 {
1730         struct e1000_hw *hw = E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);
1731         struct e1000_filter_info *filter_info =
1732                 E1000_DEV_PRIVATE_TO_FILTER_INFO(dev->data->dev_private);
1733
1734         if (filter_info->syn_info & E1000_SYN_FILTER_ENABLE) {
1735                 filter_info->syn_info = 0;
1736                 E1000_WRITE_REG(hw, E1000_SYNQF(0), 0);
1737                 E1000_WRITE_FLUSH(hw);
1738         }
1739 }
1740
1741 /* remove all the flex filters */
1742 static void
1743 igb_clear_all_flex_filter(struct rte_eth_dev *dev)
1744 {
1745         struct e1000_filter_info *filter_info =
1746                 E1000_DEV_PRIVATE_TO_FILTER_INFO(dev->data->dev_private);
1747         struct e1000_flex_filter *flex_filter;
1748
1749         while ((flex_filter = TAILQ_FIRST(&filter_info->flex_list)))
1750                 igb_remove_flex_filter(dev, flex_filter);
1751 }
1752
1753 /* remove the rss filter */
1754 static void
1755 igb_clear_rss_filter(struct rte_eth_dev *dev)
1756 {
1757         struct e1000_filter_info *filter =
1758                 E1000_DEV_PRIVATE_TO_FILTER_INFO(dev->data->dev_private);
1759
1760         if (filter->rss_info.num)
1761                 igb_config_rss_filter(dev, &filter->rss_info, FALSE);
1762 }
1763
1764 void
1765 igb_filterlist_flush(struct rte_eth_dev *dev)
1766 {
1767         struct igb_ntuple_filter_ele *ntuple_filter_ptr;
1768         struct igb_ethertype_filter_ele *ethertype_filter_ptr;
1769         struct igb_eth_syn_filter_ele *syn_filter_ptr;
1770         struct igb_flex_filter_ele *flex_filter_ptr;
1771         struct igb_rss_conf_ele  *rss_filter_ptr;
1772         struct igb_flow_mem *igb_flow_mem_ptr;
1773         enum rte_filter_type filter_type;
1774         struct rte_flow *pmd_flow;
1775
1776         TAILQ_FOREACH(igb_flow_mem_ptr, &igb_flow_list, entries) {
1777                 if (igb_flow_mem_ptr->dev == dev) {
1778                         pmd_flow = igb_flow_mem_ptr->flow;
1779                         filter_type = pmd_flow->filter_type;
1780
1781                         switch (filter_type) {
1782                         case RTE_ETH_FILTER_NTUPLE:
1783                                 ntuple_filter_ptr =
1784                                 (struct igb_ntuple_filter_ele *)
1785                                         pmd_flow->rule;
1786                                 TAILQ_REMOVE(&igb_filter_ntuple_list,
1787                                                 ntuple_filter_ptr, entries);
1788                                 rte_free(ntuple_filter_ptr);
1789                                 break;
1790                         case RTE_ETH_FILTER_ETHERTYPE:
1791                                 ethertype_filter_ptr =
1792                                 (struct igb_ethertype_filter_ele *)
1793                                         pmd_flow->rule;
1794                                 TAILQ_REMOVE(&igb_filter_ethertype_list,
1795                                                 ethertype_filter_ptr, entries);
1796                                 rte_free(ethertype_filter_ptr);
1797                                 break;
1798                         case RTE_ETH_FILTER_SYN:
1799                                 syn_filter_ptr =
1800                                         (struct igb_eth_syn_filter_ele *)
1801                                                 pmd_flow->rule;
1802                                 TAILQ_REMOVE(&igb_filter_syn_list,
1803                                                 syn_filter_ptr, entries);
1804                                 rte_free(syn_filter_ptr);
1805                                 break;
1806                         case RTE_ETH_FILTER_FLEXIBLE:
1807                                 flex_filter_ptr =
1808                                         (struct igb_flex_filter_ele *)
1809                                                 pmd_flow->rule;
1810                                 TAILQ_REMOVE(&igb_filter_flex_list,
1811                                                 flex_filter_ptr, entries);
1812                                 rte_free(flex_filter_ptr);
1813                                 break;
1814                         case RTE_ETH_FILTER_HASH:
1815                                 rss_filter_ptr =
1816                                         (struct igb_rss_conf_ele *)
1817                                                 pmd_flow->rule;
1818                                 TAILQ_REMOVE(&igb_filter_rss_list,
1819                                                 rss_filter_ptr, entries);
1820                                 rte_free(rss_filter_ptr);
1821                                 break;
1822                         default:
1823                                 PMD_DRV_LOG(WARNING, "Filter type"
1824                                         "(%d) not supported", filter_type);
1825                                 break;
1826                         }
1827                         TAILQ_REMOVE(&igb_flow_list,
1828                                  igb_flow_mem_ptr,
1829                                  entries);
1830                         rte_free(igb_flow_mem_ptr->flow);
1831                         rte_free(igb_flow_mem_ptr);
1832                 }
1833         }
1834 }
1835
1836 /*  Destroy all flow rules associated with a port on igb. */
1837 static int
1838 igb_flow_flush(struct rte_eth_dev *dev,
1839                 __rte_unused struct rte_flow_error *error)
1840 {
1841         igb_clear_all_ntuple_filter(dev);
1842         igb_clear_all_ethertype_filter(dev);
1843         igb_clear_syn_filter(dev);
1844         igb_clear_all_flex_filter(dev);
1845         igb_clear_rss_filter(dev);
1846         igb_filterlist_flush(dev);
1847
1848         return 0;
1849 }
1850
1851 const struct rte_flow_ops igb_flow_ops = {
1852         .validate = igb_flow_validate,
1853         .create = igb_flow_create,
1854         .destroy = igb_flow_destroy,
1855         .flush = igb_flow_flush,
1856 };