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