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