ethdev: flatten RSS configuration in flow API
[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->queue_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->queue_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->key_len && rss->key_len != RTE_DIM(rss_conf->key))
1314                 return rte_flow_error_set
1315                         (error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ACTION, act,
1316                          "RSS hash key must be exactly 40 bytes");
1317         if (rss->queue_num > RTE_DIM(rss_conf->queue))
1318                 return rte_flow_error_set
1319                         (error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ACTION, act,
1320                          "too many queues for RSS context");
1321         if (igb_rss_conf_init(rss_conf, rss))
1322                 return rte_flow_error_set
1323                         (error, EINVAL, RTE_FLOW_ERROR_TYPE_ACTION, act,
1324                          "RSS context initialization failure");
1325
1326         /* check if the next not void item is END */
1327         index++;
1328         NEXT_ITEM_OF_ACTION(act, actions, index);
1329         if (act->type != RTE_FLOW_ACTION_TYPE_END) {
1330                 memset(rss_conf, 0, sizeof(struct rte_eth_rss_conf));
1331                 rte_flow_error_set(error, EINVAL,
1332                         RTE_FLOW_ERROR_TYPE_ACTION,
1333                         act, "Not supported action.");
1334                 return -rte_errno;
1335         }
1336
1337         /* parse attr */
1338         /* must be input direction */
1339         if (!attr->ingress) {
1340                 memset(rss_conf, 0, sizeof(struct igb_rte_flow_rss_conf));
1341                 rte_flow_error_set(error, EINVAL,
1342                                    RTE_FLOW_ERROR_TYPE_ATTR_INGRESS,
1343                                    attr, "Only support ingress.");
1344                 return -rte_errno;
1345         }
1346
1347         /* not supported */
1348         if (attr->egress) {
1349                 memset(rss_conf, 0, sizeof(struct igb_rte_flow_rss_conf));
1350                 rte_flow_error_set(error, EINVAL,
1351                                    RTE_FLOW_ERROR_TYPE_ATTR_EGRESS,
1352                                    attr, "Not support egress.");
1353                 return -rte_errno;
1354         }
1355
1356         if (attr->priority > 0xFFFF) {
1357                 memset(rss_conf, 0, sizeof(struct igb_rte_flow_rss_conf));
1358                 rte_flow_error_set(error, EINVAL,
1359                                    RTE_FLOW_ERROR_TYPE_ATTR_PRIORITY,
1360                                    attr, "Error priority.");
1361                 return -rte_errno;
1362         }
1363
1364         return 0;
1365 }
1366
1367 /**
1368  * Create a flow rule.
1369  * Theorically one rule can match more than one filters.
1370  * We will let it use the filter which it hitt first.
1371  * So, the sequence matters.
1372  */
1373 static struct rte_flow *
1374 igb_flow_create(struct rte_eth_dev *dev,
1375                   const struct rte_flow_attr *attr,
1376                   const struct rte_flow_item pattern[],
1377                   const struct rte_flow_action actions[],
1378                   struct rte_flow_error *error)
1379 {
1380         int ret;
1381         struct rte_eth_ntuple_filter ntuple_filter;
1382         struct rte_eth_ethertype_filter ethertype_filter;
1383         struct rte_eth_syn_filter syn_filter;
1384         struct rte_eth_flex_filter flex_filter;
1385         struct igb_rte_flow_rss_conf rss_conf;
1386         struct rte_flow *flow = NULL;
1387         struct igb_ntuple_filter_ele *ntuple_filter_ptr;
1388         struct igb_ethertype_filter_ele *ethertype_filter_ptr;
1389         struct igb_eth_syn_filter_ele *syn_filter_ptr;
1390         struct igb_flex_filter_ele *flex_filter_ptr;
1391         struct igb_rss_conf_ele *rss_filter_ptr;
1392         struct igb_flow_mem *igb_flow_mem_ptr;
1393
1394         flow = rte_zmalloc("igb_rte_flow", sizeof(struct rte_flow), 0);
1395         if (!flow) {
1396                 PMD_DRV_LOG(ERR, "failed to allocate memory");
1397                 return (struct rte_flow *)flow;
1398         }
1399         igb_flow_mem_ptr = rte_zmalloc("igb_flow_mem",
1400                         sizeof(struct igb_flow_mem), 0);
1401         if (!igb_flow_mem_ptr) {
1402                 PMD_DRV_LOG(ERR, "failed to allocate memory");
1403                 rte_free(flow);
1404                 return NULL;
1405         }
1406         igb_flow_mem_ptr->flow = flow;
1407         igb_flow_mem_ptr->dev = dev;
1408         TAILQ_INSERT_TAIL(&igb_flow_list,
1409                                 igb_flow_mem_ptr, entries);
1410
1411         memset(&ntuple_filter, 0, sizeof(struct rte_eth_ntuple_filter));
1412         ret = igb_parse_ntuple_filter(dev, attr, pattern,
1413                         actions, &ntuple_filter, error);
1414         if (!ret) {
1415                 ret = igb_add_del_ntuple_filter(dev, &ntuple_filter, TRUE);
1416                 if (!ret) {
1417                         ntuple_filter_ptr = rte_zmalloc("igb_ntuple_filter",
1418                                 sizeof(struct igb_ntuple_filter_ele), 0);
1419                         if (!ntuple_filter_ptr) {
1420                                 PMD_DRV_LOG(ERR, "failed to allocate memory");
1421                                 goto out;
1422                         }
1423
1424                         rte_memcpy(&ntuple_filter_ptr->filter_info,
1425                                 &ntuple_filter,
1426                                 sizeof(struct rte_eth_ntuple_filter));
1427                         TAILQ_INSERT_TAIL(&igb_filter_ntuple_list,
1428                                 ntuple_filter_ptr, entries);
1429                         flow->rule = ntuple_filter_ptr;
1430                         flow->filter_type = RTE_ETH_FILTER_NTUPLE;
1431                         return flow;
1432                 }
1433                 goto out;
1434         }
1435
1436         memset(&ethertype_filter, 0, sizeof(struct rte_eth_ethertype_filter));
1437         ret = igb_parse_ethertype_filter(dev, attr, pattern,
1438                                 actions, &ethertype_filter, error);
1439         if (!ret) {
1440                 ret = igb_add_del_ethertype_filter(dev,
1441                                 &ethertype_filter, TRUE);
1442                 if (!ret) {
1443                         ethertype_filter_ptr = rte_zmalloc(
1444                                 "igb_ethertype_filter",
1445                                 sizeof(struct igb_ethertype_filter_ele), 0);
1446                         if (!ethertype_filter_ptr) {
1447                                 PMD_DRV_LOG(ERR, "failed to allocate memory");
1448                                 goto out;
1449                         }
1450
1451                         rte_memcpy(&ethertype_filter_ptr->filter_info,
1452                                 &ethertype_filter,
1453                                 sizeof(struct rte_eth_ethertype_filter));
1454                         TAILQ_INSERT_TAIL(&igb_filter_ethertype_list,
1455                                 ethertype_filter_ptr, entries);
1456                         flow->rule = ethertype_filter_ptr;
1457                         flow->filter_type = RTE_ETH_FILTER_ETHERTYPE;
1458                         return flow;
1459                 }
1460                 goto out;
1461         }
1462
1463         memset(&syn_filter, 0, sizeof(struct rte_eth_syn_filter));
1464         ret = igb_parse_syn_filter(dev, attr, pattern,
1465                                 actions, &syn_filter, error);
1466         if (!ret) {
1467                 ret = eth_igb_syn_filter_set(dev, &syn_filter, TRUE);
1468                 if (!ret) {
1469                         syn_filter_ptr = rte_zmalloc("igb_syn_filter",
1470                                 sizeof(struct igb_eth_syn_filter_ele), 0);
1471                         if (!syn_filter_ptr) {
1472                                 PMD_DRV_LOG(ERR, "failed to allocate memory");
1473                                 goto out;
1474                         }
1475
1476                         rte_memcpy(&syn_filter_ptr->filter_info,
1477                                 &syn_filter,
1478                                 sizeof(struct rte_eth_syn_filter));
1479                         TAILQ_INSERT_TAIL(&igb_filter_syn_list,
1480                                 syn_filter_ptr,
1481                                 entries);
1482                         flow->rule = syn_filter_ptr;
1483                         flow->filter_type = RTE_ETH_FILTER_SYN;
1484                         return flow;
1485                 }
1486                 goto out;
1487         }
1488
1489         memset(&flex_filter, 0, sizeof(struct rte_eth_flex_filter));
1490         ret = igb_parse_flex_filter(dev, attr, pattern,
1491                                         actions, &flex_filter, error);
1492         if (!ret) {
1493                 ret = eth_igb_add_del_flex_filter(dev, &flex_filter, TRUE);
1494                 if (!ret) {
1495                         flex_filter_ptr = rte_zmalloc("igb_flex_filter",
1496                                 sizeof(struct igb_flex_filter_ele), 0);
1497                         if (!flex_filter_ptr) {
1498                                 PMD_DRV_LOG(ERR, "failed to allocate memory");
1499                                 goto out;
1500                         }
1501
1502                         rte_memcpy(&flex_filter_ptr->filter_info,
1503                                 &flex_filter,
1504                                 sizeof(struct rte_eth_flex_filter));
1505                         TAILQ_INSERT_TAIL(&igb_filter_flex_list,
1506                                 flex_filter_ptr, entries);
1507                         flow->rule = flex_filter_ptr;
1508                         flow->filter_type = RTE_ETH_FILTER_FLEXIBLE;
1509                         return flow;
1510                 }
1511         }
1512
1513         memset(&rss_conf, 0, sizeof(struct igb_rte_flow_rss_conf));
1514         ret = igb_parse_rss_filter(dev, attr,
1515                                         actions, &rss_conf, error);
1516         if (!ret) {
1517                 ret = igb_config_rss_filter(dev, &rss_conf, TRUE);
1518                 if (!ret) {
1519                         rss_filter_ptr = rte_zmalloc("igb_rss_filter",
1520                                 sizeof(struct igb_rss_conf_ele), 0);
1521                         if (!rss_filter_ptr) {
1522                                 PMD_DRV_LOG(ERR, "failed to allocate memory");
1523                                 goto out;
1524                         }
1525                         igb_rss_conf_init(&rss_filter_ptr->filter_info,
1526                                           &rss_conf.conf);
1527                         TAILQ_INSERT_TAIL(&igb_filter_rss_list,
1528                                 rss_filter_ptr, entries);
1529                         flow->rule = rss_filter_ptr;
1530                         flow->filter_type = RTE_ETH_FILTER_HASH;
1531                         return flow;
1532                 }
1533         }
1534
1535 out:
1536         TAILQ_REMOVE(&igb_flow_list,
1537                 igb_flow_mem_ptr, entries);
1538         rte_flow_error_set(error, -ret,
1539                            RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
1540                            "Failed to create flow.");
1541         rte_free(igb_flow_mem_ptr);
1542         rte_free(flow);
1543         return NULL;
1544 }
1545
1546 /**
1547  * Check if the flow rule is supported by igb.
1548  * It only checkes the format. Don't guarantee the rule can be programmed into
1549  * the HW. Because there can be no enough room for the rule.
1550  */
1551 static int
1552 igb_flow_validate(__rte_unused struct rte_eth_dev *dev,
1553                 const struct rte_flow_attr *attr,
1554                 const struct rte_flow_item pattern[],
1555                 const struct rte_flow_action actions[],
1556                 struct rte_flow_error *error)
1557 {
1558         struct rte_eth_ntuple_filter ntuple_filter;
1559         struct rte_eth_ethertype_filter ethertype_filter;
1560         struct rte_eth_syn_filter syn_filter;
1561         struct rte_eth_flex_filter flex_filter;
1562         struct igb_rte_flow_rss_conf rss_conf;
1563         int ret;
1564
1565         memset(&ntuple_filter, 0, sizeof(struct rte_eth_ntuple_filter));
1566         ret = igb_parse_ntuple_filter(dev, attr, pattern,
1567                                 actions, &ntuple_filter, error);
1568         if (!ret)
1569                 return 0;
1570
1571         memset(&ethertype_filter, 0, sizeof(struct rte_eth_ethertype_filter));
1572         ret = igb_parse_ethertype_filter(dev, attr, pattern,
1573                                 actions, &ethertype_filter, error);
1574         if (!ret)
1575                 return 0;
1576
1577         memset(&syn_filter, 0, sizeof(struct rte_eth_syn_filter));
1578         ret = igb_parse_syn_filter(dev, attr, pattern,
1579                                 actions, &syn_filter, error);
1580         if (!ret)
1581                 return 0;
1582
1583         memset(&flex_filter, 0, sizeof(struct rte_eth_flex_filter));
1584         ret = igb_parse_flex_filter(dev, attr, pattern,
1585                                 actions, &flex_filter, error);
1586         if (!ret)
1587                 return 0;
1588
1589         memset(&rss_conf, 0, sizeof(struct igb_rte_flow_rss_conf));
1590         ret = igb_parse_rss_filter(dev, attr,
1591                                         actions, &rss_conf, error);
1592
1593         return ret;
1594 }
1595
1596 /* Destroy a flow rule on igb. */
1597 static int
1598 igb_flow_destroy(struct rte_eth_dev *dev,
1599                 struct rte_flow *flow,
1600                 struct rte_flow_error *error)
1601 {
1602         int ret;
1603         struct rte_flow *pmd_flow = flow;
1604         enum rte_filter_type filter_type = pmd_flow->filter_type;
1605         struct igb_ntuple_filter_ele *ntuple_filter_ptr;
1606         struct igb_ethertype_filter_ele *ethertype_filter_ptr;
1607         struct igb_eth_syn_filter_ele *syn_filter_ptr;
1608         struct igb_flex_filter_ele *flex_filter_ptr;
1609         struct igb_flow_mem *igb_flow_mem_ptr;
1610         struct igb_rss_conf_ele *rss_filter_ptr;
1611
1612         switch (filter_type) {
1613         case RTE_ETH_FILTER_NTUPLE:
1614                 ntuple_filter_ptr = (struct igb_ntuple_filter_ele *)
1615                                         pmd_flow->rule;
1616                 ret = igb_add_del_ntuple_filter(dev,
1617                                 &ntuple_filter_ptr->filter_info, FALSE);
1618                 if (!ret) {
1619                         TAILQ_REMOVE(&igb_filter_ntuple_list,
1620                         ntuple_filter_ptr, entries);
1621                         rte_free(ntuple_filter_ptr);
1622                 }
1623                 break;
1624         case RTE_ETH_FILTER_ETHERTYPE:
1625                 ethertype_filter_ptr = (struct igb_ethertype_filter_ele *)
1626                                         pmd_flow->rule;
1627                 ret = igb_add_del_ethertype_filter(dev,
1628                                 &ethertype_filter_ptr->filter_info, FALSE);
1629                 if (!ret) {
1630                         TAILQ_REMOVE(&igb_filter_ethertype_list,
1631                                 ethertype_filter_ptr, entries);
1632                         rte_free(ethertype_filter_ptr);
1633                 }
1634                 break;
1635         case RTE_ETH_FILTER_SYN:
1636                 syn_filter_ptr = (struct igb_eth_syn_filter_ele *)
1637                                 pmd_flow->rule;
1638                 ret = eth_igb_syn_filter_set(dev,
1639                                 &syn_filter_ptr->filter_info, FALSE);
1640                 if (!ret) {
1641                         TAILQ_REMOVE(&igb_filter_syn_list,
1642                                 syn_filter_ptr, entries);
1643                         rte_free(syn_filter_ptr);
1644                 }
1645                 break;
1646         case RTE_ETH_FILTER_FLEXIBLE:
1647                 flex_filter_ptr = (struct igb_flex_filter_ele *)
1648                                 pmd_flow->rule;
1649                 ret = eth_igb_add_del_flex_filter(dev,
1650                                 &flex_filter_ptr->filter_info, FALSE);
1651                 if (!ret) {
1652                         TAILQ_REMOVE(&igb_filter_flex_list,
1653                                 flex_filter_ptr, entries);
1654                         rte_free(flex_filter_ptr);
1655                 }
1656                 break;
1657         case RTE_ETH_FILTER_HASH:
1658                 rss_filter_ptr = (struct igb_rss_conf_ele *)
1659                                 pmd_flow->rule;
1660                 ret = igb_config_rss_filter(dev,
1661                                         &rss_filter_ptr->filter_info, FALSE);
1662                 if (!ret) {
1663                         TAILQ_REMOVE(&igb_filter_rss_list,
1664                                 rss_filter_ptr, entries);
1665                         rte_free(rss_filter_ptr);
1666                 }
1667                 break;
1668         default:
1669                 PMD_DRV_LOG(WARNING, "Filter type (%d) not supported",
1670                             filter_type);
1671                 ret = -EINVAL;
1672                 break;
1673         }
1674
1675         if (ret) {
1676                 rte_flow_error_set(error, EINVAL,
1677                                 RTE_FLOW_ERROR_TYPE_HANDLE,
1678                                 NULL, "Failed to destroy flow");
1679                 return ret;
1680         }
1681
1682         TAILQ_FOREACH(igb_flow_mem_ptr, &igb_flow_list, entries) {
1683                 if (igb_flow_mem_ptr->flow == pmd_flow) {
1684                         TAILQ_REMOVE(&igb_flow_list,
1685                                 igb_flow_mem_ptr, entries);
1686                         rte_free(igb_flow_mem_ptr);
1687                 }
1688         }
1689         rte_free(flow);
1690
1691         return ret;
1692 }
1693
1694 /* remove all the n-tuple filters */
1695 static void
1696 igb_clear_all_ntuple_filter(struct rte_eth_dev *dev)
1697 {
1698         struct e1000_filter_info *filter_info =
1699                 E1000_DEV_PRIVATE_TO_FILTER_INFO(dev->data->dev_private);
1700         struct e1000_5tuple_filter *p_5tuple;
1701         struct e1000_2tuple_filter *p_2tuple;
1702
1703         while ((p_5tuple = TAILQ_FIRST(&filter_info->fivetuple_list)))
1704                 igb_delete_5tuple_filter_82576(dev, p_5tuple);
1705
1706         while ((p_2tuple = TAILQ_FIRST(&filter_info->twotuple_list)))
1707                 igb_delete_2tuple_filter(dev, p_2tuple);
1708 }
1709
1710 /* remove all the ether type filters */
1711 static void
1712 igb_clear_all_ethertype_filter(struct rte_eth_dev *dev)
1713 {
1714         struct e1000_hw *hw = E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);
1715         struct e1000_filter_info *filter_info =
1716                 E1000_DEV_PRIVATE_TO_FILTER_INFO(dev->data->dev_private);
1717         int i;
1718
1719         for (i = 0; i < E1000_MAX_ETQF_FILTERS; i++) {
1720                 if (filter_info->ethertype_mask & (1 << i)) {
1721                         (void)igb_ethertype_filter_remove(filter_info,
1722                                                             (uint8_t)i);
1723                         E1000_WRITE_REG(hw, E1000_ETQF(i), 0);
1724                         E1000_WRITE_FLUSH(hw);
1725                 }
1726         }
1727 }
1728
1729 /* remove the SYN filter */
1730 static void
1731 igb_clear_syn_filter(struct rte_eth_dev *dev)
1732 {
1733         struct e1000_hw *hw = E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);
1734         struct e1000_filter_info *filter_info =
1735                 E1000_DEV_PRIVATE_TO_FILTER_INFO(dev->data->dev_private);
1736
1737         if (filter_info->syn_info & E1000_SYN_FILTER_ENABLE) {
1738                 filter_info->syn_info = 0;
1739                 E1000_WRITE_REG(hw, E1000_SYNQF(0), 0);
1740                 E1000_WRITE_FLUSH(hw);
1741         }
1742 }
1743
1744 /* remove all the flex filters */
1745 static void
1746 igb_clear_all_flex_filter(struct rte_eth_dev *dev)
1747 {
1748         struct e1000_filter_info *filter_info =
1749                 E1000_DEV_PRIVATE_TO_FILTER_INFO(dev->data->dev_private);
1750         struct e1000_flex_filter *flex_filter;
1751
1752         while ((flex_filter = TAILQ_FIRST(&filter_info->flex_list)))
1753                 igb_remove_flex_filter(dev, flex_filter);
1754 }
1755
1756 /* remove the rss filter */
1757 static void
1758 igb_clear_rss_filter(struct rte_eth_dev *dev)
1759 {
1760         struct e1000_filter_info *filter =
1761                 E1000_DEV_PRIVATE_TO_FILTER_INFO(dev->data->dev_private);
1762
1763         if (filter->rss_info.conf.queue_num)
1764                 igb_config_rss_filter(dev, &filter->rss_info, FALSE);
1765 }
1766
1767 void
1768 igb_filterlist_flush(struct rte_eth_dev *dev)
1769 {
1770         struct igb_ntuple_filter_ele *ntuple_filter_ptr;
1771         struct igb_ethertype_filter_ele *ethertype_filter_ptr;
1772         struct igb_eth_syn_filter_ele *syn_filter_ptr;
1773         struct igb_flex_filter_ele *flex_filter_ptr;
1774         struct igb_rss_conf_ele  *rss_filter_ptr;
1775         struct igb_flow_mem *igb_flow_mem_ptr;
1776         enum rte_filter_type filter_type;
1777         struct rte_flow *pmd_flow;
1778
1779         TAILQ_FOREACH(igb_flow_mem_ptr, &igb_flow_list, entries) {
1780                 if (igb_flow_mem_ptr->dev == dev) {
1781                         pmd_flow = igb_flow_mem_ptr->flow;
1782                         filter_type = pmd_flow->filter_type;
1783
1784                         switch (filter_type) {
1785                         case RTE_ETH_FILTER_NTUPLE:
1786                                 ntuple_filter_ptr =
1787                                 (struct igb_ntuple_filter_ele *)
1788                                         pmd_flow->rule;
1789                                 TAILQ_REMOVE(&igb_filter_ntuple_list,
1790                                                 ntuple_filter_ptr, entries);
1791                                 rte_free(ntuple_filter_ptr);
1792                                 break;
1793                         case RTE_ETH_FILTER_ETHERTYPE:
1794                                 ethertype_filter_ptr =
1795                                 (struct igb_ethertype_filter_ele *)
1796                                         pmd_flow->rule;
1797                                 TAILQ_REMOVE(&igb_filter_ethertype_list,
1798                                                 ethertype_filter_ptr, entries);
1799                                 rte_free(ethertype_filter_ptr);
1800                                 break;
1801                         case RTE_ETH_FILTER_SYN:
1802                                 syn_filter_ptr =
1803                                         (struct igb_eth_syn_filter_ele *)
1804                                                 pmd_flow->rule;
1805                                 TAILQ_REMOVE(&igb_filter_syn_list,
1806                                                 syn_filter_ptr, entries);
1807                                 rte_free(syn_filter_ptr);
1808                                 break;
1809                         case RTE_ETH_FILTER_FLEXIBLE:
1810                                 flex_filter_ptr =
1811                                         (struct igb_flex_filter_ele *)
1812                                                 pmd_flow->rule;
1813                                 TAILQ_REMOVE(&igb_filter_flex_list,
1814                                                 flex_filter_ptr, entries);
1815                                 rte_free(flex_filter_ptr);
1816                                 break;
1817                         case RTE_ETH_FILTER_HASH:
1818                                 rss_filter_ptr =
1819                                         (struct igb_rss_conf_ele *)
1820                                                 pmd_flow->rule;
1821                                 TAILQ_REMOVE(&igb_filter_rss_list,
1822                                                 rss_filter_ptr, entries);
1823                                 rte_free(rss_filter_ptr);
1824                                 break;
1825                         default:
1826                                 PMD_DRV_LOG(WARNING, "Filter type"
1827                                         "(%d) not supported", filter_type);
1828                                 break;
1829                         }
1830                         TAILQ_REMOVE(&igb_flow_list,
1831                                  igb_flow_mem_ptr,
1832                                  entries);
1833                         rte_free(igb_flow_mem_ptr->flow);
1834                         rte_free(igb_flow_mem_ptr);
1835                 }
1836         }
1837 }
1838
1839 /*  Destroy all flow rules associated with a port on igb. */
1840 static int
1841 igb_flow_flush(struct rte_eth_dev *dev,
1842                 __rte_unused struct rte_flow_error *error)
1843 {
1844         igb_clear_all_ntuple_filter(dev);
1845         igb_clear_all_ethertype_filter(dev);
1846         igb_clear_syn_filter(dev);
1847         igb_clear_all_flex_filter(dev);
1848         igb_clear_rss_filter(dev);
1849         igb_filterlist_flush(dev);
1850
1851         return 0;
1852 }
1853
1854 const struct rte_flow_ops igb_flow_ops = {
1855         .validate = igb_flow_validate,
1856         .create = igb_flow_create,
1857         .destroy = igb_flow_destroy,
1858         .flush = igb_flow_flush,
1859 };