net/ixgbe: replace macro with inline function
[dpdk.git] / drivers / net / ixgbe / ixgbe_flow.c
1 /*-
2  *   BSD LICENSE
3  *
4  *   Copyright(c) 2010-2016 Intel Corporation. All rights reserved.
5  *   All rights reserved.
6  *
7  *   Redistribution and use in source and binary forms, with or without
8  *   modification, are permitted provided that the following conditions
9  *   are met:
10  *
11  *     * Redistributions of source code must retain the above copyright
12  *       notice, this list of conditions and the following disclaimer.
13  *     * Redistributions in binary form must reproduce the above copyright
14  *       notice, this list of conditions and the following disclaimer in
15  *       the documentation and/or other materials provided with the
16  *       distribution.
17  *     * Neither the name of Intel Corporation nor the names of its
18  *       contributors may be used to endorse or promote products derived
19  *       from this software without specific prior written permission.
20  *
21  *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22  *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23  *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24  *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25  *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26  *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27  *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28  *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29  *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30  *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31  *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32  */
33
34 #include <sys/queue.h>
35 #include <stdio.h>
36 #include <errno.h>
37 #include <stdint.h>
38 #include <string.h>
39 #include <unistd.h>
40 #include <stdarg.h>
41 #include <inttypes.h>
42 #include <netinet/in.h>
43 #include <rte_byteorder.h>
44 #include <rte_common.h>
45 #include <rte_cycles.h>
46
47 #include <rte_interrupts.h>
48 #include <rte_log.h>
49 #include <rte_debug.h>
50 #include <rte_pci.h>
51 #include <rte_atomic.h>
52 #include <rte_branch_prediction.h>
53 #include <rte_memory.h>
54 #include <rte_memzone.h>
55 #include <rte_eal.h>
56 #include <rte_alarm.h>
57 #include <rte_ether.h>
58 #include <rte_ethdev.h>
59 #include <rte_atomic.h>
60 #include <rte_malloc.h>
61 #include <rte_random.h>
62 #include <rte_dev.h>
63 #include <rte_hash_crc.h>
64 #include <rte_flow.h>
65 #include <rte_flow_driver.h>
66
67 #include "ixgbe_logs.h"
68 #include "base/ixgbe_api.h"
69 #include "base/ixgbe_vf.h"
70 #include "base/ixgbe_common.h"
71 #include "ixgbe_ethdev.h"
72 #include "ixgbe_bypass.h"
73 #include "ixgbe_rxtx.h"
74 #include "base/ixgbe_type.h"
75 #include "base/ixgbe_phy.h"
76 #include "rte_pmd_ixgbe.h"
77
78
79 #define IXGBE_MIN_N_TUPLE_PRIO 1
80 #define IXGBE_MAX_N_TUPLE_PRIO 7
81 #define IXGBE_MAX_FLX_SOURCE_OFF 62
82
83 /**
84  * Endless loop will never happen with below assumption
85  * 1. there is at least one no-void item(END)
86  * 2. cur is before END.
87  */
88 static inline
89 const struct rte_flow_item *next_no_void_pattern(
90                 const struct rte_flow_item pattern[],
91                 const struct rte_flow_item *cur)
92 {
93         const struct rte_flow_item *next =
94                 cur ? cur + 1 : &pattern[0];
95         while (1) {
96                 if (next->type != RTE_FLOW_ITEM_TYPE_VOID)
97                         return next;
98                 next++;
99         }
100 }
101
102 static inline
103 const struct rte_flow_action *next_no_void_action(
104                 const struct rte_flow_action actions[],
105                 const struct rte_flow_action *cur)
106 {
107         const struct rte_flow_action *next =
108                 cur ? cur + 1 : &actions[0];
109         while (1) {
110                 if (next->type != RTE_FLOW_ACTION_TYPE_VOID)
111                         return next;
112                 next++;
113         }
114 }
115
116 /**
117  * Please aware there's an asumption for all the parsers.
118  * rte_flow_item is using big endian, rte_flow_attr and
119  * rte_flow_action are using CPU order.
120  * Because the pattern is used to describe the packets,
121  * normally the packets should use network order.
122  */
123
124 /**
125  * Parse the rule to see if it is a n-tuple rule.
126  * And get the n-tuple filter info BTW.
127  * pattern:
128  * The first not void item can be ETH or IPV4.
129  * The second not void item must be IPV4 if the first one is ETH.
130  * The third not void item must be UDP or TCP.
131  * The next not void item must be END.
132  * action:
133  * The first not void action should be QUEUE.
134  * The next not void action should be END.
135  * pattern example:
136  * ITEM         Spec                    Mask
137  * ETH          NULL                    NULL
138  * IPV4         src_addr 192.168.1.20   0xFFFFFFFF
139  *              dst_addr 192.167.3.50   0xFFFFFFFF
140  *              next_proto_id   17      0xFF
141  * UDP/TCP/     src_port        80      0xFFFF
142  * SCTP         dst_port        80      0xFFFF
143  * END
144  * other members in mask and spec should set to 0x00.
145  * item->last should be NULL.
146  */
147 static int
148 cons_parse_ntuple_filter(const struct rte_flow_attr *attr,
149                          const struct rte_flow_item pattern[],
150                          const struct rte_flow_action actions[],
151                          struct rte_eth_ntuple_filter *filter,
152                          struct rte_flow_error *error)
153 {
154         const struct rte_flow_item *item;
155         const struct rte_flow_action *act;
156         const struct rte_flow_item_ipv4 *ipv4_spec;
157         const struct rte_flow_item_ipv4 *ipv4_mask;
158         const struct rte_flow_item_tcp *tcp_spec;
159         const struct rte_flow_item_tcp *tcp_mask;
160         const struct rte_flow_item_udp *udp_spec;
161         const struct rte_flow_item_udp *udp_mask;
162         const struct rte_flow_item_sctp *sctp_spec;
163         const struct rte_flow_item_sctp *sctp_mask;
164
165         if (!pattern) {
166                 rte_flow_error_set(error,
167                         EINVAL, RTE_FLOW_ERROR_TYPE_ITEM_NUM,
168                         NULL, "NULL pattern.");
169                 return -rte_errno;
170         }
171
172         if (!actions) {
173                 rte_flow_error_set(error, EINVAL,
174                                    RTE_FLOW_ERROR_TYPE_ACTION_NUM,
175                                    NULL, "NULL action.");
176                 return -rte_errno;
177         }
178         if (!attr) {
179                 rte_flow_error_set(error, EINVAL,
180                                    RTE_FLOW_ERROR_TYPE_ATTR,
181                                    NULL, "NULL attribute.");
182                 return -rte_errno;
183         }
184
185         /* the first not void item can be MAC or IPv4 */
186         item = next_no_void_pattern(pattern, NULL);
187
188         if (item->type != RTE_FLOW_ITEM_TYPE_ETH &&
189             item->type != RTE_FLOW_ITEM_TYPE_IPV4) {
190                 rte_flow_error_set(error, EINVAL,
191                         RTE_FLOW_ERROR_TYPE_ITEM,
192                         item, "Not supported by ntuple filter");
193                 return -rte_errno;
194         }
195         /* Skip Ethernet */
196         if (item->type == RTE_FLOW_ITEM_TYPE_ETH) {
197                 /*Not supported last point for range*/
198                 if (item->last) {
199                         rte_flow_error_set(error,
200                           EINVAL,
201                           RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
202                           item, "Not supported last point for range");
203                         return -rte_errno;
204
205                 }
206                 /* if the first item is MAC, the content should be NULL */
207                 if (item->spec || item->mask) {
208                         rte_flow_error_set(error, EINVAL,
209                                 RTE_FLOW_ERROR_TYPE_ITEM,
210                                 item, "Not supported by ntuple filter");
211                         return -rte_errno;
212                 }
213                 /* check if the next not void item is IPv4 */
214                 item = next_no_void_pattern(pattern, item);
215                 if (item->type != RTE_FLOW_ITEM_TYPE_IPV4) {
216                         rte_flow_error_set(error,
217                           EINVAL, RTE_FLOW_ERROR_TYPE_ITEM,
218                           item, "Not supported by ntuple filter");
219                           return -rte_errno;
220                 }
221         }
222
223         /* get the IPv4 info */
224         if (!item->spec || !item->mask) {
225                 rte_flow_error_set(error, EINVAL,
226                         RTE_FLOW_ERROR_TYPE_ITEM,
227                         item, "Invalid ntuple mask");
228                 return -rte_errno;
229         }
230         /*Not supported last point for range*/
231         if (item->last) {
232                 rte_flow_error_set(error, EINVAL,
233                         RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
234                         item, "Not supported last point for range");
235                 return -rte_errno;
236
237         }
238
239         ipv4_mask = (const struct rte_flow_item_ipv4 *)item->mask;
240         /**
241          * Only support src & dst addresses, protocol,
242          * others should be masked.
243          */
244         if (ipv4_mask->hdr.version_ihl ||
245             ipv4_mask->hdr.type_of_service ||
246             ipv4_mask->hdr.total_length ||
247             ipv4_mask->hdr.packet_id ||
248             ipv4_mask->hdr.fragment_offset ||
249             ipv4_mask->hdr.time_to_live ||
250             ipv4_mask->hdr.hdr_checksum) {
251                         rte_flow_error_set(error,
252                         EINVAL, RTE_FLOW_ERROR_TYPE_ITEM,
253                         item, "Not supported by ntuple filter");
254                 return -rte_errno;
255         }
256
257         filter->dst_ip_mask = ipv4_mask->hdr.dst_addr;
258         filter->src_ip_mask = ipv4_mask->hdr.src_addr;
259         filter->proto_mask  = ipv4_mask->hdr.next_proto_id;
260
261         ipv4_spec = (const struct rte_flow_item_ipv4 *)item->spec;
262         filter->dst_ip = ipv4_spec->hdr.dst_addr;
263         filter->src_ip = ipv4_spec->hdr.src_addr;
264         filter->proto  = ipv4_spec->hdr.next_proto_id;
265
266         /* check if the next not void item is TCP or UDP */
267         item = next_no_void_pattern(pattern, item);
268         if (item->type != RTE_FLOW_ITEM_TYPE_TCP &&
269             item->type != RTE_FLOW_ITEM_TYPE_UDP &&
270             item->type != RTE_FLOW_ITEM_TYPE_SCTP) {
271                 memset(filter, 0, sizeof(struct rte_eth_ntuple_filter));
272                 rte_flow_error_set(error, EINVAL,
273                         RTE_FLOW_ERROR_TYPE_ITEM,
274                         item, "Not supported by ntuple filter");
275                 return -rte_errno;
276         }
277
278         /* get the TCP/UDP info */
279         if (!item->spec || !item->mask) {
280                 memset(filter, 0, sizeof(struct rte_eth_ntuple_filter));
281                 rte_flow_error_set(error, EINVAL,
282                         RTE_FLOW_ERROR_TYPE_ITEM,
283                         item, "Invalid ntuple mask");
284                 return -rte_errno;
285         }
286
287         /*Not supported last point for range*/
288         if (item->last) {
289                 memset(filter, 0, sizeof(struct rte_eth_ntuple_filter));
290                 rte_flow_error_set(error, EINVAL,
291                         RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
292                         item, "Not supported last point for range");
293                 return -rte_errno;
294
295         }
296
297         if (item->type == RTE_FLOW_ITEM_TYPE_TCP) {
298                 tcp_mask = (const struct rte_flow_item_tcp *)item->mask;
299
300                 /**
301                  * Only support src & dst ports, tcp flags,
302                  * others should be masked.
303                  */
304                 if (tcp_mask->hdr.sent_seq ||
305                     tcp_mask->hdr.recv_ack ||
306                     tcp_mask->hdr.data_off ||
307                     tcp_mask->hdr.rx_win ||
308                     tcp_mask->hdr.cksum ||
309                     tcp_mask->hdr.tcp_urp) {
310                         memset(filter, 0,
311                                 sizeof(struct rte_eth_ntuple_filter));
312                         rte_flow_error_set(error, EINVAL,
313                                 RTE_FLOW_ERROR_TYPE_ITEM,
314                                 item, "Not supported by ntuple filter");
315                         return -rte_errno;
316                 }
317
318                 filter->dst_port_mask  = tcp_mask->hdr.dst_port;
319                 filter->src_port_mask  = tcp_mask->hdr.src_port;
320                 if (tcp_mask->hdr.tcp_flags == 0xFF) {
321                         filter->flags |= RTE_NTUPLE_FLAGS_TCP_FLAG;
322                 } else if (!tcp_mask->hdr.tcp_flags) {
323                         filter->flags &= ~RTE_NTUPLE_FLAGS_TCP_FLAG;
324                 } else {
325                         memset(filter, 0, sizeof(struct rte_eth_ntuple_filter));
326                         rte_flow_error_set(error, EINVAL,
327                                 RTE_FLOW_ERROR_TYPE_ITEM,
328                                 item, "Not supported by ntuple filter");
329                         return -rte_errno;
330                 }
331
332                 tcp_spec = (const struct rte_flow_item_tcp *)item->spec;
333                 filter->dst_port  = tcp_spec->hdr.dst_port;
334                 filter->src_port  = tcp_spec->hdr.src_port;
335                 filter->tcp_flags = tcp_spec->hdr.tcp_flags;
336         } else if (item->type == RTE_FLOW_ITEM_TYPE_UDP) {
337                 udp_mask = (const struct rte_flow_item_udp *)item->mask;
338
339                 /**
340                  * Only support src & dst ports,
341                  * others should be masked.
342                  */
343                 if (udp_mask->hdr.dgram_len ||
344                     udp_mask->hdr.dgram_cksum) {
345                         memset(filter, 0,
346                                 sizeof(struct rte_eth_ntuple_filter));
347                         rte_flow_error_set(error, EINVAL,
348                                 RTE_FLOW_ERROR_TYPE_ITEM,
349                                 item, "Not supported by ntuple filter");
350                         return -rte_errno;
351                 }
352
353                 filter->dst_port_mask = udp_mask->hdr.dst_port;
354                 filter->src_port_mask = udp_mask->hdr.src_port;
355
356                 udp_spec = (const struct rte_flow_item_udp *)item->spec;
357                 filter->dst_port = udp_spec->hdr.dst_port;
358                 filter->src_port = udp_spec->hdr.src_port;
359         } else {
360                 sctp_mask = (const struct rte_flow_item_sctp *)item->mask;
361
362                 /**
363                  * Only support src & dst ports,
364                  * others should be masked.
365                  */
366                 if (sctp_mask->hdr.tag ||
367                     sctp_mask->hdr.cksum) {
368                         memset(filter, 0,
369                                 sizeof(struct rte_eth_ntuple_filter));
370                         rte_flow_error_set(error, EINVAL,
371                                 RTE_FLOW_ERROR_TYPE_ITEM,
372                                 item, "Not supported by ntuple filter");
373                         return -rte_errno;
374                 }
375
376                 filter->dst_port_mask = sctp_mask->hdr.dst_port;
377                 filter->src_port_mask = sctp_mask->hdr.src_port;
378
379                 sctp_spec = (const struct rte_flow_item_sctp *)item->spec;
380                 filter->dst_port = sctp_spec->hdr.dst_port;
381                 filter->src_port = sctp_spec->hdr.src_port;
382         }
383
384         /* check if the next not void item is END */
385         item = next_no_void_pattern(pattern, item);
386         if (item->type != RTE_FLOW_ITEM_TYPE_END) {
387                 memset(filter, 0, sizeof(struct rte_eth_ntuple_filter));
388                 rte_flow_error_set(error, EINVAL,
389                         RTE_FLOW_ERROR_TYPE_ITEM,
390                         item, "Not supported by ntuple filter");
391                 return -rte_errno;
392         }
393
394         /**
395          * n-tuple only supports forwarding,
396          * check if the first not void action is QUEUE.
397          */
398         act = next_no_void_action(actions, NULL);
399         if (act->type != RTE_FLOW_ACTION_TYPE_QUEUE) {
400                 memset(filter, 0, sizeof(struct rte_eth_ntuple_filter));
401                 rte_flow_error_set(error, EINVAL,
402                         RTE_FLOW_ERROR_TYPE_ACTION,
403                         item, "Not supported action.");
404                 return -rte_errno;
405         }
406         filter->queue =
407                 ((const struct rte_flow_action_queue *)act->conf)->index;
408
409         /* check if the next not void item is END */
410         act = next_no_void_action(actions, act);
411         if (act->type != RTE_FLOW_ACTION_TYPE_END) {
412                 memset(filter, 0, sizeof(struct rte_eth_ntuple_filter));
413                 rte_flow_error_set(error, EINVAL,
414                         RTE_FLOW_ERROR_TYPE_ACTION,
415                         act, "Not supported action.");
416                 return -rte_errno;
417         }
418
419         /* parse attr */
420         /* must be input direction */
421         if (!attr->ingress) {
422                 memset(filter, 0, sizeof(struct rte_eth_ntuple_filter));
423                 rte_flow_error_set(error, EINVAL,
424                                    RTE_FLOW_ERROR_TYPE_ATTR_INGRESS,
425                                    attr, "Only support ingress.");
426                 return -rte_errno;
427         }
428
429         /* not supported */
430         if (attr->egress) {
431                 memset(filter, 0, sizeof(struct rte_eth_ntuple_filter));
432                 rte_flow_error_set(error, EINVAL,
433                                    RTE_FLOW_ERROR_TYPE_ATTR_EGRESS,
434                                    attr, "Not support egress.");
435                 return -rte_errno;
436         }
437
438         if (attr->priority > 0xFFFF) {
439                 memset(filter, 0, sizeof(struct rte_eth_ntuple_filter));
440                 rte_flow_error_set(error, EINVAL,
441                                    RTE_FLOW_ERROR_TYPE_ATTR_PRIORITY,
442                                    attr, "Error priority.");
443                 return -rte_errno;
444         }
445         filter->priority = (uint16_t)attr->priority;
446         if (attr->priority < IXGBE_MIN_N_TUPLE_PRIO ||
447             attr->priority > IXGBE_MAX_N_TUPLE_PRIO)
448             filter->priority = 1;
449
450         return 0;
451 }
452
453 /* a specific function for ixgbe because the flags is specific */
454 static int
455 ixgbe_parse_ntuple_filter(struct rte_eth_dev *dev,
456                           const struct rte_flow_attr *attr,
457                           const struct rte_flow_item pattern[],
458                           const struct rte_flow_action actions[],
459                           struct rte_eth_ntuple_filter *filter,
460                           struct rte_flow_error *error)
461 {
462         int ret;
463         struct ixgbe_hw *hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
464
465         MAC_TYPE_FILTER_SUP_EXT(hw->mac.type);
466
467         ret = cons_parse_ntuple_filter(attr, pattern, actions, filter, error);
468
469         if (ret)
470                 return ret;
471
472         /* Ixgbe doesn't support tcp flags. */
473         if (filter->flags & RTE_NTUPLE_FLAGS_TCP_FLAG) {
474                 memset(filter, 0, sizeof(struct rte_eth_ntuple_filter));
475                 rte_flow_error_set(error, EINVAL,
476                                    RTE_FLOW_ERROR_TYPE_ITEM,
477                                    NULL, "Not supported by ntuple filter");
478                 return -rte_errno;
479         }
480
481         /* Ixgbe doesn't support many priorities. */
482         if (filter->priority < IXGBE_MIN_N_TUPLE_PRIO ||
483             filter->priority > IXGBE_MAX_N_TUPLE_PRIO) {
484                 memset(filter, 0, sizeof(struct rte_eth_ntuple_filter));
485                 rte_flow_error_set(error, EINVAL,
486                         RTE_FLOW_ERROR_TYPE_ITEM,
487                         NULL, "Priority not supported by ntuple filter");
488                 return -rte_errno;
489         }
490
491         if (filter->queue >= IXGBE_MAX_RX_QUEUE_NUM ||
492                 filter->priority > IXGBE_5TUPLE_MAX_PRI ||
493                 filter->priority < IXGBE_5TUPLE_MIN_PRI)
494                 return -rte_errno;
495
496         /* fixed value for ixgbe */
497         filter->flags = RTE_5TUPLE_FLAGS;
498         return 0;
499 }
500
501 /**
502  * Parse the rule to see if it is a ethertype rule.
503  * And get the ethertype filter info BTW.
504  * pattern:
505  * The first not void item can be ETH.
506  * The next not void item must be END.
507  * action:
508  * The first not void action should be QUEUE.
509  * The next not void action should be END.
510  * pattern example:
511  * ITEM         Spec                    Mask
512  * ETH          type    0x0807          0xFFFF
513  * END
514  * other members in mask and spec should set to 0x00.
515  * item->last should be NULL.
516  */
517 static int
518 cons_parse_ethertype_filter(const struct rte_flow_attr *attr,
519                             const struct rte_flow_item *pattern,
520                             const struct rte_flow_action *actions,
521                             struct rte_eth_ethertype_filter *filter,
522                             struct rte_flow_error *error)
523 {
524         const struct rte_flow_item *item;
525         const struct rte_flow_action *act;
526         const struct rte_flow_item_eth *eth_spec;
527         const struct rte_flow_item_eth *eth_mask;
528         const struct rte_flow_action_queue *act_q;
529
530         if (!pattern) {
531                 rte_flow_error_set(error, EINVAL,
532                                 RTE_FLOW_ERROR_TYPE_ITEM_NUM,
533                                 NULL, "NULL pattern.");
534                 return -rte_errno;
535         }
536
537         if (!actions) {
538                 rte_flow_error_set(error, EINVAL,
539                                 RTE_FLOW_ERROR_TYPE_ACTION_NUM,
540                                 NULL, "NULL action.");
541                 return -rte_errno;
542         }
543
544         if (!attr) {
545                 rte_flow_error_set(error, EINVAL,
546                                    RTE_FLOW_ERROR_TYPE_ATTR,
547                                    NULL, "NULL attribute.");
548                 return -rte_errno;
549         }
550
551         item = next_no_void_pattern(pattern, NULL);
552         /* The first non-void item should be MAC. */
553         if (item->type != RTE_FLOW_ITEM_TYPE_ETH) {
554                 rte_flow_error_set(error, EINVAL,
555                         RTE_FLOW_ERROR_TYPE_ITEM,
556                         item, "Not supported by ethertype filter");
557                 return -rte_errno;
558         }
559
560         /*Not supported last point for range*/
561         if (item->last) {
562                 rte_flow_error_set(error, EINVAL,
563                         RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
564                         item, "Not supported last point for range");
565                 return -rte_errno;
566         }
567
568         /* Get the MAC info. */
569         if (!item->spec || !item->mask) {
570                 rte_flow_error_set(error, EINVAL,
571                                 RTE_FLOW_ERROR_TYPE_ITEM,
572                                 item, "Not supported by ethertype filter");
573                 return -rte_errno;
574         }
575
576         eth_spec = (const struct rte_flow_item_eth *)item->spec;
577         eth_mask = (const struct rte_flow_item_eth *)item->mask;
578
579         /* Mask bits of source MAC address must be full of 0.
580          * Mask bits of destination MAC address must be full
581          * of 1 or full of 0.
582          */
583         if (!is_zero_ether_addr(&eth_mask->src) ||
584             (!is_zero_ether_addr(&eth_mask->dst) &&
585              !is_broadcast_ether_addr(&eth_mask->dst))) {
586                 rte_flow_error_set(error, EINVAL,
587                                 RTE_FLOW_ERROR_TYPE_ITEM,
588                                 item, "Invalid ether address mask");
589                 return -rte_errno;
590         }
591
592         if ((eth_mask->type & UINT16_MAX) != UINT16_MAX) {
593                 rte_flow_error_set(error, EINVAL,
594                                 RTE_FLOW_ERROR_TYPE_ITEM,
595                                 item, "Invalid ethertype mask");
596                 return -rte_errno;
597         }
598
599         /* If mask bits of destination MAC address
600          * are full of 1, set RTE_ETHTYPE_FLAGS_MAC.
601          */
602         if (is_broadcast_ether_addr(&eth_mask->dst)) {
603                 filter->mac_addr = eth_spec->dst;
604                 filter->flags |= RTE_ETHTYPE_FLAGS_MAC;
605         } else {
606                 filter->flags &= ~RTE_ETHTYPE_FLAGS_MAC;
607         }
608         filter->ether_type = rte_be_to_cpu_16(eth_spec->type);
609
610         /* Check if the next non-void item is END. */
611         item = next_no_void_pattern(pattern, item);
612         if (item->type != RTE_FLOW_ITEM_TYPE_END) {
613                 rte_flow_error_set(error, EINVAL,
614                                 RTE_FLOW_ERROR_TYPE_ITEM,
615                                 item, "Not supported by ethertype filter.");
616                 return -rte_errno;
617         }
618
619         /* Parse action */
620
621         act = next_no_void_action(actions, NULL);
622         if (act->type != RTE_FLOW_ACTION_TYPE_QUEUE &&
623             act->type != RTE_FLOW_ACTION_TYPE_DROP) {
624                 rte_flow_error_set(error, EINVAL,
625                                 RTE_FLOW_ERROR_TYPE_ACTION,
626                                 act, "Not supported action.");
627                 return -rte_errno;
628         }
629
630         if (act->type == RTE_FLOW_ACTION_TYPE_QUEUE) {
631                 act_q = (const struct rte_flow_action_queue *)act->conf;
632                 filter->queue = act_q->index;
633         } else {
634                 filter->flags |= RTE_ETHTYPE_FLAGS_DROP;
635         }
636
637         /* Check if the next non-void item is END */
638         act = next_no_void_action(actions, act);
639         if (act->type != RTE_FLOW_ACTION_TYPE_END) {
640                 rte_flow_error_set(error, EINVAL,
641                                 RTE_FLOW_ERROR_TYPE_ACTION,
642                                 act, "Not supported action.");
643                 return -rte_errno;
644         }
645
646         /* Parse attr */
647         /* Must be input direction */
648         if (!attr->ingress) {
649                 rte_flow_error_set(error, EINVAL,
650                                 RTE_FLOW_ERROR_TYPE_ATTR_INGRESS,
651                                 attr, "Only support ingress.");
652                 return -rte_errno;
653         }
654
655         /* Not supported */
656         if (attr->egress) {
657                 rte_flow_error_set(error, EINVAL,
658                                 RTE_FLOW_ERROR_TYPE_ATTR_EGRESS,
659                                 attr, "Not support egress.");
660                 return -rte_errno;
661         }
662
663         /* Not supported */
664         if (attr->priority) {
665                 rte_flow_error_set(error, EINVAL,
666                                 RTE_FLOW_ERROR_TYPE_ATTR_PRIORITY,
667                                 attr, "Not support priority.");
668                 return -rte_errno;
669         }
670
671         /* Not supported */
672         if (attr->group) {
673                 rte_flow_error_set(error, EINVAL,
674                                 RTE_FLOW_ERROR_TYPE_ATTR_GROUP,
675                                 attr, "Not support group.");
676                 return -rte_errno;
677         }
678
679         return 0;
680 }
681
682 static int
683 ixgbe_parse_ethertype_filter(struct rte_eth_dev *dev,
684                                  const struct rte_flow_attr *attr,
685                              const struct rte_flow_item pattern[],
686                              const struct rte_flow_action actions[],
687                              struct rte_eth_ethertype_filter *filter,
688                              struct rte_flow_error *error)
689 {
690         int ret;
691         struct ixgbe_hw *hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
692
693         MAC_TYPE_FILTER_SUP(hw->mac.type);
694
695         ret = cons_parse_ethertype_filter(attr, pattern,
696                                         actions, filter, error);
697
698         if (ret)
699                 return ret;
700
701         /* Ixgbe doesn't support MAC address. */
702         if (filter->flags & RTE_ETHTYPE_FLAGS_MAC) {
703                 memset(filter, 0, sizeof(struct rte_eth_ethertype_filter));
704                 rte_flow_error_set(error, EINVAL,
705                         RTE_FLOW_ERROR_TYPE_ITEM,
706                         NULL, "Not supported by ethertype filter");
707                 return -rte_errno;
708         }
709
710         if (filter->queue >= IXGBE_MAX_RX_QUEUE_NUM) {
711                 memset(filter, 0, sizeof(struct rte_eth_ethertype_filter));
712                 rte_flow_error_set(error, EINVAL,
713                         RTE_FLOW_ERROR_TYPE_ITEM,
714                         NULL, "queue index much too big");
715                 return -rte_errno;
716         }
717
718         if (filter->ether_type == ETHER_TYPE_IPv4 ||
719                 filter->ether_type == ETHER_TYPE_IPv6) {
720                 memset(filter, 0, sizeof(struct rte_eth_ethertype_filter));
721                 rte_flow_error_set(error, EINVAL,
722                         RTE_FLOW_ERROR_TYPE_ITEM,
723                         NULL, "IPv4/IPv6 not supported by ethertype filter");
724                 return -rte_errno;
725         }
726
727         if (filter->flags & RTE_ETHTYPE_FLAGS_MAC) {
728                 memset(filter, 0, sizeof(struct rte_eth_ethertype_filter));
729                 rte_flow_error_set(error, EINVAL,
730                         RTE_FLOW_ERROR_TYPE_ITEM,
731                         NULL, "mac compare is unsupported");
732                 return -rte_errno;
733         }
734
735         if (filter->flags & RTE_ETHTYPE_FLAGS_DROP) {
736                 memset(filter, 0, sizeof(struct rte_eth_ethertype_filter));
737                 rte_flow_error_set(error, EINVAL,
738                         RTE_FLOW_ERROR_TYPE_ITEM,
739                         NULL, "drop option is unsupported");
740                 return -rte_errno;
741         }
742
743         return 0;
744 }
745
746 /**
747  * Parse the rule to see if it is a TCP SYN rule.
748  * And get the TCP SYN filter info BTW.
749  * pattern:
750  * The first not void item must be ETH.
751  * The second not void item must be IPV4 or IPV6.
752  * The third not void item must be TCP.
753  * The next not void item must be END.
754  * action:
755  * The first not void action should be QUEUE.
756  * The next not void action should be END.
757  * pattern example:
758  * ITEM         Spec                    Mask
759  * ETH          NULL                    NULL
760  * IPV4/IPV6    NULL                    NULL
761  * TCP          tcp_flags       0x02    0xFF
762  * END
763  * other members in mask and spec should set to 0x00.
764  * item->last should be NULL.
765  */
766 static int
767 cons_parse_syn_filter(const struct rte_flow_attr *attr,
768                                 const struct rte_flow_item pattern[],
769                                 const struct rte_flow_action actions[],
770                                 struct rte_eth_syn_filter *filter,
771                                 struct rte_flow_error *error)
772 {
773         const struct rte_flow_item *item;
774         const struct rte_flow_action *act;
775         const struct rte_flow_item_tcp *tcp_spec;
776         const struct rte_flow_item_tcp *tcp_mask;
777         const struct rte_flow_action_queue *act_q;
778
779         if (!pattern) {
780                 rte_flow_error_set(error, EINVAL,
781                                 RTE_FLOW_ERROR_TYPE_ITEM_NUM,
782                                 NULL, "NULL pattern.");
783                 return -rte_errno;
784         }
785
786         if (!actions) {
787                 rte_flow_error_set(error, EINVAL,
788                                 RTE_FLOW_ERROR_TYPE_ACTION_NUM,
789                                 NULL, "NULL action.");
790                 return -rte_errno;
791         }
792
793         if (!attr) {
794                 rte_flow_error_set(error, EINVAL,
795                                    RTE_FLOW_ERROR_TYPE_ATTR,
796                                    NULL, "NULL attribute.");
797                 return -rte_errno;
798         }
799
800
801         /* the first not void item should be MAC or IPv4 or IPv6 or TCP */
802         item = next_no_void_pattern(pattern, NULL);
803         if (item->type != RTE_FLOW_ITEM_TYPE_ETH &&
804             item->type != RTE_FLOW_ITEM_TYPE_IPV4 &&
805             item->type != RTE_FLOW_ITEM_TYPE_IPV6 &&
806             item->type != RTE_FLOW_ITEM_TYPE_TCP) {
807                 rte_flow_error_set(error, EINVAL,
808                                 RTE_FLOW_ERROR_TYPE_ITEM,
809                                 item, "Not supported by syn filter");
810                 return -rte_errno;
811         }
812                 /*Not supported last point for range*/
813         if (item->last) {
814                 rte_flow_error_set(error, EINVAL,
815                         RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
816                         item, "Not supported last point for range");
817                 return -rte_errno;
818         }
819
820         /* Skip Ethernet */
821         if (item->type == RTE_FLOW_ITEM_TYPE_ETH) {
822                 /* if the item is MAC, the content should be NULL */
823                 if (item->spec || item->mask) {
824                         rte_flow_error_set(error, EINVAL,
825                                 RTE_FLOW_ERROR_TYPE_ITEM,
826                                 item, "Invalid SYN address mask");
827                         return -rte_errno;
828                 }
829
830                 /* check if the next not void item is IPv4 or IPv6 */
831                 item = next_no_void_pattern(pattern, item);
832                 if (item->type != RTE_FLOW_ITEM_TYPE_IPV4 &&
833                     item->type != RTE_FLOW_ITEM_TYPE_IPV6) {
834                         rte_flow_error_set(error, EINVAL,
835                                 RTE_FLOW_ERROR_TYPE_ITEM,
836                                 item, "Not supported by syn filter");
837                         return -rte_errno;
838                 }
839         }
840
841         /* Skip IP */
842         if (item->type == RTE_FLOW_ITEM_TYPE_IPV4 ||
843             item->type == RTE_FLOW_ITEM_TYPE_IPV6) {
844                 /* if the item is IP, the content should be NULL */
845                 if (item->spec || item->mask) {
846                         rte_flow_error_set(error, EINVAL,
847                                 RTE_FLOW_ERROR_TYPE_ITEM,
848                                 item, "Invalid SYN mask");
849                         return -rte_errno;
850                 }
851
852                 /* check if the next not void item is TCP */
853                 item = next_no_void_pattern(pattern, item);
854                 if (item->type != RTE_FLOW_ITEM_TYPE_TCP) {
855                         rte_flow_error_set(error, EINVAL,
856                                 RTE_FLOW_ERROR_TYPE_ITEM,
857                                 item, "Not supported by syn filter");
858                         return -rte_errno;
859                 }
860         }
861
862         /* Get the TCP info. Only support SYN. */
863         if (!item->spec || !item->mask) {
864                 rte_flow_error_set(error, EINVAL,
865                                 RTE_FLOW_ERROR_TYPE_ITEM,
866                                 item, "Invalid SYN mask");
867                 return -rte_errno;
868         }
869         /*Not supported last point for range*/
870         if (item->last) {
871                 rte_flow_error_set(error, EINVAL,
872                         RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
873                         item, "Not supported last point for range");
874                 return -rte_errno;
875         }
876
877         tcp_spec = (const struct rte_flow_item_tcp *)item->spec;
878         tcp_mask = (const struct rte_flow_item_tcp *)item->mask;
879         if (!(tcp_spec->hdr.tcp_flags & TCP_SYN_FLAG) ||
880             tcp_mask->hdr.src_port ||
881             tcp_mask->hdr.dst_port ||
882             tcp_mask->hdr.sent_seq ||
883             tcp_mask->hdr.recv_ack ||
884             tcp_mask->hdr.data_off ||
885             tcp_mask->hdr.tcp_flags != TCP_SYN_FLAG ||
886             tcp_mask->hdr.rx_win ||
887             tcp_mask->hdr.cksum ||
888             tcp_mask->hdr.tcp_urp) {
889                 memset(filter, 0, sizeof(struct rte_eth_syn_filter));
890                 rte_flow_error_set(error, EINVAL,
891                                 RTE_FLOW_ERROR_TYPE_ITEM,
892                                 item, "Not supported by syn filter");
893                 return -rte_errno;
894         }
895
896         /* check if the next not void item is END */
897         item = next_no_void_pattern(pattern, item);
898         if (item->type != RTE_FLOW_ITEM_TYPE_END) {
899                 memset(filter, 0, sizeof(struct rte_eth_syn_filter));
900                 rte_flow_error_set(error, EINVAL,
901                                 RTE_FLOW_ERROR_TYPE_ITEM,
902                                 item, "Not supported by syn filter");
903                 return -rte_errno;
904         }
905
906         /* check if the first not void action is QUEUE. */
907         act = next_no_void_action(actions, NULL);
908         if (act->type != RTE_FLOW_ACTION_TYPE_QUEUE) {
909                 memset(filter, 0, sizeof(struct rte_eth_syn_filter));
910                 rte_flow_error_set(error, EINVAL,
911                                 RTE_FLOW_ERROR_TYPE_ACTION,
912                                 act, "Not supported action.");
913                 return -rte_errno;
914         }
915
916         act_q = (const struct rte_flow_action_queue *)act->conf;
917         filter->queue = act_q->index;
918         if (filter->queue >= IXGBE_MAX_RX_QUEUE_NUM) {
919                 memset(filter, 0, sizeof(struct rte_eth_syn_filter));
920                 rte_flow_error_set(error, EINVAL,
921                                 RTE_FLOW_ERROR_TYPE_ACTION,
922                                 act, "Not supported action.");
923                 return -rte_errno;
924         }
925
926         /* check if the next not void item is END */
927         act = next_no_void_action(actions, act);
928         if (act->type != RTE_FLOW_ACTION_TYPE_END) {
929                 memset(filter, 0, sizeof(struct rte_eth_syn_filter));
930                 rte_flow_error_set(error, EINVAL,
931                                 RTE_FLOW_ERROR_TYPE_ACTION,
932                                 act, "Not supported action.");
933                 return -rte_errno;
934         }
935
936         /* parse attr */
937         /* must be input direction */
938         if (!attr->ingress) {
939                 memset(filter, 0, sizeof(struct rte_eth_syn_filter));
940                 rte_flow_error_set(error, EINVAL,
941                         RTE_FLOW_ERROR_TYPE_ATTR_INGRESS,
942                         attr, "Only support ingress.");
943                 return -rte_errno;
944         }
945
946         /* not supported */
947         if (attr->egress) {
948                 memset(filter, 0, sizeof(struct rte_eth_syn_filter));
949                 rte_flow_error_set(error, EINVAL,
950                         RTE_FLOW_ERROR_TYPE_ATTR_EGRESS,
951                         attr, "Not support egress.");
952                 return -rte_errno;
953         }
954
955         /* Support 2 priorities, the lowest or highest. */
956         if (!attr->priority) {
957                 filter->hig_pri = 0;
958         } else if (attr->priority == (uint32_t)~0U) {
959                 filter->hig_pri = 1;
960         } else {
961                 memset(filter, 0, sizeof(struct rte_eth_syn_filter));
962                 rte_flow_error_set(error, EINVAL,
963                         RTE_FLOW_ERROR_TYPE_ATTR_PRIORITY,
964                         attr, "Not support priority.");
965                 return -rte_errno;
966         }
967
968         return 0;
969 }
970
971 static int
972 ixgbe_parse_syn_filter(struct rte_eth_dev *dev,
973                                  const struct rte_flow_attr *attr,
974                              const struct rte_flow_item pattern[],
975                              const struct rte_flow_action actions[],
976                              struct rte_eth_syn_filter *filter,
977                              struct rte_flow_error *error)
978 {
979         int ret;
980         struct ixgbe_hw *hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
981
982         MAC_TYPE_FILTER_SUP(hw->mac.type);
983
984         ret = cons_parse_syn_filter(attr, pattern,
985                                         actions, filter, error);
986
987         if (ret)
988                 return ret;
989
990         return 0;
991 }
992
993 /**
994  * Parse the rule to see if it is a L2 tunnel rule.
995  * And get the L2 tunnel filter info BTW.
996  * Only support E-tag now.
997  * pattern:
998  * The first not void item can be E_TAG.
999  * The next not void item must be END.
1000  * action:
1001  * The first not void action should be QUEUE.
1002  * The next not void action should be END.
1003  * pattern example:
1004  * ITEM         Spec                    Mask
1005  * E_TAG        grp             0x1     0x3
1006                 e_cid_base      0x309   0xFFF
1007  * END
1008  * other members in mask and spec should set to 0x00.
1009  * item->last should be NULL.
1010  */
1011 static int
1012 cons_parse_l2_tn_filter(const struct rte_flow_attr *attr,
1013                         const struct rte_flow_item pattern[],
1014                         const struct rte_flow_action actions[],
1015                         struct rte_eth_l2_tunnel_conf *filter,
1016                         struct rte_flow_error *error)
1017 {
1018         const struct rte_flow_item *item;
1019         const struct rte_flow_item_e_tag *e_tag_spec;
1020         const struct rte_flow_item_e_tag *e_tag_mask;
1021         const struct rte_flow_action *act;
1022         const struct rte_flow_action_queue *act_q;
1023
1024         if (!pattern) {
1025                 rte_flow_error_set(error, EINVAL,
1026                         RTE_FLOW_ERROR_TYPE_ITEM_NUM,
1027                         NULL, "NULL pattern.");
1028                 return -rte_errno;
1029         }
1030
1031         if (!actions) {
1032                 rte_flow_error_set(error, EINVAL,
1033                                    RTE_FLOW_ERROR_TYPE_ACTION_NUM,
1034                                    NULL, "NULL action.");
1035                 return -rte_errno;
1036         }
1037
1038         if (!attr) {
1039                 rte_flow_error_set(error, EINVAL,
1040                                    RTE_FLOW_ERROR_TYPE_ATTR,
1041                                    NULL, "NULL attribute.");
1042                 return -rte_errno;
1043         }
1044
1045         /* The first not void item should be e-tag. */
1046         item = next_no_void_pattern(pattern, NULL);
1047         if (item->type != RTE_FLOW_ITEM_TYPE_E_TAG) {
1048                 memset(filter, 0, sizeof(struct rte_eth_l2_tunnel_conf));
1049                 rte_flow_error_set(error, EINVAL,
1050                         RTE_FLOW_ERROR_TYPE_ITEM,
1051                         item, "Not supported by L2 tunnel filter");
1052                 return -rte_errno;
1053         }
1054
1055         if (!item->spec || !item->mask) {
1056                 memset(filter, 0, sizeof(struct rte_eth_l2_tunnel_conf));
1057                 rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_ITEM,
1058                         item, "Not supported by L2 tunnel filter");
1059                 return -rte_errno;
1060         }
1061
1062         /*Not supported last point for range*/
1063         if (item->last) {
1064                 rte_flow_error_set(error, EINVAL,
1065                         RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
1066                         item, "Not supported last point for range");
1067                 return -rte_errno;
1068         }
1069
1070         e_tag_spec = (const struct rte_flow_item_e_tag *)item->spec;
1071         e_tag_mask = (const struct rte_flow_item_e_tag *)item->mask;
1072
1073         /* Only care about GRP and E cid base. */
1074         if (e_tag_mask->epcp_edei_in_ecid_b ||
1075             e_tag_mask->in_ecid_e ||
1076             e_tag_mask->ecid_e ||
1077             e_tag_mask->rsvd_grp_ecid_b != rte_cpu_to_be_16(0x3FFF)) {
1078                 memset(filter, 0, sizeof(struct rte_eth_l2_tunnel_conf));
1079                 rte_flow_error_set(error, EINVAL,
1080                         RTE_FLOW_ERROR_TYPE_ITEM,
1081                         item, "Not supported by L2 tunnel filter");
1082                 return -rte_errno;
1083         }
1084
1085         filter->l2_tunnel_type = RTE_L2_TUNNEL_TYPE_E_TAG;
1086         /**
1087          * grp and e_cid_base are bit fields and only use 14 bits.
1088          * e-tag id is taken as little endian by HW.
1089          */
1090         filter->tunnel_id = rte_be_to_cpu_16(e_tag_spec->rsvd_grp_ecid_b);
1091
1092         /* check if the next not void item is END */
1093         item = next_no_void_pattern(pattern, item);
1094         if (item->type != RTE_FLOW_ITEM_TYPE_END) {
1095                 memset(filter, 0, sizeof(struct rte_eth_l2_tunnel_conf));
1096                 rte_flow_error_set(error, EINVAL,
1097                         RTE_FLOW_ERROR_TYPE_ITEM,
1098                         item, "Not supported by L2 tunnel filter");
1099                 return -rte_errno;
1100         }
1101
1102         /* parse attr */
1103         /* must be input direction */
1104         if (!attr->ingress) {
1105                 memset(filter, 0, sizeof(struct rte_eth_l2_tunnel_conf));
1106                 rte_flow_error_set(error, EINVAL,
1107                         RTE_FLOW_ERROR_TYPE_ATTR_INGRESS,
1108                         attr, "Only support ingress.");
1109                 return -rte_errno;
1110         }
1111
1112         /* not supported */
1113         if (attr->egress) {
1114                 memset(filter, 0, sizeof(struct rte_eth_l2_tunnel_conf));
1115                 rte_flow_error_set(error, EINVAL,
1116                         RTE_FLOW_ERROR_TYPE_ATTR_EGRESS,
1117                         attr, "Not support egress.");
1118                 return -rte_errno;
1119         }
1120
1121         /* not supported */
1122         if (attr->priority) {
1123                 memset(filter, 0, sizeof(struct rte_eth_l2_tunnel_conf));
1124                 rte_flow_error_set(error, EINVAL,
1125                         RTE_FLOW_ERROR_TYPE_ATTR_PRIORITY,
1126                         attr, "Not support priority.");
1127                 return -rte_errno;
1128         }
1129
1130         /* check if the first not void action is QUEUE. */
1131         act = next_no_void_action(actions, NULL);
1132         if (act->type != RTE_FLOW_ACTION_TYPE_QUEUE) {
1133                 memset(filter, 0, sizeof(struct rte_eth_l2_tunnel_conf));
1134                 rte_flow_error_set(error, EINVAL,
1135                         RTE_FLOW_ERROR_TYPE_ACTION,
1136                         act, "Not supported action.");
1137                 return -rte_errno;
1138         }
1139
1140         act_q = (const struct rte_flow_action_queue *)act->conf;
1141         filter->pool = act_q->index;
1142
1143         /* check if the next not void item is END */
1144         act = next_no_void_action(actions, act);
1145         if (act->type != RTE_FLOW_ACTION_TYPE_END) {
1146                 memset(filter, 0, sizeof(struct rte_eth_l2_tunnel_conf));
1147                 rte_flow_error_set(error, EINVAL,
1148                         RTE_FLOW_ERROR_TYPE_ACTION,
1149                         act, "Not supported action.");
1150                 return -rte_errno;
1151         }
1152
1153         return 0;
1154 }
1155
1156 static int
1157 ixgbe_parse_l2_tn_filter(struct rte_eth_dev *dev,
1158                         const struct rte_flow_attr *attr,
1159                         const struct rte_flow_item pattern[],
1160                         const struct rte_flow_action actions[],
1161                         struct rte_eth_l2_tunnel_conf *l2_tn_filter,
1162                         struct rte_flow_error *error)
1163 {
1164         int ret = 0;
1165         struct ixgbe_hw *hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
1166
1167         ret = cons_parse_l2_tn_filter(attr, pattern,
1168                                 actions, l2_tn_filter, error);
1169
1170         if (hw->mac.type != ixgbe_mac_X550 &&
1171                 hw->mac.type != ixgbe_mac_X550EM_x &&
1172                 hw->mac.type != ixgbe_mac_X550EM_a) {
1173                 memset(l2_tn_filter, 0, sizeof(struct rte_eth_l2_tunnel_conf));
1174                 rte_flow_error_set(error, EINVAL,
1175                         RTE_FLOW_ERROR_TYPE_ITEM,
1176                         NULL, "Not supported by L2 tunnel filter");
1177                 return -rte_errno;
1178         }
1179
1180         return ret;
1181 }
1182
1183 /* Parse to get the attr and action info of flow director rule. */
1184 static int
1185 ixgbe_parse_fdir_act_attr(const struct rte_flow_attr *attr,
1186                           const struct rte_flow_action actions[],
1187                           struct ixgbe_fdir_rule *rule,
1188                           struct rte_flow_error *error)
1189 {
1190         const struct rte_flow_action *act;
1191         const struct rte_flow_action_queue *act_q;
1192         const struct rte_flow_action_mark *mark;
1193
1194         /* parse attr */
1195         /* must be input direction */
1196         if (!attr->ingress) {
1197                 memset(rule, 0, sizeof(struct ixgbe_fdir_rule));
1198                 rte_flow_error_set(error, EINVAL,
1199                         RTE_FLOW_ERROR_TYPE_ATTR_INGRESS,
1200                         attr, "Only support ingress.");
1201                 return -rte_errno;
1202         }
1203
1204         /* not supported */
1205         if (attr->egress) {
1206                 memset(rule, 0, sizeof(struct ixgbe_fdir_rule));
1207                 rte_flow_error_set(error, EINVAL,
1208                         RTE_FLOW_ERROR_TYPE_ATTR_EGRESS,
1209                         attr, "Not support egress.");
1210                 return -rte_errno;
1211         }
1212
1213         /* not supported */
1214         if (attr->priority) {
1215                 memset(rule, 0, sizeof(struct ixgbe_fdir_rule));
1216                 rte_flow_error_set(error, EINVAL,
1217                         RTE_FLOW_ERROR_TYPE_ATTR_PRIORITY,
1218                         attr, "Not support priority.");
1219                 return -rte_errno;
1220         }
1221
1222         /* check if the first not void action is QUEUE or DROP. */
1223         act = next_no_void_action(actions, NULL);
1224         if (act->type != RTE_FLOW_ACTION_TYPE_QUEUE &&
1225             act->type != RTE_FLOW_ACTION_TYPE_DROP) {
1226                 memset(rule, 0, sizeof(struct ixgbe_fdir_rule));
1227                 rte_flow_error_set(error, EINVAL,
1228                         RTE_FLOW_ERROR_TYPE_ACTION,
1229                         act, "Not supported action.");
1230                 return -rte_errno;
1231         }
1232
1233         if (act->type == RTE_FLOW_ACTION_TYPE_QUEUE) {
1234                 act_q = (const struct rte_flow_action_queue *)act->conf;
1235                 rule->queue = act_q->index;
1236         } else { /* drop */
1237                 rule->fdirflags = IXGBE_FDIRCMD_DROP;
1238         }
1239
1240         /* check if the next not void item is MARK */
1241         act = next_no_void_action(actions, act);
1242         if ((act->type != RTE_FLOW_ACTION_TYPE_MARK) &&
1243                 (act->type != RTE_FLOW_ACTION_TYPE_END)) {
1244                 memset(rule, 0, sizeof(struct ixgbe_fdir_rule));
1245                 rte_flow_error_set(error, EINVAL,
1246                         RTE_FLOW_ERROR_TYPE_ACTION,
1247                         act, "Not supported action.");
1248                 return -rte_errno;
1249         }
1250
1251         rule->soft_id = 0;
1252
1253         if (act->type == RTE_FLOW_ACTION_TYPE_MARK) {
1254                 mark = (const struct rte_flow_action_mark *)act->conf;
1255                 rule->soft_id = mark->id;
1256                 act = next_no_void_action(actions, act);
1257         }
1258
1259         /* check if the next not void item is END */
1260         if (act->type != RTE_FLOW_ACTION_TYPE_END) {
1261                 memset(rule, 0, sizeof(struct ixgbe_fdir_rule));
1262                 rte_flow_error_set(error, EINVAL,
1263                         RTE_FLOW_ERROR_TYPE_ACTION,
1264                         act, "Not supported action.");
1265                 return -rte_errno;
1266         }
1267
1268         return 0;
1269 }
1270
1271 /**
1272  * Parse the rule to see if it is a IP or MAC VLAN flow director rule.
1273  * And get the flow director filter info BTW.
1274  * UDP/TCP/SCTP PATTERN:
1275  * The first not void item can be ETH or IPV4.
1276  * The second not void item must be IPV4 if the first one is ETH.
1277  * The next not void item could be UDP or TCP or SCTP (optional)
1278  * The next not void item could be RAW (for flexbyte, optional)
1279  * The next not void item must be END.
1280  * MAC VLAN PATTERN:
1281  * The first not void item must be ETH.
1282  * The second not void item must be MAC VLAN.
1283  * The next not void item must be END.
1284  * ACTION:
1285  * The first not void action should be QUEUE or DROP.
1286  * The second not void optional action should be MARK,
1287  * mark_id is a uint32_t number.
1288  * The next not void action should be END.
1289  * UDP/TCP/SCTP pattern example:
1290  * ITEM         Spec                    Mask
1291  * ETH          NULL                    NULL
1292  * IPV4         src_addr 192.168.1.20   0xFFFFFFFF
1293  *              dst_addr 192.167.3.50   0xFFFFFFFF
1294  * UDP/TCP/SCTP src_port        80      0xFFFF
1295  *              dst_port        80      0xFFFF
1296  * FLEX relative        0       0x1
1297  *              search          0       0x1
1298  *              reserved        0       0
1299  *              offset          12      0xFFFFFFFF
1300  *              limit           0       0xFFFF
1301  *              length          2       0xFFFF
1302  *              pattern[0]      0x86    0xFF
1303  *              pattern[1]      0xDD    0xFF
1304  * END
1305  * MAC VLAN pattern example:
1306  * ITEM         Spec                    Mask
1307  * ETH          dst_addr
1308                 {0xAC, 0x7B, 0xA1,      {0xFF, 0xFF, 0xFF,
1309                 0x2C, 0x6D, 0x36}       0xFF, 0xFF, 0xFF}
1310  * MAC VLAN     tci     0x2016          0xEFFF
1311  * END
1312  * Other members in mask and spec should set to 0x00.
1313  * Item->last should be NULL.
1314  */
1315 static int
1316 ixgbe_parse_fdir_filter_normal(const struct rte_flow_attr *attr,
1317                                const struct rte_flow_item pattern[],
1318                                const struct rte_flow_action actions[],
1319                                struct ixgbe_fdir_rule *rule,
1320                                struct rte_flow_error *error)
1321 {
1322         const struct rte_flow_item *item;
1323         const struct rte_flow_item_eth *eth_spec;
1324         const struct rte_flow_item_eth *eth_mask;
1325         const struct rte_flow_item_ipv4 *ipv4_spec;
1326         const struct rte_flow_item_ipv4 *ipv4_mask;
1327         const struct rte_flow_item_tcp *tcp_spec;
1328         const struct rte_flow_item_tcp *tcp_mask;
1329         const struct rte_flow_item_udp *udp_spec;
1330         const struct rte_flow_item_udp *udp_mask;
1331         const struct rte_flow_item_sctp *sctp_spec;
1332         const struct rte_flow_item_sctp *sctp_mask;
1333         const struct rte_flow_item_vlan *vlan_spec;
1334         const struct rte_flow_item_vlan *vlan_mask;
1335         const struct rte_flow_item_raw *raw_mask;
1336         const struct rte_flow_item_raw *raw_spec;
1337
1338         uint32_t j;
1339
1340         if (!pattern) {
1341                 rte_flow_error_set(error, EINVAL,
1342                         RTE_FLOW_ERROR_TYPE_ITEM_NUM,
1343                         NULL, "NULL pattern.");
1344                 return -rte_errno;
1345         }
1346
1347         if (!actions) {
1348                 rte_flow_error_set(error, EINVAL,
1349                                    RTE_FLOW_ERROR_TYPE_ACTION_NUM,
1350                                    NULL, "NULL action.");
1351                 return -rte_errno;
1352         }
1353
1354         if (!attr) {
1355                 rte_flow_error_set(error, EINVAL,
1356                                    RTE_FLOW_ERROR_TYPE_ATTR,
1357                                    NULL, "NULL attribute.");
1358                 return -rte_errno;
1359         }
1360
1361         /**
1362          * Some fields may not be provided. Set spec to 0 and mask to default
1363          * value. So, we need not do anything for the not provided fields later.
1364          */
1365         memset(rule, 0, sizeof(struct ixgbe_fdir_rule));
1366         memset(&rule->mask, 0xFF, sizeof(struct ixgbe_hw_fdir_mask));
1367         rule->mask.vlan_tci_mask = 0;
1368         rule->mask.flex_bytes_mask = 0;
1369
1370         /**
1371          * The first not void item should be
1372          * MAC or IPv4 or TCP or UDP or SCTP.
1373          */
1374         item = next_no_void_pattern(pattern, NULL);
1375         if (item->type != RTE_FLOW_ITEM_TYPE_ETH &&
1376             item->type != RTE_FLOW_ITEM_TYPE_IPV4 &&
1377             item->type != RTE_FLOW_ITEM_TYPE_TCP &&
1378             item->type != RTE_FLOW_ITEM_TYPE_UDP &&
1379             item->type != RTE_FLOW_ITEM_TYPE_SCTP) {
1380                 memset(rule, 0, sizeof(struct ixgbe_fdir_rule));
1381                 rte_flow_error_set(error, EINVAL,
1382                         RTE_FLOW_ERROR_TYPE_ITEM,
1383                         item, "Not supported by fdir filter");
1384                 return -rte_errno;
1385         }
1386
1387         rule->mode = RTE_FDIR_MODE_PERFECT;
1388
1389         /*Not supported last point for range*/
1390         if (item->last) {
1391                 rte_flow_error_set(error, EINVAL,
1392                         RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
1393                         item, "Not supported last point for range");
1394                 return -rte_errno;
1395         }
1396
1397         /* Get the MAC info. */
1398         if (item->type == RTE_FLOW_ITEM_TYPE_ETH) {
1399                 /**
1400                  * Only support vlan and dst MAC address,
1401                  * others should be masked.
1402                  */
1403                 if (item->spec && !item->mask) {
1404                         memset(rule, 0, sizeof(struct ixgbe_fdir_rule));
1405                         rte_flow_error_set(error, EINVAL,
1406                                 RTE_FLOW_ERROR_TYPE_ITEM,
1407                                 item, "Not supported by fdir filter");
1408                         return -rte_errno;
1409                 }
1410
1411                 if (item->spec) {
1412                         rule->b_spec = TRUE;
1413                         eth_spec = (const struct rte_flow_item_eth *)item->spec;
1414
1415                         /* Get the dst MAC. */
1416                         for (j = 0; j < ETHER_ADDR_LEN; j++) {
1417                                 rule->ixgbe_fdir.formatted.inner_mac[j] =
1418                                         eth_spec->dst.addr_bytes[j];
1419                         }
1420                 }
1421
1422
1423                 if (item->mask) {
1424                         /* If ethernet has meaning, it means MAC VLAN mode. */
1425                         rule->mode = RTE_FDIR_MODE_PERFECT_MAC_VLAN;
1426
1427                         rule->b_mask = TRUE;
1428                         eth_mask = (const struct rte_flow_item_eth *)item->mask;
1429
1430                         /* Ether type should be masked. */
1431                         if (eth_mask->type) {
1432                                 memset(rule, 0, sizeof(struct ixgbe_fdir_rule));
1433                                 rte_flow_error_set(error, EINVAL,
1434                                         RTE_FLOW_ERROR_TYPE_ITEM,
1435                                         item, "Not supported by fdir filter");
1436                                 return -rte_errno;
1437                         }
1438
1439                         /**
1440                          * src MAC address must be masked,
1441                          * and don't support dst MAC address mask.
1442                          */
1443                         for (j = 0; j < ETHER_ADDR_LEN; j++) {
1444                                 if (eth_mask->src.addr_bytes[j] ||
1445                                         eth_mask->dst.addr_bytes[j] != 0xFF) {
1446                                         memset(rule, 0,
1447                                         sizeof(struct ixgbe_fdir_rule));
1448                                         rte_flow_error_set(error, EINVAL,
1449                                         RTE_FLOW_ERROR_TYPE_ITEM,
1450                                         item, "Not supported by fdir filter");
1451                                         return -rte_errno;
1452                                 }
1453                         }
1454
1455                         /* When no VLAN, considered as full mask. */
1456                         rule->mask.vlan_tci_mask = rte_cpu_to_be_16(0xEFFF);
1457                 }
1458                 /*** If both spec and mask are item,
1459                  * it means don't care about ETH.
1460                  * Do nothing.
1461                  */
1462
1463                 /**
1464                  * Check if the next not void item is vlan or ipv4.
1465                  * IPv6 is not supported.
1466                  */
1467                 item = next_no_void_pattern(pattern, item);
1468                 if (rule->mode == RTE_FDIR_MODE_PERFECT_MAC_VLAN) {
1469                         if (item->type != RTE_FLOW_ITEM_TYPE_VLAN) {
1470                                 memset(rule, 0, sizeof(struct ixgbe_fdir_rule));
1471                                 rte_flow_error_set(error, EINVAL,
1472                                         RTE_FLOW_ERROR_TYPE_ITEM,
1473                                         item, "Not supported by fdir filter");
1474                                 return -rte_errno;
1475                         }
1476                 } else {
1477                         if (item->type != RTE_FLOW_ITEM_TYPE_IPV4) {
1478                                 memset(rule, 0, sizeof(struct ixgbe_fdir_rule));
1479                                 rte_flow_error_set(error, EINVAL,
1480                                         RTE_FLOW_ERROR_TYPE_ITEM,
1481                                         item, "Not supported by fdir filter");
1482                                 return -rte_errno;
1483                         }
1484                 }
1485         }
1486
1487         if (item->type == RTE_FLOW_ITEM_TYPE_VLAN) {
1488                 if (!(item->spec && item->mask)) {
1489                         memset(rule, 0, sizeof(struct ixgbe_fdir_rule));
1490                         rte_flow_error_set(error, EINVAL,
1491                                 RTE_FLOW_ERROR_TYPE_ITEM,
1492                                 item, "Not supported by fdir filter");
1493                         return -rte_errno;
1494                 }
1495
1496                 /*Not supported last point for range*/
1497                 if (item->last) {
1498                         rte_flow_error_set(error, EINVAL,
1499                                 RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
1500                                 item, "Not supported last point for range");
1501                         return -rte_errno;
1502                 }
1503
1504                 vlan_spec = (const struct rte_flow_item_vlan *)item->spec;
1505                 vlan_mask = (const struct rte_flow_item_vlan *)item->mask;
1506
1507                 rule->ixgbe_fdir.formatted.vlan_id = vlan_spec->tci;
1508
1509                 rule->mask.vlan_tci_mask = vlan_mask->tci;
1510                 rule->mask.vlan_tci_mask &= rte_cpu_to_be_16(0xEFFF);
1511                 /* More than one tags are not supported. */
1512
1513                 /* Next not void item must be END */
1514                 item = next_no_void_pattern(pattern, item);
1515                 if (item->type != RTE_FLOW_ITEM_TYPE_END) {
1516                         memset(rule, 0, sizeof(struct ixgbe_fdir_rule));
1517                         rte_flow_error_set(error, EINVAL,
1518                                 RTE_FLOW_ERROR_TYPE_ITEM,
1519                                 item, "Not supported by fdir filter");
1520                         return -rte_errno;
1521                 }
1522         }
1523
1524         /* Get the IP info. */
1525         if (item->type == RTE_FLOW_ITEM_TYPE_IPV4) {
1526                 /**
1527                  * Set the flow type even if there's no content
1528                  * as we must have a flow type.
1529                  */
1530                 rule->ixgbe_fdir.formatted.flow_type =
1531                         IXGBE_ATR_FLOW_TYPE_IPV4;
1532                 /*Not supported last point for range*/
1533                 if (item->last) {
1534                         rte_flow_error_set(error, EINVAL,
1535                                 RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
1536                                 item, "Not supported last point for range");
1537                         return -rte_errno;
1538                 }
1539                 /**
1540                  * Only care about src & dst addresses,
1541                  * others should be masked.
1542                  */
1543                 if (!item->mask) {
1544                         memset(rule, 0, sizeof(struct ixgbe_fdir_rule));
1545                         rte_flow_error_set(error, EINVAL,
1546                                 RTE_FLOW_ERROR_TYPE_ITEM,
1547                                 item, "Not supported by fdir filter");
1548                         return -rte_errno;
1549                 }
1550                 rule->b_mask = TRUE;
1551                 ipv4_mask =
1552                         (const struct rte_flow_item_ipv4 *)item->mask;
1553                 if (ipv4_mask->hdr.version_ihl ||
1554                     ipv4_mask->hdr.type_of_service ||
1555                     ipv4_mask->hdr.total_length ||
1556                     ipv4_mask->hdr.packet_id ||
1557                     ipv4_mask->hdr.fragment_offset ||
1558                     ipv4_mask->hdr.time_to_live ||
1559                     ipv4_mask->hdr.next_proto_id ||
1560                     ipv4_mask->hdr.hdr_checksum) {
1561                         memset(rule, 0, sizeof(struct ixgbe_fdir_rule));
1562                         rte_flow_error_set(error, EINVAL,
1563                                 RTE_FLOW_ERROR_TYPE_ITEM,
1564                                 item, "Not supported by fdir filter");
1565                         return -rte_errno;
1566                 }
1567                 rule->mask.dst_ipv4_mask = ipv4_mask->hdr.dst_addr;
1568                 rule->mask.src_ipv4_mask = ipv4_mask->hdr.src_addr;
1569
1570                 if (item->spec) {
1571                         rule->b_spec = TRUE;
1572                         ipv4_spec =
1573                                 (const struct rte_flow_item_ipv4 *)item->spec;
1574                         rule->ixgbe_fdir.formatted.dst_ip[0] =
1575                                 ipv4_spec->hdr.dst_addr;
1576                         rule->ixgbe_fdir.formatted.src_ip[0] =
1577                                 ipv4_spec->hdr.src_addr;
1578                 }
1579
1580                 /**
1581                  * Check if the next not void item is
1582                  * TCP or UDP or SCTP or END.
1583                  */
1584                 item = next_no_void_pattern(pattern, item);
1585                 if (item->type != RTE_FLOW_ITEM_TYPE_TCP &&
1586                     item->type != RTE_FLOW_ITEM_TYPE_UDP &&
1587                     item->type != RTE_FLOW_ITEM_TYPE_SCTP &&
1588                     item->type != RTE_FLOW_ITEM_TYPE_END &&
1589                     item->type != RTE_FLOW_ITEM_TYPE_RAW) {
1590                         memset(rule, 0, sizeof(struct ixgbe_fdir_rule));
1591                         rte_flow_error_set(error, EINVAL,
1592                                 RTE_FLOW_ERROR_TYPE_ITEM,
1593                                 item, "Not supported by fdir filter");
1594                         return -rte_errno;
1595                 }
1596         }
1597
1598         /* Get the TCP info. */
1599         if (item->type == RTE_FLOW_ITEM_TYPE_TCP) {
1600                 /**
1601                  * Set the flow type even if there's no content
1602                  * as we must have a flow type.
1603                  */
1604                 rule->ixgbe_fdir.formatted.flow_type =
1605                         IXGBE_ATR_FLOW_TYPE_TCPV4;
1606                 /*Not supported last point for range*/
1607                 if (item->last) {
1608                         rte_flow_error_set(error, EINVAL,
1609                                 RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
1610                                 item, "Not supported last point for range");
1611                         return -rte_errno;
1612                 }
1613                 /**
1614                  * Only care about src & dst ports,
1615                  * others should be masked.
1616                  */
1617                 if (!item->mask) {
1618                         memset(rule, 0, sizeof(struct ixgbe_fdir_rule));
1619                         rte_flow_error_set(error, EINVAL,
1620                                 RTE_FLOW_ERROR_TYPE_ITEM,
1621                                 item, "Not supported by fdir filter");
1622                         return -rte_errno;
1623                 }
1624                 rule->b_mask = TRUE;
1625                 tcp_mask = (const struct rte_flow_item_tcp *)item->mask;
1626                 if (tcp_mask->hdr.sent_seq ||
1627                     tcp_mask->hdr.recv_ack ||
1628                     tcp_mask->hdr.data_off ||
1629                     tcp_mask->hdr.tcp_flags ||
1630                     tcp_mask->hdr.rx_win ||
1631                     tcp_mask->hdr.cksum ||
1632                     tcp_mask->hdr.tcp_urp) {
1633                         memset(rule, 0, sizeof(struct ixgbe_fdir_rule));
1634                         rte_flow_error_set(error, EINVAL,
1635                                 RTE_FLOW_ERROR_TYPE_ITEM,
1636                                 item, "Not supported by fdir filter");
1637                         return -rte_errno;
1638                 }
1639                 rule->mask.src_port_mask = tcp_mask->hdr.src_port;
1640                 rule->mask.dst_port_mask = tcp_mask->hdr.dst_port;
1641
1642                 if (item->spec) {
1643                         rule->b_spec = TRUE;
1644                         tcp_spec = (const struct rte_flow_item_tcp *)item->spec;
1645                         rule->ixgbe_fdir.formatted.src_port =
1646                                 tcp_spec->hdr.src_port;
1647                         rule->ixgbe_fdir.formatted.dst_port =
1648                                 tcp_spec->hdr.dst_port;
1649                 }
1650
1651                 item = next_no_void_pattern(pattern, item);
1652                 if (item->type != RTE_FLOW_ITEM_TYPE_RAW &&
1653                     item->type != RTE_FLOW_ITEM_TYPE_END) {
1654                         memset(rule, 0, sizeof(struct ixgbe_fdir_rule));
1655                         rte_flow_error_set(error, EINVAL,
1656                                 RTE_FLOW_ERROR_TYPE_ITEM,
1657                                 item, "Not supported by fdir filter");
1658                         return -rte_errno;
1659                 }
1660
1661         }
1662
1663         /* Get the UDP info */
1664         if (item->type == RTE_FLOW_ITEM_TYPE_UDP) {
1665                 /**
1666                  * Set the flow type even if there's no content
1667                  * as we must have a flow type.
1668                  */
1669                 rule->ixgbe_fdir.formatted.flow_type =
1670                         IXGBE_ATR_FLOW_TYPE_UDPV4;
1671                 /*Not supported last point for range*/
1672                 if (item->last) {
1673                         rte_flow_error_set(error, EINVAL,
1674                                 RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
1675                                 item, "Not supported last point for range");
1676                         return -rte_errno;
1677                 }
1678                 /**
1679                  * Only care about src & dst ports,
1680                  * others should be masked.
1681                  */
1682                 if (!item->mask) {
1683                         memset(rule, 0, sizeof(struct ixgbe_fdir_rule));
1684                         rte_flow_error_set(error, EINVAL,
1685                                 RTE_FLOW_ERROR_TYPE_ITEM,
1686                                 item, "Not supported by fdir filter");
1687                         return -rte_errno;
1688                 }
1689                 rule->b_mask = TRUE;
1690                 udp_mask = (const struct rte_flow_item_udp *)item->mask;
1691                 if (udp_mask->hdr.dgram_len ||
1692                     udp_mask->hdr.dgram_cksum) {
1693                         memset(rule, 0, sizeof(struct ixgbe_fdir_rule));
1694                         rte_flow_error_set(error, EINVAL,
1695                                 RTE_FLOW_ERROR_TYPE_ITEM,
1696                                 item, "Not supported by fdir filter");
1697                         return -rte_errno;
1698                 }
1699                 rule->mask.src_port_mask = udp_mask->hdr.src_port;
1700                 rule->mask.dst_port_mask = udp_mask->hdr.dst_port;
1701
1702                 if (item->spec) {
1703                         rule->b_spec = TRUE;
1704                         udp_spec = (const struct rte_flow_item_udp *)item->spec;
1705                         rule->ixgbe_fdir.formatted.src_port =
1706                                 udp_spec->hdr.src_port;
1707                         rule->ixgbe_fdir.formatted.dst_port =
1708                                 udp_spec->hdr.dst_port;
1709                 }
1710
1711                 item = next_no_void_pattern(pattern, item);
1712                 if (item->type != RTE_FLOW_ITEM_TYPE_RAW &&
1713                     item->type != RTE_FLOW_ITEM_TYPE_END) {
1714                         memset(rule, 0, sizeof(struct ixgbe_fdir_rule));
1715                         rte_flow_error_set(error, EINVAL,
1716                                 RTE_FLOW_ERROR_TYPE_ITEM,
1717                                 item, "Not supported by fdir filter");
1718                         return -rte_errno;
1719                 }
1720
1721         }
1722
1723         /* Get the SCTP info */
1724         if (item->type == RTE_FLOW_ITEM_TYPE_SCTP) {
1725                 /**
1726                  * Set the flow type even if there's no content
1727                  * as we must have a flow type.
1728                  */
1729                 rule->ixgbe_fdir.formatted.flow_type =
1730                         IXGBE_ATR_FLOW_TYPE_SCTPV4;
1731                 /*Not supported last point for range*/
1732                 if (item->last) {
1733                         rte_flow_error_set(error, EINVAL,
1734                                 RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
1735                                 item, "Not supported last point for range");
1736                         return -rte_errno;
1737                 }
1738                 /**
1739                  * Only care about src & dst ports,
1740                  * others should be masked.
1741                  */
1742                 if (!item->mask) {
1743                         memset(rule, 0, sizeof(struct ixgbe_fdir_rule));
1744                         rte_flow_error_set(error, EINVAL,
1745                                 RTE_FLOW_ERROR_TYPE_ITEM,
1746                                 item, "Not supported by fdir filter");
1747                         return -rte_errno;
1748                 }
1749                 rule->b_mask = TRUE;
1750                 sctp_mask =
1751                         (const struct rte_flow_item_sctp *)item->mask;
1752                 if (sctp_mask->hdr.tag ||
1753                     sctp_mask->hdr.cksum) {
1754                         memset(rule, 0, sizeof(struct ixgbe_fdir_rule));
1755                         rte_flow_error_set(error, EINVAL,
1756                                 RTE_FLOW_ERROR_TYPE_ITEM,
1757                                 item, "Not supported by fdir filter");
1758                         return -rte_errno;
1759                 }
1760                 rule->mask.src_port_mask = sctp_mask->hdr.src_port;
1761                 rule->mask.dst_port_mask = sctp_mask->hdr.dst_port;
1762
1763                 if (item->spec) {
1764                         rule->b_spec = TRUE;
1765                         sctp_spec =
1766                                 (const struct rte_flow_item_sctp *)item->spec;
1767                         rule->ixgbe_fdir.formatted.src_port =
1768                                 sctp_spec->hdr.src_port;
1769                         rule->ixgbe_fdir.formatted.dst_port =
1770                                 sctp_spec->hdr.dst_port;
1771                 }
1772
1773                 item = next_no_void_pattern(pattern, item);
1774                 if (item->type != RTE_FLOW_ITEM_TYPE_RAW &&
1775                     item->type != RTE_FLOW_ITEM_TYPE_END) {
1776                         memset(rule, 0, sizeof(struct ixgbe_fdir_rule));
1777                         rte_flow_error_set(error, EINVAL,
1778                                 RTE_FLOW_ERROR_TYPE_ITEM,
1779                                 item, "Not supported by fdir filter");
1780                         return -rte_errno;
1781                 }
1782         }
1783
1784         /* Get the flex byte info */
1785         if (item->type == RTE_FLOW_ITEM_TYPE_RAW) {
1786                 /* Not supported last point for range*/
1787                 if (item->last) {
1788                         rte_flow_error_set(error, EINVAL,
1789                                 RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
1790                                 item, "Not supported last point for range");
1791                         return -rte_errno;
1792                 }
1793                 /* mask should not be null */
1794                 if (!item->mask || !item->spec) {
1795                         memset(rule, 0, sizeof(struct ixgbe_fdir_rule));
1796                         rte_flow_error_set(error, EINVAL,
1797                                 RTE_FLOW_ERROR_TYPE_ITEM,
1798                                 item, "Not supported by fdir filter");
1799                         return -rte_errno;
1800                 }
1801
1802                 raw_mask = (const struct rte_flow_item_raw *)item->mask;
1803
1804                 /* check mask */
1805                 if (raw_mask->relative != 0x1 ||
1806                     raw_mask->search != 0x1 ||
1807                     raw_mask->reserved != 0x0 ||
1808                     (uint32_t)raw_mask->offset != 0xffffffff ||
1809                     raw_mask->limit != 0xffff ||
1810                     raw_mask->length != 0xffff) {
1811                         memset(rule, 0, sizeof(struct ixgbe_fdir_rule));
1812                         rte_flow_error_set(error, EINVAL,
1813                                 RTE_FLOW_ERROR_TYPE_ITEM,
1814                                 item, "Not supported by fdir filter");
1815                         return -rte_errno;
1816                 }
1817
1818                 raw_spec = (const struct rte_flow_item_raw *)item->spec;
1819
1820                 /* check spec */
1821                 if (raw_spec->relative != 0 ||
1822                     raw_spec->search != 0 ||
1823                     raw_spec->reserved != 0 ||
1824                     raw_spec->offset > IXGBE_MAX_FLX_SOURCE_OFF ||
1825                     raw_spec->offset % 2 ||
1826                     raw_spec->limit != 0 ||
1827                     raw_spec->length != 2 ||
1828                     /* pattern can't be 0xffff */
1829                     (raw_spec->pattern[0] == 0xff &&
1830                      raw_spec->pattern[1] == 0xff)) {
1831                         memset(rule, 0, sizeof(struct ixgbe_fdir_rule));
1832                         rte_flow_error_set(error, EINVAL,
1833                                 RTE_FLOW_ERROR_TYPE_ITEM,
1834                                 item, "Not supported by fdir filter");
1835                         return -rte_errno;
1836                 }
1837
1838                 /* check pattern mask */
1839                 if (raw_mask->pattern[0] != 0xff ||
1840                     raw_mask->pattern[1] != 0xff) {
1841                         memset(rule, 0, sizeof(struct ixgbe_fdir_rule));
1842                         rte_flow_error_set(error, EINVAL,
1843                                 RTE_FLOW_ERROR_TYPE_ITEM,
1844                                 item, "Not supported by fdir filter");
1845                         return -rte_errno;
1846                 }
1847
1848                 rule->mask.flex_bytes_mask = 0xffff;
1849                 rule->ixgbe_fdir.formatted.flex_bytes =
1850                         (((uint16_t)raw_spec->pattern[1]) << 8) |
1851                         raw_spec->pattern[0];
1852                 rule->flex_bytes_offset = raw_spec->offset;
1853         }
1854
1855         if (item->type != RTE_FLOW_ITEM_TYPE_END) {
1856                 /* check if the next not void item is END */
1857                 item = next_no_void_pattern(pattern, item);
1858                 if (item->type != RTE_FLOW_ITEM_TYPE_END) {
1859                         memset(rule, 0, sizeof(struct ixgbe_fdir_rule));
1860                         rte_flow_error_set(error, EINVAL,
1861                                 RTE_FLOW_ERROR_TYPE_ITEM,
1862                                 item, "Not supported by fdir filter");
1863                         return -rte_errno;
1864                 }
1865         }
1866
1867         return ixgbe_parse_fdir_act_attr(attr, actions, rule, error);
1868 }
1869
1870 #define NVGRE_PROTOCOL 0x6558
1871
1872 /**
1873  * Parse the rule to see if it is a VxLAN or NVGRE flow director rule.
1874  * And get the flow director filter info BTW.
1875  * VxLAN PATTERN:
1876  * The first not void item must be ETH.
1877  * The second not void item must be IPV4/ IPV6.
1878  * The third not void item must be NVGRE.
1879  * The next not void item must be END.
1880  * NVGRE PATTERN:
1881  * The first not void item must be ETH.
1882  * The second not void item must be IPV4/ IPV6.
1883  * The third not void item must be NVGRE.
1884  * The next not void item must be END.
1885  * ACTION:
1886  * The first not void action should be QUEUE or DROP.
1887  * The second not void optional action should be MARK,
1888  * mark_id is a uint32_t number.
1889  * The next not void action should be END.
1890  * VxLAN pattern example:
1891  * ITEM         Spec                    Mask
1892  * ETH          NULL                    NULL
1893  * IPV4/IPV6    NULL                    NULL
1894  * UDP          NULL                    NULL
1895  * VxLAN        vni{0x00, 0x32, 0x54}   {0xFF, 0xFF, 0xFF}
1896  * MAC VLAN     tci     0x2016          0xEFFF
1897  * END
1898  * NEGRV pattern example:
1899  * ITEM         Spec                    Mask
1900  * ETH          NULL                    NULL
1901  * IPV4/IPV6    NULL                    NULL
1902  * NVGRE        protocol        0x6558  0xFFFF
1903  *              tni{0x00, 0x32, 0x54}   {0xFF, 0xFF, 0xFF}
1904  * MAC VLAN     tci     0x2016          0xEFFF
1905  * END
1906  * other members in mask and spec should set to 0x00.
1907  * item->last should be NULL.
1908  */
1909 static int
1910 ixgbe_parse_fdir_filter_tunnel(const struct rte_flow_attr *attr,
1911                                const struct rte_flow_item pattern[],
1912                                const struct rte_flow_action actions[],
1913                                struct ixgbe_fdir_rule *rule,
1914                                struct rte_flow_error *error)
1915 {
1916         const struct rte_flow_item *item;
1917         const struct rte_flow_item_vxlan *vxlan_spec;
1918         const struct rte_flow_item_vxlan *vxlan_mask;
1919         const struct rte_flow_item_nvgre *nvgre_spec;
1920         const struct rte_flow_item_nvgre *nvgre_mask;
1921         const struct rte_flow_item_eth *eth_spec;
1922         const struct rte_flow_item_eth *eth_mask;
1923         const struct rte_flow_item_vlan *vlan_spec;
1924         const struct rte_flow_item_vlan *vlan_mask;
1925         uint32_t j;
1926
1927         if (!pattern) {
1928                 rte_flow_error_set(error, EINVAL,
1929                         RTE_FLOW_ERROR_TYPE_ITEM_NUM,
1930                                    NULL, "NULL pattern.");
1931                 return -rte_errno;
1932         }
1933
1934         if (!actions) {
1935                 rte_flow_error_set(error, EINVAL,
1936                                    RTE_FLOW_ERROR_TYPE_ACTION_NUM,
1937                                    NULL, "NULL action.");
1938                 return -rte_errno;
1939         }
1940
1941         if (!attr) {
1942                 rte_flow_error_set(error, EINVAL,
1943                                    RTE_FLOW_ERROR_TYPE_ATTR,
1944                                    NULL, "NULL attribute.");
1945                 return -rte_errno;
1946         }
1947
1948         /**
1949          * Some fields may not be provided. Set spec to 0 and mask to default
1950          * value. So, we need not do anything for the not provided fields later.
1951          */
1952         memset(rule, 0, sizeof(struct ixgbe_fdir_rule));
1953         memset(&rule->mask, 0xFF, sizeof(struct ixgbe_hw_fdir_mask));
1954         rule->mask.vlan_tci_mask = 0;
1955
1956         /**
1957          * The first not void item should be
1958          * MAC or IPv4 or IPv6 or UDP or VxLAN.
1959          */
1960         item = next_no_void_pattern(pattern, NULL);
1961         if (item->type != RTE_FLOW_ITEM_TYPE_ETH &&
1962             item->type != RTE_FLOW_ITEM_TYPE_IPV4 &&
1963             item->type != RTE_FLOW_ITEM_TYPE_IPV6 &&
1964             item->type != RTE_FLOW_ITEM_TYPE_UDP &&
1965             item->type != RTE_FLOW_ITEM_TYPE_VXLAN &&
1966             item->type != RTE_FLOW_ITEM_TYPE_NVGRE) {
1967                 memset(rule, 0, sizeof(struct ixgbe_fdir_rule));
1968                 rte_flow_error_set(error, EINVAL,
1969                         RTE_FLOW_ERROR_TYPE_ITEM,
1970                         item, "Not supported by fdir filter");
1971                 return -rte_errno;
1972         }
1973
1974         rule->mode = RTE_FDIR_MODE_PERFECT_TUNNEL;
1975
1976         /* Skip MAC. */
1977         if (item->type == RTE_FLOW_ITEM_TYPE_ETH) {
1978                 /* Only used to describe the protocol stack. */
1979                 if (item->spec || item->mask) {
1980                         memset(rule, 0, sizeof(struct ixgbe_fdir_rule));
1981                         rte_flow_error_set(error, EINVAL,
1982                                 RTE_FLOW_ERROR_TYPE_ITEM,
1983                                 item, "Not supported by fdir filter");
1984                         return -rte_errno;
1985                 }
1986                 /* Not supported last point for range*/
1987                 if (item->last) {
1988                         rte_flow_error_set(error, EINVAL,
1989                                 RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
1990                                 item, "Not supported last point for range");
1991                         return -rte_errno;
1992                 }
1993
1994                 /* Check if the next not void item is IPv4 or IPv6. */
1995                 item = next_no_void_pattern(pattern, item);
1996                 if (item->type != RTE_FLOW_ITEM_TYPE_IPV4 &&
1997                     item->type != RTE_FLOW_ITEM_TYPE_IPV6) {
1998                         memset(rule, 0, sizeof(struct ixgbe_fdir_rule));
1999                         rte_flow_error_set(error, EINVAL,
2000                                 RTE_FLOW_ERROR_TYPE_ITEM,
2001                                 item, "Not supported by fdir filter");
2002                         return -rte_errno;
2003                 }
2004         }
2005
2006         /* Skip IP. */
2007         if (item->type == RTE_FLOW_ITEM_TYPE_IPV4 ||
2008             item->type == RTE_FLOW_ITEM_TYPE_IPV6) {
2009                 /* Only used to describe the protocol stack. */
2010                 if (item->spec || item->mask) {
2011                         memset(rule, 0, sizeof(struct ixgbe_fdir_rule));
2012                         rte_flow_error_set(error, EINVAL,
2013                                 RTE_FLOW_ERROR_TYPE_ITEM,
2014                                 item, "Not supported by fdir filter");
2015                         return -rte_errno;
2016                 }
2017                 /*Not supported last point for range*/
2018                 if (item->last) {
2019                         rte_flow_error_set(error, EINVAL,
2020                                 RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
2021                                 item, "Not supported last point for range");
2022                         return -rte_errno;
2023                 }
2024
2025                 /* Check if the next not void item is UDP or NVGRE. */
2026                 item = next_no_void_pattern(pattern, item);
2027                 if (item->type != RTE_FLOW_ITEM_TYPE_UDP &&
2028                     item->type != RTE_FLOW_ITEM_TYPE_NVGRE) {
2029                         memset(rule, 0, sizeof(struct ixgbe_fdir_rule));
2030                         rte_flow_error_set(error, EINVAL,
2031                                 RTE_FLOW_ERROR_TYPE_ITEM,
2032                                 item, "Not supported by fdir filter");
2033                         return -rte_errno;
2034                 }
2035         }
2036
2037         /* Skip UDP. */
2038         if (item->type == RTE_FLOW_ITEM_TYPE_UDP) {
2039                 /* Only used to describe the protocol stack. */
2040                 if (item->spec || item->mask) {
2041                         memset(rule, 0, sizeof(struct ixgbe_fdir_rule));
2042                         rte_flow_error_set(error, EINVAL,
2043                                 RTE_FLOW_ERROR_TYPE_ITEM,
2044                                 item, "Not supported by fdir filter");
2045                         return -rte_errno;
2046                 }
2047                 /*Not supported last point for range*/
2048                 if (item->last) {
2049                         rte_flow_error_set(error, EINVAL,
2050                                 RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
2051                                 item, "Not supported last point for range");
2052                         return -rte_errno;
2053                 }
2054
2055                 /* Check if the next not void item is VxLAN. */
2056                 item = next_no_void_pattern(pattern, item);
2057                 if (item->type != RTE_FLOW_ITEM_TYPE_VXLAN) {
2058                         memset(rule, 0, sizeof(struct ixgbe_fdir_rule));
2059                         rte_flow_error_set(error, EINVAL,
2060                                 RTE_FLOW_ERROR_TYPE_ITEM,
2061                                 item, "Not supported by fdir filter");
2062                         return -rte_errno;
2063                 }
2064         }
2065
2066         /* Get the VxLAN info */
2067         if (item->type == RTE_FLOW_ITEM_TYPE_VXLAN) {
2068                 rule->ixgbe_fdir.formatted.tunnel_type =
2069                         RTE_FDIR_TUNNEL_TYPE_VXLAN;
2070
2071                 /* Only care about VNI, others should be masked. */
2072                 if (!item->mask) {
2073                         memset(rule, 0, sizeof(struct ixgbe_fdir_rule));
2074                         rte_flow_error_set(error, EINVAL,
2075                                 RTE_FLOW_ERROR_TYPE_ITEM,
2076                                 item, "Not supported by fdir filter");
2077                         return -rte_errno;
2078                 }
2079                 /*Not supported last point for range*/
2080                 if (item->last) {
2081                         rte_flow_error_set(error, EINVAL,
2082                                 RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
2083                                 item, "Not supported last point for range");
2084                         return -rte_errno;
2085                 }
2086                 rule->b_mask = TRUE;
2087
2088                 /* Tunnel type is always meaningful. */
2089                 rule->mask.tunnel_type_mask = 1;
2090
2091                 vxlan_mask =
2092                         (const struct rte_flow_item_vxlan *)item->mask;
2093                 if (vxlan_mask->flags) {
2094                         memset(rule, 0, sizeof(struct ixgbe_fdir_rule));
2095                         rte_flow_error_set(error, EINVAL,
2096                                 RTE_FLOW_ERROR_TYPE_ITEM,
2097                                 item, "Not supported by fdir filter");
2098                         return -rte_errno;
2099                 }
2100                 /* VNI must be totally masked or not. */
2101                 if ((vxlan_mask->vni[0] || vxlan_mask->vni[1] ||
2102                         vxlan_mask->vni[2]) &&
2103                         ((vxlan_mask->vni[0] != 0xFF) ||
2104                         (vxlan_mask->vni[1] != 0xFF) ||
2105                                 (vxlan_mask->vni[2] != 0xFF))) {
2106                         memset(rule, 0, sizeof(struct ixgbe_fdir_rule));
2107                         rte_flow_error_set(error, EINVAL,
2108                                 RTE_FLOW_ERROR_TYPE_ITEM,
2109                                 item, "Not supported by fdir filter");
2110                         return -rte_errno;
2111                 }
2112
2113                 rte_memcpy(&rule->mask.tunnel_id_mask, vxlan_mask->vni,
2114                         RTE_DIM(vxlan_mask->vni));
2115
2116                 if (item->spec) {
2117                         rule->b_spec = TRUE;
2118                         vxlan_spec = (const struct rte_flow_item_vxlan *)
2119                                         item->spec;
2120                         rte_memcpy(((uint8_t *)
2121                                 &rule->ixgbe_fdir.formatted.tni_vni + 1),
2122                                 vxlan_spec->vni, RTE_DIM(vxlan_spec->vni));
2123                         rule->ixgbe_fdir.formatted.tni_vni = rte_be_to_cpu_32(
2124                                 rule->ixgbe_fdir.formatted.tni_vni);
2125                 }
2126         }
2127
2128         /* Get the NVGRE info */
2129         if (item->type == RTE_FLOW_ITEM_TYPE_NVGRE) {
2130                 rule->ixgbe_fdir.formatted.tunnel_type =
2131                         RTE_FDIR_TUNNEL_TYPE_NVGRE;
2132
2133                 /**
2134                  * Only care about flags0, flags1, protocol and TNI,
2135                  * others should be masked.
2136                  */
2137                 if (!item->mask) {
2138                         memset(rule, 0, sizeof(struct ixgbe_fdir_rule));
2139                         rte_flow_error_set(error, EINVAL,
2140                                 RTE_FLOW_ERROR_TYPE_ITEM,
2141                                 item, "Not supported by fdir filter");
2142                         return -rte_errno;
2143                 }
2144                 /*Not supported last point for range*/
2145                 if (item->last) {
2146                         rte_flow_error_set(error, EINVAL,
2147                                 RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
2148                                 item, "Not supported last point for range");
2149                         return -rte_errno;
2150                 }
2151                 rule->b_mask = TRUE;
2152
2153                 /* Tunnel type is always meaningful. */
2154                 rule->mask.tunnel_type_mask = 1;
2155
2156                 nvgre_mask =
2157                         (const struct rte_flow_item_nvgre *)item->mask;
2158                 if (nvgre_mask->flow_id) {
2159                         memset(rule, 0, sizeof(struct ixgbe_fdir_rule));
2160                         rte_flow_error_set(error, EINVAL,
2161                                 RTE_FLOW_ERROR_TYPE_ITEM,
2162                                 item, "Not supported by fdir filter");
2163                         return -rte_errno;
2164                 }
2165                 if (nvgre_mask->c_k_s_rsvd0_ver !=
2166                         rte_cpu_to_be_16(0x3000) ||
2167                     nvgre_mask->protocol != 0xFFFF) {
2168                         memset(rule, 0, sizeof(struct ixgbe_fdir_rule));
2169                         rte_flow_error_set(error, EINVAL,
2170                                 RTE_FLOW_ERROR_TYPE_ITEM,
2171                                 item, "Not supported by fdir filter");
2172                         return -rte_errno;
2173                 }
2174                 /* TNI must be totally masked or not. */
2175                 if (nvgre_mask->tni[0] &&
2176                     ((nvgre_mask->tni[0] != 0xFF) ||
2177                     (nvgre_mask->tni[1] != 0xFF) ||
2178                     (nvgre_mask->tni[2] != 0xFF))) {
2179                         memset(rule, 0, sizeof(struct ixgbe_fdir_rule));
2180                         rte_flow_error_set(error, EINVAL,
2181                                 RTE_FLOW_ERROR_TYPE_ITEM,
2182                                 item, "Not supported by fdir filter");
2183                         return -rte_errno;
2184                 }
2185                 /* tni is a 24-bits bit field */
2186                 rte_memcpy(&rule->mask.tunnel_id_mask, nvgre_mask->tni,
2187                         RTE_DIM(nvgre_mask->tni));
2188                 rule->mask.tunnel_id_mask <<= 8;
2189
2190                 if (item->spec) {
2191                         rule->b_spec = TRUE;
2192                         nvgre_spec =
2193                                 (const struct rte_flow_item_nvgre *)item->spec;
2194                         if (nvgre_spec->c_k_s_rsvd0_ver !=
2195                             rte_cpu_to_be_16(0x2000) ||
2196                             nvgre_spec->protocol !=
2197                             rte_cpu_to_be_16(NVGRE_PROTOCOL)) {
2198                                 memset(rule, 0, sizeof(struct ixgbe_fdir_rule));
2199                                 rte_flow_error_set(error, EINVAL,
2200                                         RTE_FLOW_ERROR_TYPE_ITEM,
2201                                         item, "Not supported by fdir filter");
2202                                 return -rte_errno;
2203                         }
2204                         /* tni is a 24-bits bit field */
2205                         rte_memcpy(&rule->ixgbe_fdir.formatted.tni_vni,
2206                         nvgre_spec->tni, RTE_DIM(nvgre_spec->tni));
2207                         rule->ixgbe_fdir.formatted.tni_vni <<= 8;
2208                 }
2209         }
2210
2211         /* check if the next not void item is MAC */
2212         item = next_no_void_pattern(pattern, item);
2213         if (item->type != RTE_FLOW_ITEM_TYPE_ETH) {
2214                 memset(rule, 0, sizeof(struct ixgbe_fdir_rule));
2215                 rte_flow_error_set(error, EINVAL,
2216                         RTE_FLOW_ERROR_TYPE_ITEM,
2217                         item, "Not supported by fdir filter");
2218                 return -rte_errno;
2219         }
2220
2221         /**
2222          * Only support vlan and dst MAC address,
2223          * others should be masked.
2224          */
2225
2226         if (!item->mask) {
2227                 memset(rule, 0, sizeof(struct ixgbe_fdir_rule));
2228                 rte_flow_error_set(error, EINVAL,
2229                         RTE_FLOW_ERROR_TYPE_ITEM,
2230                         item, "Not supported by fdir filter");
2231                 return -rte_errno;
2232         }
2233         /*Not supported last point for range*/
2234         if (item->last) {
2235                 rte_flow_error_set(error, EINVAL,
2236                         RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
2237                         item, "Not supported last point for range");
2238                 return -rte_errno;
2239         }
2240         rule->b_mask = TRUE;
2241         eth_mask = (const struct rte_flow_item_eth *)item->mask;
2242
2243         /* Ether type should be masked. */
2244         if (eth_mask->type) {
2245                 memset(rule, 0, sizeof(struct ixgbe_fdir_rule));
2246                 rte_flow_error_set(error, EINVAL,
2247                         RTE_FLOW_ERROR_TYPE_ITEM,
2248                         item, "Not supported by fdir filter");
2249                 return -rte_errno;
2250         }
2251
2252         /* src MAC address should be masked. */
2253         for (j = 0; j < ETHER_ADDR_LEN; j++) {
2254                 if (eth_mask->src.addr_bytes[j]) {
2255                         memset(rule, 0,
2256                                sizeof(struct ixgbe_fdir_rule));
2257                         rte_flow_error_set(error, EINVAL,
2258                                 RTE_FLOW_ERROR_TYPE_ITEM,
2259                                 item, "Not supported by fdir filter");
2260                         return -rte_errno;
2261                 }
2262         }
2263         rule->mask.mac_addr_byte_mask = 0;
2264         for (j = 0; j < ETHER_ADDR_LEN; j++) {
2265                 /* It's a per byte mask. */
2266                 if (eth_mask->dst.addr_bytes[j] == 0xFF) {
2267                         rule->mask.mac_addr_byte_mask |= 0x1 << j;
2268                 } else if (eth_mask->dst.addr_bytes[j]) {
2269                         memset(rule, 0, sizeof(struct ixgbe_fdir_rule));
2270                         rte_flow_error_set(error, EINVAL,
2271                                 RTE_FLOW_ERROR_TYPE_ITEM,
2272                                 item, "Not supported by fdir filter");
2273                         return -rte_errno;
2274                 }
2275         }
2276
2277         /* When no vlan, considered as full mask. */
2278         rule->mask.vlan_tci_mask = rte_cpu_to_be_16(0xEFFF);
2279
2280         if (item->spec) {
2281                 rule->b_spec = TRUE;
2282                 eth_spec = (const struct rte_flow_item_eth *)item->spec;
2283
2284                 /* Get the dst MAC. */
2285                 for (j = 0; j < ETHER_ADDR_LEN; j++) {
2286                         rule->ixgbe_fdir.formatted.inner_mac[j] =
2287                                 eth_spec->dst.addr_bytes[j];
2288                 }
2289         }
2290
2291         /**
2292          * Check if the next not void item is vlan or ipv4.
2293          * IPv6 is not supported.
2294          */
2295         item = next_no_void_pattern(pattern, item);
2296         if ((item->type != RTE_FLOW_ITEM_TYPE_VLAN) &&
2297                 (item->type != RTE_FLOW_ITEM_TYPE_IPV4)) {
2298                 memset(rule, 0, sizeof(struct ixgbe_fdir_rule));
2299                 rte_flow_error_set(error, EINVAL,
2300                         RTE_FLOW_ERROR_TYPE_ITEM,
2301                         item, "Not supported by fdir filter");
2302                 return -rte_errno;
2303         }
2304         /*Not supported last point for range*/
2305         if (item->last) {
2306                 rte_flow_error_set(error, EINVAL,
2307                         RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
2308                         item, "Not supported last point for range");
2309                 return -rte_errno;
2310         }
2311
2312         if (item->type == RTE_FLOW_ITEM_TYPE_VLAN) {
2313                 if (!(item->spec && item->mask)) {
2314                         memset(rule, 0, sizeof(struct ixgbe_fdir_rule));
2315                         rte_flow_error_set(error, EINVAL,
2316                                 RTE_FLOW_ERROR_TYPE_ITEM,
2317                                 item, "Not supported by fdir filter");
2318                         return -rte_errno;
2319                 }
2320
2321                 vlan_spec = (const struct rte_flow_item_vlan *)item->spec;
2322                 vlan_mask = (const struct rte_flow_item_vlan *)item->mask;
2323
2324                 rule->ixgbe_fdir.formatted.vlan_id = vlan_spec->tci;
2325
2326                 rule->mask.vlan_tci_mask = vlan_mask->tci;
2327                 rule->mask.vlan_tci_mask &= rte_cpu_to_be_16(0xEFFF);
2328                 /* More than one tags are not supported. */
2329
2330                 /* check if the next not void item is END */
2331                 item = next_no_void_pattern(pattern, item);
2332
2333                 if (item->type != RTE_FLOW_ITEM_TYPE_END) {
2334                         memset(rule, 0, sizeof(struct ixgbe_fdir_rule));
2335                         rte_flow_error_set(error, EINVAL,
2336                                 RTE_FLOW_ERROR_TYPE_ITEM,
2337                                 item, "Not supported by fdir filter");
2338                         return -rte_errno;
2339                 }
2340         }
2341
2342         /**
2343          * If the tags is 0, it means don't care about the VLAN.
2344          * Do nothing.
2345          */
2346
2347         return ixgbe_parse_fdir_act_attr(attr, actions, rule, error);
2348 }
2349
2350 static int
2351 ixgbe_parse_fdir_filter(struct rte_eth_dev *dev,
2352                         const struct rte_flow_attr *attr,
2353                         const struct rte_flow_item pattern[],
2354                         const struct rte_flow_action actions[],
2355                         struct ixgbe_fdir_rule *rule,
2356                         struct rte_flow_error *error)
2357 {
2358         int ret;
2359         struct ixgbe_hw *hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
2360         enum rte_fdir_mode fdir_mode = dev->data->dev_conf.fdir_conf.mode;
2361
2362         if (hw->mac.type != ixgbe_mac_82599EB &&
2363                 hw->mac.type != ixgbe_mac_X540 &&
2364                 hw->mac.type != ixgbe_mac_X550 &&
2365                 hw->mac.type != ixgbe_mac_X550EM_x &&
2366                 hw->mac.type != ixgbe_mac_X550EM_a)
2367                 return -ENOTSUP;
2368
2369         ret = ixgbe_parse_fdir_filter_normal(attr, pattern,
2370                                         actions, rule, error);
2371
2372         if (!ret)
2373                 goto step_next;
2374
2375         ret = ixgbe_parse_fdir_filter_tunnel(attr, pattern,
2376                                         actions, rule, error);
2377
2378 step_next:
2379         if (fdir_mode == RTE_FDIR_MODE_NONE ||
2380             fdir_mode != rule->mode)
2381                 return -ENOTSUP;
2382         return ret;
2383 }
2384
2385 void
2386 ixgbe_filterlist_flush(void)
2387 {
2388         struct ixgbe_ntuple_filter_ele *ntuple_filter_ptr;
2389         struct ixgbe_ethertype_filter_ele *ethertype_filter_ptr;
2390         struct ixgbe_eth_syn_filter_ele *syn_filter_ptr;
2391         struct ixgbe_eth_l2_tunnel_conf_ele *l2_tn_filter_ptr;
2392         struct ixgbe_fdir_rule_ele *fdir_rule_ptr;
2393         struct ixgbe_flow_mem *ixgbe_flow_mem_ptr;
2394
2395         while ((ntuple_filter_ptr = TAILQ_FIRST(&filter_ntuple_list))) {
2396                 TAILQ_REMOVE(&filter_ntuple_list,
2397                                  ntuple_filter_ptr,
2398                                  entries);
2399                 rte_free(ntuple_filter_ptr);
2400         }
2401
2402         while ((ethertype_filter_ptr = TAILQ_FIRST(&filter_ethertype_list))) {
2403                 TAILQ_REMOVE(&filter_ethertype_list,
2404                                  ethertype_filter_ptr,
2405                                  entries);
2406                 rte_free(ethertype_filter_ptr);
2407         }
2408
2409         while ((syn_filter_ptr = TAILQ_FIRST(&filter_syn_list))) {
2410                 TAILQ_REMOVE(&filter_syn_list,
2411                                  syn_filter_ptr,
2412                                  entries);
2413                 rte_free(syn_filter_ptr);
2414         }
2415
2416         while ((l2_tn_filter_ptr = TAILQ_FIRST(&filter_l2_tunnel_list))) {
2417                 TAILQ_REMOVE(&filter_l2_tunnel_list,
2418                                  l2_tn_filter_ptr,
2419                                  entries);
2420                 rte_free(l2_tn_filter_ptr);
2421         }
2422
2423         while ((fdir_rule_ptr = TAILQ_FIRST(&filter_fdir_list))) {
2424                 TAILQ_REMOVE(&filter_fdir_list,
2425                                  fdir_rule_ptr,
2426                                  entries);
2427                 rte_free(fdir_rule_ptr);
2428         }
2429
2430         while ((ixgbe_flow_mem_ptr = TAILQ_FIRST(&ixgbe_flow_list))) {
2431                 TAILQ_REMOVE(&ixgbe_flow_list,
2432                                  ixgbe_flow_mem_ptr,
2433                                  entries);
2434                 rte_free(ixgbe_flow_mem_ptr->flow);
2435                 rte_free(ixgbe_flow_mem_ptr);
2436         }
2437 }
2438
2439 /**
2440  * Create or destroy a flow rule.
2441  * Theorically one rule can match more than one filters.
2442  * We will let it use the filter which it hitt first.
2443  * So, the sequence matters.
2444  */
2445 static struct rte_flow *
2446 ixgbe_flow_create(struct rte_eth_dev *dev,
2447                   const struct rte_flow_attr *attr,
2448                   const struct rte_flow_item pattern[],
2449                   const struct rte_flow_action actions[],
2450                   struct rte_flow_error *error)
2451 {
2452         int ret;
2453         struct rte_eth_ntuple_filter ntuple_filter;
2454         struct rte_eth_ethertype_filter ethertype_filter;
2455         struct rte_eth_syn_filter syn_filter;
2456         struct ixgbe_fdir_rule fdir_rule;
2457         struct rte_eth_l2_tunnel_conf l2_tn_filter;
2458         struct ixgbe_hw_fdir_info *fdir_info =
2459                 IXGBE_DEV_PRIVATE_TO_FDIR_INFO(dev->data->dev_private);
2460         struct rte_flow *flow = NULL;
2461         struct ixgbe_ntuple_filter_ele *ntuple_filter_ptr;
2462         struct ixgbe_ethertype_filter_ele *ethertype_filter_ptr;
2463         struct ixgbe_eth_syn_filter_ele *syn_filter_ptr;
2464         struct ixgbe_eth_l2_tunnel_conf_ele *l2_tn_filter_ptr;
2465         struct ixgbe_fdir_rule_ele *fdir_rule_ptr;
2466         struct ixgbe_flow_mem *ixgbe_flow_mem_ptr;
2467
2468         flow = rte_zmalloc("ixgbe_rte_flow", sizeof(struct rte_flow), 0);
2469         if (!flow) {
2470                 PMD_DRV_LOG(ERR, "failed to allocate memory");
2471                 return (struct rte_flow *)flow;
2472         }
2473         ixgbe_flow_mem_ptr = rte_zmalloc("ixgbe_flow_mem",
2474                         sizeof(struct ixgbe_flow_mem), 0);
2475         if (!ixgbe_flow_mem_ptr) {
2476                 PMD_DRV_LOG(ERR, "failed to allocate memory");
2477                 rte_free(flow);
2478                 return NULL;
2479         }
2480         ixgbe_flow_mem_ptr->flow = flow;
2481         TAILQ_INSERT_TAIL(&ixgbe_flow_list,
2482                                 ixgbe_flow_mem_ptr, entries);
2483
2484         memset(&ntuple_filter, 0, sizeof(struct rte_eth_ntuple_filter));
2485         ret = ixgbe_parse_ntuple_filter(dev, attr, pattern,
2486                         actions, &ntuple_filter, error);
2487         if (!ret) {
2488                 ret = ixgbe_add_del_ntuple_filter(dev, &ntuple_filter, TRUE);
2489                 if (!ret) {
2490                         ntuple_filter_ptr = rte_zmalloc("ixgbe_ntuple_filter",
2491                                 sizeof(struct ixgbe_ntuple_filter_ele), 0);
2492                         (void)rte_memcpy(&ntuple_filter_ptr->filter_info,
2493                                 &ntuple_filter,
2494                                 sizeof(struct rte_eth_ntuple_filter));
2495                         TAILQ_INSERT_TAIL(&filter_ntuple_list,
2496                                 ntuple_filter_ptr, entries);
2497                         flow->rule = ntuple_filter_ptr;
2498                         flow->filter_type = RTE_ETH_FILTER_NTUPLE;
2499                         return flow;
2500                 }
2501                 goto out;
2502         }
2503
2504         memset(&ethertype_filter, 0, sizeof(struct rte_eth_ethertype_filter));
2505         ret = ixgbe_parse_ethertype_filter(dev, attr, pattern,
2506                                 actions, &ethertype_filter, error);
2507         if (!ret) {
2508                 ret = ixgbe_add_del_ethertype_filter(dev,
2509                                 &ethertype_filter, TRUE);
2510                 if (!ret) {
2511                         ethertype_filter_ptr = rte_zmalloc(
2512                                 "ixgbe_ethertype_filter",
2513                                 sizeof(struct ixgbe_ethertype_filter_ele), 0);
2514                         (void)rte_memcpy(&ethertype_filter_ptr->filter_info,
2515                                 &ethertype_filter,
2516                                 sizeof(struct rte_eth_ethertype_filter));
2517                         TAILQ_INSERT_TAIL(&filter_ethertype_list,
2518                                 ethertype_filter_ptr, entries);
2519                         flow->rule = ethertype_filter_ptr;
2520                         flow->filter_type = RTE_ETH_FILTER_ETHERTYPE;
2521                         return flow;
2522                 }
2523                 goto out;
2524         }
2525
2526         memset(&syn_filter, 0, sizeof(struct rte_eth_syn_filter));
2527         ret = ixgbe_parse_syn_filter(dev, attr, pattern,
2528                                 actions, &syn_filter, error);
2529         if (!ret) {
2530                 ret = ixgbe_syn_filter_set(dev, &syn_filter, TRUE);
2531                 if (!ret) {
2532                         syn_filter_ptr = rte_zmalloc("ixgbe_syn_filter",
2533                                 sizeof(struct ixgbe_eth_syn_filter_ele), 0);
2534                         (void)rte_memcpy(&syn_filter_ptr->filter_info,
2535                                 &syn_filter,
2536                                 sizeof(struct rte_eth_syn_filter));
2537                         TAILQ_INSERT_TAIL(&filter_syn_list,
2538                                 syn_filter_ptr,
2539                                 entries);
2540                         flow->rule = syn_filter_ptr;
2541                         flow->filter_type = RTE_ETH_FILTER_SYN;
2542                         return flow;
2543                 }
2544                 goto out;
2545         }
2546
2547         memset(&fdir_rule, 0, sizeof(struct ixgbe_fdir_rule));
2548         ret = ixgbe_parse_fdir_filter(dev, attr, pattern,
2549                                 actions, &fdir_rule, error);
2550         if (!ret) {
2551                 /* A mask cannot be deleted. */
2552                 if (fdir_rule.b_mask) {
2553                         if (!fdir_info->mask_added) {
2554                                 /* It's the first time the mask is set. */
2555                                 rte_memcpy(&fdir_info->mask,
2556                                         &fdir_rule.mask,
2557                                         sizeof(struct ixgbe_hw_fdir_mask));
2558                                 fdir_info->flex_bytes_offset =
2559                                         fdir_rule.flex_bytes_offset;
2560
2561                                 if (fdir_rule.mask.flex_bytes_mask)
2562                                         ixgbe_fdir_set_flexbytes_offset(dev,
2563                                                 fdir_rule.flex_bytes_offset);
2564
2565                                 ret = ixgbe_fdir_set_input_mask(dev);
2566                                 if (ret)
2567                                         goto out;
2568
2569                                 fdir_info->mask_added = TRUE;
2570                         } else {
2571                                 /**
2572                                  * Only support one global mask,
2573                                  * all the masks should be the same.
2574                                  */
2575                                 ret = memcmp(&fdir_info->mask,
2576                                         &fdir_rule.mask,
2577                                         sizeof(struct ixgbe_hw_fdir_mask));
2578                                 if (ret)
2579                                         goto out;
2580
2581                                 if (fdir_info->flex_bytes_offset !=
2582                                                 fdir_rule.flex_bytes_offset)
2583                                         goto out;
2584                         }
2585                 }
2586
2587                 if (fdir_rule.b_spec) {
2588                         ret = ixgbe_fdir_filter_program(dev, &fdir_rule,
2589                                         FALSE, FALSE);
2590                         if (!ret) {
2591                                 fdir_rule_ptr = rte_zmalloc("ixgbe_fdir_filter",
2592                                         sizeof(struct ixgbe_fdir_rule_ele), 0);
2593                                 (void)rte_memcpy(&fdir_rule_ptr->filter_info,
2594                                         &fdir_rule,
2595                                         sizeof(struct ixgbe_fdir_rule));
2596                                 TAILQ_INSERT_TAIL(&filter_fdir_list,
2597                                         fdir_rule_ptr, entries);
2598                                 flow->rule = fdir_rule_ptr;
2599                                 flow->filter_type = RTE_ETH_FILTER_FDIR;
2600
2601                                 return flow;
2602                         }
2603
2604                         if (ret)
2605                                 goto out;
2606                 }
2607
2608                 goto out;
2609         }
2610
2611         memset(&l2_tn_filter, 0, sizeof(struct rte_eth_l2_tunnel_conf));
2612         ret = ixgbe_parse_l2_tn_filter(dev, attr, pattern,
2613                                         actions, &l2_tn_filter, error);
2614         if (!ret) {
2615                 ret = ixgbe_dev_l2_tunnel_filter_add(dev, &l2_tn_filter, FALSE);
2616                 if (!ret) {
2617                         l2_tn_filter_ptr = rte_zmalloc("ixgbe_l2_tn_filter",
2618                                 sizeof(struct ixgbe_eth_l2_tunnel_conf_ele), 0);
2619                         (void)rte_memcpy(&l2_tn_filter_ptr->filter_info,
2620                                 &l2_tn_filter,
2621                                 sizeof(struct rte_eth_l2_tunnel_conf));
2622                         TAILQ_INSERT_TAIL(&filter_l2_tunnel_list,
2623                                 l2_tn_filter_ptr, entries);
2624                         flow->rule = l2_tn_filter_ptr;
2625                         flow->filter_type = RTE_ETH_FILTER_L2_TUNNEL;
2626                         return flow;
2627                 }
2628         }
2629
2630 out:
2631         TAILQ_REMOVE(&ixgbe_flow_list,
2632                 ixgbe_flow_mem_ptr, entries);
2633         rte_flow_error_set(error, -ret,
2634                            RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
2635                            "Failed to create flow.");
2636         rte_free(ixgbe_flow_mem_ptr);
2637         rte_free(flow);
2638         return NULL;
2639 }
2640
2641 /**
2642  * Check if the flow rule is supported by ixgbe.
2643  * It only checkes the format. Don't guarantee the rule can be programmed into
2644  * the HW. Because there can be no enough room for the rule.
2645  */
2646 static int
2647 ixgbe_flow_validate(struct rte_eth_dev *dev,
2648                 const struct rte_flow_attr *attr,
2649                 const struct rte_flow_item pattern[],
2650                 const struct rte_flow_action actions[],
2651                 struct rte_flow_error *error)
2652 {
2653         struct rte_eth_ntuple_filter ntuple_filter;
2654         struct rte_eth_ethertype_filter ethertype_filter;
2655         struct rte_eth_syn_filter syn_filter;
2656         struct rte_eth_l2_tunnel_conf l2_tn_filter;
2657         struct ixgbe_fdir_rule fdir_rule;
2658         int ret;
2659
2660         memset(&ntuple_filter, 0, sizeof(struct rte_eth_ntuple_filter));
2661         ret = ixgbe_parse_ntuple_filter(dev, attr, pattern,
2662                                 actions, &ntuple_filter, error);
2663         if (!ret)
2664                 return 0;
2665
2666         memset(&ethertype_filter, 0, sizeof(struct rte_eth_ethertype_filter));
2667         ret = ixgbe_parse_ethertype_filter(dev, attr, pattern,
2668                                 actions, &ethertype_filter, error);
2669         if (!ret)
2670                 return 0;
2671
2672         memset(&syn_filter, 0, sizeof(struct rte_eth_syn_filter));
2673         ret = ixgbe_parse_syn_filter(dev, attr, pattern,
2674                                 actions, &syn_filter, error);
2675         if (!ret)
2676                 return 0;
2677
2678         memset(&fdir_rule, 0, sizeof(struct ixgbe_fdir_rule));
2679         ret = ixgbe_parse_fdir_filter(dev, attr, pattern,
2680                                 actions, &fdir_rule, error);
2681         if (!ret)
2682                 return 0;
2683
2684         memset(&l2_tn_filter, 0, sizeof(struct rte_eth_l2_tunnel_conf));
2685         ret = ixgbe_parse_l2_tn_filter(dev, attr, pattern,
2686                                 actions, &l2_tn_filter, error);
2687
2688         return ret;
2689 }
2690
2691 /* Destroy a flow rule on ixgbe. */
2692 static int
2693 ixgbe_flow_destroy(struct rte_eth_dev *dev,
2694                 struct rte_flow *flow,
2695                 struct rte_flow_error *error)
2696 {
2697         int ret;
2698         struct rte_flow *pmd_flow = flow;
2699         enum rte_filter_type filter_type = pmd_flow->filter_type;
2700         struct rte_eth_ntuple_filter ntuple_filter;
2701         struct rte_eth_ethertype_filter ethertype_filter;
2702         struct rte_eth_syn_filter syn_filter;
2703         struct ixgbe_fdir_rule fdir_rule;
2704         struct rte_eth_l2_tunnel_conf l2_tn_filter;
2705         struct ixgbe_ntuple_filter_ele *ntuple_filter_ptr;
2706         struct ixgbe_ethertype_filter_ele *ethertype_filter_ptr;
2707         struct ixgbe_eth_syn_filter_ele *syn_filter_ptr;
2708         struct ixgbe_eth_l2_tunnel_conf_ele *l2_tn_filter_ptr;
2709         struct ixgbe_fdir_rule_ele *fdir_rule_ptr;
2710         struct ixgbe_flow_mem *ixgbe_flow_mem_ptr;
2711         struct ixgbe_hw_fdir_info *fdir_info =
2712                 IXGBE_DEV_PRIVATE_TO_FDIR_INFO(dev->data->dev_private);
2713
2714         switch (filter_type) {
2715         case RTE_ETH_FILTER_NTUPLE:
2716                 ntuple_filter_ptr = (struct ixgbe_ntuple_filter_ele *)
2717                                         pmd_flow->rule;
2718                 (void)rte_memcpy(&ntuple_filter,
2719                         &ntuple_filter_ptr->filter_info,
2720                         sizeof(struct rte_eth_ntuple_filter));
2721                 ret = ixgbe_add_del_ntuple_filter(dev, &ntuple_filter, FALSE);
2722                 if (!ret) {
2723                         TAILQ_REMOVE(&filter_ntuple_list,
2724                         ntuple_filter_ptr, entries);
2725                         rte_free(ntuple_filter_ptr);
2726                 }
2727                 break;
2728         case RTE_ETH_FILTER_ETHERTYPE:
2729                 ethertype_filter_ptr = (struct ixgbe_ethertype_filter_ele *)
2730                                         pmd_flow->rule;
2731                 (void)rte_memcpy(&ethertype_filter,
2732                         &ethertype_filter_ptr->filter_info,
2733                         sizeof(struct rte_eth_ethertype_filter));
2734                 ret = ixgbe_add_del_ethertype_filter(dev,
2735                                 &ethertype_filter, FALSE);
2736                 if (!ret) {
2737                         TAILQ_REMOVE(&filter_ethertype_list,
2738                                 ethertype_filter_ptr, entries);
2739                         rte_free(ethertype_filter_ptr);
2740                 }
2741                 break;
2742         case RTE_ETH_FILTER_SYN:
2743                 syn_filter_ptr = (struct ixgbe_eth_syn_filter_ele *)
2744                                 pmd_flow->rule;
2745                 (void)rte_memcpy(&syn_filter,
2746                         &syn_filter_ptr->filter_info,
2747                         sizeof(struct rte_eth_syn_filter));
2748                 ret = ixgbe_syn_filter_set(dev, &syn_filter, FALSE);
2749                 if (!ret) {
2750                         TAILQ_REMOVE(&filter_syn_list,
2751                                 syn_filter_ptr, entries);
2752                         rte_free(syn_filter_ptr);
2753                 }
2754                 break;
2755         case RTE_ETH_FILTER_FDIR:
2756                 fdir_rule_ptr = (struct ixgbe_fdir_rule_ele *)pmd_flow->rule;
2757                 (void)rte_memcpy(&fdir_rule,
2758                         &fdir_rule_ptr->filter_info,
2759                         sizeof(struct ixgbe_fdir_rule));
2760                 ret = ixgbe_fdir_filter_program(dev, &fdir_rule, TRUE, FALSE);
2761                 if (!ret) {
2762                         TAILQ_REMOVE(&filter_fdir_list,
2763                                 fdir_rule_ptr, entries);
2764                         rte_free(fdir_rule_ptr);
2765                         if (TAILQ_EMPTY(&filter_fdir_list))
2766                                 fdir_info->mask_added = false;
2767                 }
2768                 break;
2769         case RTE_ETH_FILTER_L2_TUNNEL:
2770                 l2_tn_filter_ptr = (struct ixgbe_eth_l2_tunnel_conf_ele *)
2771                                 pmd_flow->rule;
2772                 (void)rte_memcpy(&l2_tn_filter, &l2_tn_filter_ptr->filter_info,
2773                         sizeof(struct rte_eth_l2_tunnel_conf));
2774                 ret = ixgbe_dev_l2_tunnel_filter_del(dev, &l2_tn_filter);
2775                 if (!ret) {
2776                         TAILQ_REMOVE(&filter_l2_tunnel_list,
2777                                 l2_tn_filter_ptr, entries);
2778                         rte_free(l2_tn_filter_ptr);
2779                 }
2780                 break;
2781         default:
2782                 PMD_DRV_LOG(WARNING, "Filter type (%d) not supported",
2783                             filter_type);
2784                 ret = -EINVAL;
2785                 break;
2786         }
2787
2788         if (ret) {
2789                 rte_flow_error_set(error, EINVAL,
2790                                 RTE_FLOW_ERROR_TYPE_HANDLE,
2791                                 NULL, "Failed to destroy flow");
2792                 return ret;
2793         }
2794
2795         TAILQ_FOREACH(ixgbe_flow_mem_ptr, &ixgbe_flow_list, entries) {
2796                 if (ixgbe_flow_mem_ptr->flow == pmd_flow) {
2797                         TAILQ_REMOVE(&ixgbe_flow_list,
2798                                 ixgbe_flow_mem_ptr, entries);
2799                         rte_free(ixgbe_flow_mem_ptr);
2800                 }
2801         }
2802         rte_free(flow);
2803
2804         return ret;
2805 }
2806
2807 /*  Destroy all flow rules associated with a port on ixgbe. */
2808 static int
2809 ixgbe_flow_flush(struct rte_eth_dev *dev,
2810                 struct rte_flow_error *error)
2811 {
2812         int ret = 0;
2813
2814         ixgbe_clear_all_ntuple_filter(dev);
2815         ixgbe_clear_all_ethertype_filter(dev);
2816         ixgbe_clear_syn_filter(dev);
2817
2818         ret = ixgbe_clear_all_fdir_filter(dev);
2819         if (ret < 0) {
2820                 rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_HANDLE,
2821                                         NULL, "Failed to flush rule");
2822                 return ret;
2823         }
2824
2825         ret = ixgbe_clear_all_l2_tn_filter(dev);
2826         if (ret < 0) {
2827                 rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_HANDLE,
2828                                         NULL, "Failed to flush rule");
2829                 return ret;
2830         }
2831
2832         ixgbe_filterlist_flush();
2833
2834         return 0;
2835 }
2836
2837 const struct rte_flow_ops ixgbe_flow_ops = {
2838         .validate = ixgbe_flow_validate,
2839         .create = ixgbe_flow_create,
2840         .destroy = ixgbe_flow_destroy,
2841         .flush = ixgbe_flow_flush,
2842 };