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