xref: /dpdk/drivers/net/e1000/igb_flow.c (revision c7e9729d)
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2010-2016 Intel Corporation
3  */
4 
5 #include <sys/queue.h>
6 #include <stdio.h>
7 #include <errno.h>
8 #include <stdint.h>
9 #include <stdarg.h>
10 
11 #include <rte_common.h>
12 #include <rte_interrupts.h>
13 #include <rte_byteorder.h>
14 #include <rte_log.h>
15 #include <rte_debug.h>
16 #include <rte_pci.h>
17 #include <rte_ether.h>
18 #include <rte_ethdev_driver.h>
19 #include <rte_ethdev_pci.h>
20 #include <rte_memory.h>
21 #include <rte_eal.h>
22 #include <rte_atomic.h>
23 #include <rte_malloc.h>
24 #include <rte_dev.h>
25 #include <rte_flow.h>
26 #include <rte_flow_driver.h>
27 
28 #include "e1000_logs.h"
29 #include "base/e1000_api.h"
30 #include "e1000_ethdev.h"
31 
32 #define NEXT_ITEM_OF_PATTERN(item, pattern, index)		\
33 	do {							\
34 		item = (pattern) + (index);			\
35 		while (item->type == RTE_FLOW_ITEM_TYPE_VOID) {	\
36 		(index)++;					\
37 		item = (pattern) + (index);			\
38 		}						\
39 	} while (0)
40 
41 #define NEXT_ITEM_OF_ACTION(act, actions, index)		\
42 	do {							\
43 		act = (actions) + (index);			\
44 		while (act->type == RTE_FLOW_ACTION_TYPE_VOID) {\
45 		(index)++;					\
46 		act = (actions) + (index);			\
47 		}						\
48 	} while (0)
49 
50 #define	IGB_FLEX_RAW_NUM	12
51 
52 /**
53  * Please aware there's an asumption for all the parsers.
54  * rte_flow_item is using big endian, rte_flow_attr and
55  * rte_flow_action are using CPU order.
56  * Because the pattern is used to describe the packets,
57  * normally the packets should use network order.
58  */
59 
60 /**
61  * Parse the rule to see if it is a n-tuple rule.
62  * And get the n-tuple filter info BTW.
63  * pattern:
64  * The first not void item can be ETH or IPV4.
65  * The second not void item must be IPV4 if the first one is ETH.
66  * The third not void item must be UDP or TCP or SCTP
67  * The next not void item must be END.
68  * action:
69  * The first not void action should be QUEUE.
70  * The next not void action should be END.
71  * pattern example:
72  * ITEM		Spec			Mask
73  * ETH		NULL			NULL
74  * IPV4		src_addr 192.168.1.20	0xFFFFFFFF
75  *			dst_addr 192.167.3.50	0xFFFFFFFF
76  *			next_proto_id	17	0xFF
77  * UDP/TCP/	src_port	80	0xFFFF
78  * SCTP		dst_port	80	0xFFFF
79  * END
80  * other members in mask and spec should set to 0x00.
81  * item->last should be NULL.
82  */
83 static int
84 cons_parse_ntuple_filter(const struct rte_flow_attr *attr,
85 			 const struct rte_flow_item pattern[],
86 			 const struct rte_flow_action actions[],
87 			 struct rte_eth_ntuple_filter *filter,
88 			 struct rte_flow_error *error)
89 {
90 	const struct rte_flow_item *item;
91 	const struct rte_flow_action *act;
92 	const struct rte_flow_item_ipv4 *ipv4_spec;
93 	const struct rte_flow_item_ipv4 *ipv4_mask;
94 	const struct rte_flow_item_tcp *tcp_spec;
95 	const struct rte_flow_item_tcp *tcp_mask;
96 	const struct rte_flow_item_udp *udp_spec;
97 	const struct rte_flow_item_udp *udp_mask;
98 	const struct rte_flow_item_sctp *sctp_spec;
99 	const struct rte_flow_item_sctp *sctp_mask;
100 	uint32_t index;
101 
102 	if (!pattern) {
103 		rte_flow_error_set(error,
104 			EINVAL, RTE_FLOW_ERROR_TYPE_ITEM_NUM,
105 			NULL, "NULL pattern.");
106 		return -rte_errno;
107 	}
108 
109 	if (!actions) {
110 		rte_flow_error_set(error, EINVAL,
111 				   RTE_FLOW_ERROR_TYPE_ACTION_NUM,
112 				   NULL, "NULL action.");
113 		return -rte_errno;
114 	}
115 	if (!attr) {
116 		rte_flow_error_set(error, EINVAL,
117 				   RTE_FLOW_ERROR_TYPE_ATTR,
118 				   NULL, "NULL attribute.");
119 		return -rte_errno;
120 	}
121 
122 	/* parse pattern */
123 	index = 0;
124 
125 	/* the first not void item can be MAC or IPv4 */
126 	NEXT_ITEM_OF_PATTERN(item, pattern, index);
127 
128 	if (item->type != RTE_FLOW_ITEM_TYPE_ETH &&
129 	    item->type != RTE_FLOW_ITEM_TYPE_IPV4) {
130 		rte_flow_error_set(error, EINVAL,
131 			RTE_FLOW_ERROR_TYPE_ITEM,
132 			item, "Not supported by ntuple filter");
133 		return -rte_errno;
134 	}
135 	/* Skip Ethernet */
136 	if (item->type == RTE_FLOW_ITEM_TYPE_ETH) {
137 		/*Not supported last point for range*/
138 		if (item->last) {
139 			rte_flow_error_set(error,
140 			  EINVAL,
141 			  RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
142 			  item, "Not supported last point for range");
143 			return -rte_errno;
144 		}
145 		/* if the first item is MAC, the content should be NULL */
146 		if (item->spec || item->mask) {
147 			rte_flow_error_set(error, EINVAL,
148 				RTE_FLOW_ERROR_TYPE_ITEM,
149 				item, "Not supported by ntuple filter");
150 			return -rte_errno;
151 		}
152 		/* check if the next not void item is IPv4 */
153 		index++;
154 		NEXT_ITEM_OF_PATTERN(item, pattern, index);
155 		if (item->type != RTE_FLOW_ITEM_TYPE_IPV4) {
156 			rte_flow_error_set(error,
157 			  EINVAL, RTE_FLOW_ERROR_TYPE_ITEM,
158 			  item, "Not supported by ntuple filter");
159 			return -rte_errno;
160 		}
161 	}
162 
163 	/* get the IPv4 info */
164 	if (!item->spec || !item->mask) {
165 		rte_flow_error_set(error, EINVAL,
166 			RTE_FLOW_ERROR_TYPE_ITEM,
167 			item, "Invalid ntuple mask");
168 		return -rte_errno;
169 	}
170 	/* Not supported last point for range */
171 	if (item->last) {
172 		rte_flow_error_set(error, EINVAL,
173 			RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
174 			item, "Not supported last point for range");
175 		return -rte_errno;
176 	}
177 
178 	ipv4_mask = item->mask;
179 	/**
180 	 * Only support src & dst addresses, protocol,
181 	 * others should be masked.
182 	 */
183 
184 	if (ipv4_mask->hdr.version_ihl ||
185 		ipv4_mask->hdr.type_of_service ||
186 		ipv4_mask->hdr.total_length ||
187 		ipv4_mask->hdr.packet_id ||
188 		ipv4_mask->hdr.fragment_offset ||
189 		ipv4_mask->hdr.time_to_live ||
190 		ipv4_mask->hdr.hdr_checksum) {
191 		rte_flow_error_set(error,
192 			EINVAL, RTE_FLOW_ERROR_TYPE_ITEM,
193 			item, "Not supported by ntuple filter");
194 		return -rte_errno;
195 	}
196 
197 	filter->dst_ip_mask = ipv4_mask->hdr.dst_addr;
198 	filter->src_ip_mask = ipv4_mask->hdr.src_addr;
199 	filter->proto_mask  = ipv4_mask->hdr.next_proto_id;
200 
201 	ipv4_spec = item->spec;
202 	filter->dst_ip = ipv4_spec->hdr.dst_addr;
203 	filter->src_ip = ipv4_spec->hdr.src_addr;
204 	filter->proto  = ipv4_spec->hdr.next_proto_id;
205 
206 	/* check if the next not void item is TCP or UDP or SCTP */
207 	index++;
208 	NEXT_ITEM_OF_PATTERN(item, pattern, index);
209 	if (item->type != RTE_FLOW_ITEM_TYPE_TCP &&
210 	    item->type != RTE_FLOW_ITEM_TYPE_UDP &&
211 	    item->type != RTE_FLOW_ITEM_TYPE_SCTP) {
212 		memset(filter, 0, sizeof(struct rte_eth_ntuple_filter));
213 		rte_flow_error_set(error, EINVAL,
214 			RTE_FLOW_ERROR_TYPE_ITEM,
215 			item, "Not supported by ntuple filter");
216 		return -rte_errno;
217 	}
218 
219 	/* Not supported last point for range */
220 	if (item->last) {
221 		memset(filter, 0, sizeof(struct rte_eth_ntuple_filter));
222 		rte_flow_error_set(error, EINVAL,
223 			RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
224 			item, "Not supported last point for range");
225 		return -rte_errno;
226 	}
227 
228 	/* get the TCP/UDP/SCTP info */
229 	if (item->type == RTE_FLOW_ITEM_TYPE_TCP) {
230 		if (item->spec && item->mask) {
231 			tcp_mask = item->mask;
232 
233 			/**
234 			 * Only support src & dst ports, tcp flags,
235 			 * others should be masked.
236 			 */
237 			if (tcp_mask->hdr.sent_seq ||
238 				tcp_mask->hdr.recv_ack ||
239 				tcp_mask->hdr.data_off ||
240 				tcp_mask->hdr.rx_win ||
241 				tcp_mask->hdr.cksum ||
242 				tcp_mask->hdr.tcp_urp) {
243 				memset(filter, 0,
244 					sizeof(struct rte_eth_ntuple_filter));
245 				rte_flow_error_set(error, EINVAL,
246 					RTE_FLOW_ERROR_TYPE_ITEM,
247 					item, "Not supported by ntuple filter");
248 				return -rte_errno;
249 			}
250 
251 			filter->dst_port_mask  = tcp_mask->hdr.dst_port;
252 			filter->src_port_mask  = tcp_mask->hdr.src_port;
253 			if (tcp_mask->hdr.tcp_flags == 0xFF) {
254 				filter->flags |= RTE_NTUPLE_FLAGS_TCP_FLAG;
255 			} else if (!tcp_mask->hdr.tcp_flags) {
256 				filter->flags &= ~RTE_NTUPLE_FLAGS_TCP_FLAG;
257 			} else {
258 				memset(filter, 0,
259 					sizeof(struct rte_eth_ntuple_filter));
260 				rte_flow_error_set(error, EINVAL,
261 					RTE_FLOW_ERROR_TYPE_ITEM,
262 					item, "Not supported by ntuple filter");
263 				return -rte_errno;
264 			}
265 
266 			tcp_spec = item->spec;
267 			filter->dst_port  = tcp_spec->hdr.dst_port;
268 			filter->src_port  = tcp_spec->hdr.src_port;
269 			filter->tcp_flags = tcp_spec->hdr.tcp_flags;
270 		}
271 	} else if (item->type == RTE_FLOW_ITEM_TYPE_UDP) {
272 		if (item->spec && item->mask) {
273 			udp_mask = item->mask;
274 
275 			/**
276 			 * Only support src & dst ports,
277 			 * others should be masked.
278 			 */
279 			if (udp_mask->hdr.dgram_len ||
280 			    udp_mask->hdr.dgram_cksum) {
281 				memset(filter, 0,
282 					sizeof(struct rte_eth_ntuple_filter));
283 				rte_flow_error_set(error, EINVAL,
284 					RTE_FLOW_ERROR_TYPE_ITEM,
285 					item, "Not supported by ntuple filter");
286 				return -rte_errno;
287 			}
288 
289 			filter->dst_port_mask = udp_mask->hdr.dst_port;
290 			filter->src_port_mask = udp_mask->hdr.src_port;
291 
292 			udp_spec = item->spec;
293 			filter->dst_port = udp_spec->hdr.dst_port;
294 			filter->src_port = udp_spec->hdr.src_port;
295 		}
296 	} else {
297 		if (item->spec && item->mask) {
298 			sctp_mask = item->mask;
299 
300 			/**
301 			 * Only support src & dst ports,
302 			 * others should be masked.
303 			 */
304 			if (sctp_mask->hdr.tag ||
305 			    sctp_mask->hdr.cksum) {
306 				memset(filter, 0,
307 					sizeof(struct rte_eth_ntuple_filter));
308 				rte_flow_error_set(error, EINVAL,
309 					RTE_FLOW_ERROR_TYPE_ITEM,
310 					item, "Not supported by ntuple filter");
311 				return -rte_errno;
312 			}
313 
314 			filter->dst_port_mask = sctp_mask->hdr.dst_port;
315 			filter->src_port_mask = sctp_mask->hdr.src_port;
316 
317 			sctp_spec = (const struct rte_flow_item_sctp *)
318 					item->spec;
319 			filter->dst_port = sctp_spec->hdr.dst_port;
320 			filter->src_port = sctp_spec->hdr.src_port;
321 		}
322 	}
323 	/* check if the next not void item is END */
324 	index++;
325 	NEXT_ITEM_OF_PATTERN(item, pattern, index);
326 	if (item->type != RTE_FLOW_ITEM_TYPE_END) {
327 		memset(filter, 0, sizeof(struct rte_eth_ntuple_filter));
328 		rte_flow_error_set(error, EINVAL,
329 			RTE_FLOW_ERROR_TYPE_ITEM,
330 			item, "Not supported by ntuple filter");
331 		return -rte_errno;
332 	}
333 
334 	/* parse action */
335 	index = 0;
336 
337 	/**
338 	 * n-tuple only supports forwarding,
339 	 * check if the first not void action is QUEUE.
340 	 */
341 	NEXT_ITEM_OF_ACTION(act, actions, index);
342 	if (act->type != RTE_FLOW_ACTION_TYPE_QUEUE) {
343 		memset(filter, 0, sizeof(struct rte_eth_ntuple_filter));
344 		rte_flow_error_set(error, EINVAL,
345 			RTE_FLOW_ERROR_TYPE_ACTION,
346 			item, "Not supported action.");
347 		return -rte_errno;
348 	}
349 	filter->queue =
350 		((const struct rte_flow_action_queue *)act->conf)->index;
351 
352 	/* check if the next not void item is END */
353 	index++;
354 	NEXT_ITEM_OF_ACTION(act, actions, index);
355 	if (act->type != RTE_FLOW_ACTION_TYPE_END) {
356 		memset(filter, 0, sizeof(struct rte_eth_ntuple_filter));
357 		rte_flow_error_set(error, EINVAL,
358 			RTE_FLOW_ERROR_TYPE_ACTION,
359 			act, "Not supported action.");
360 		return -rte_errno;
361 	}
362 
363 	/* parse attr */
364 	/* must be input direction */
365 	if (!attr->ingress) {
366 		memset(filter, 0, sizeof(struct rte_eth_ntuple_filter));
367 		rte_flow_error_set(error, EINVAL,
368 				   RTE_FLOW_ERROR_TYPE_ATTR_INGRESS,
369 				   attr, "Only support ingress.");
370 		return -rte_errno;
371 	}
372 
373 	/* not supported */
374 	if (attr->egress) {
375 		memset(filter, 0, sizeof(struct rte_eth_ntuple_filter));
376 		rte_flow_error_set(error, EINVAL,
377 				   RTE_FLOW_ERROR_TYPE_ATTR_EGRESS,
378 				   attr, "Not support egress.");
379 		return -rte_errno;
380 	}
381 
382 	if (attr->priority > 0xFFFF) {
383 		memset(filter, 0, sizeof(struct rte_eth_ntuple_filter));
384 		rte_flow_error_set(error, EINVAL,
385 				   RTE_FLOW_ERROR_TYPE_ATTR_PRIORITY,
386 				   attr, "Error priority.");
387 		return -rte_errno;
388 	}
389 	filter->priority = (uint16_t)attr->priority;
390 
391 	return 0;
392 }
393 
394 /* a specific function for igb because the flags is specific */
395 static int
396 igb_parse_ntuple_filter(struct rte_eth_dev *dev,
397 			  const struct rte_flow_attr *attr,
398 			  const struct rte_flow_item pattern[],
399 			  const struct rte_flow_action actions[],
400 			  struct rte_eth_ntuple_filter *filter,
401 			  struct rte_flow_error *error)
402 {
403 	struct e1000_hw *hw = E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);
404 	int ret;
405 
406 	MAC_TYPE_FILTER_SUP(hw->mac.type);
407 
408 	ret = cons_parse_ntuple_filter(attr, pattern, actions, filter, error);
409 
410 	if (ret)
411 		return ret;
412 
413 	/* Igb doesn't support many priorities. */
414 	if (filter->priority > E1000_2TUPLE_MAX_PRI) {
415 		memset(filter, 0, sizeof(struct rte_eth_ntuple_filter));
416 		rte_flow_error_set(error, EINVAL,
417 			RTE_FLOW_ERROR_TYPE_ITEM,
418 			NULL, "Priority not supported by ntuple filter");
419 		return -rte_errno;
420 	}
421 
422 	if (hw->mac.type == e1000_82576) {
423 		if (filter->queue >= IGB_MAX_RX_QUEUE_NUM_82576) {
424 			memset(filter, 0, sizeof(struct rte_eth_ntuple_filter));
425 			rte_flow_error_set(error, EINVAL,
426 				RTE_FLOW_ERROR_TYPE_ITEM,
427 				NULL, "queue number not "
428 				"supported by ntuple filter");
429 			return -rte_errno;
430 		}
431 		filter->flags |= RTE_5TUPLE_FLAGS;
432 	} else {
433 		if (filter->src_ip_mask || filter->dst_ip_mask ||
434 			filter->src_port_mask) {
435 			memset(filter, 0, sizeof(struct rte_eth_ntuple_filter));
436 			rte_flow_error_set(error, EINVAL,
437 				RTE_FLOW_ERROR_TYPE_ITEM,
438 				NULL, "only two tuple are "
439 				"supported by this filter");
440 			return -rte_errno;
441 		}
442 		if (filter->queue >= IGB_MAX_RX_QUEUE_NUM) {
443 			memset(filter, 0, sizeof(struct rte_eth_ntuple_filter));
444 			rte_flow_error_set(error, EINVAL,
445 				RTE_FLOW_ERROR_TYPE_ITEM,
446 				NULL, "queue number not "
447 				"supported by ntuple filter");
448 			return -rte_errno;
449 		}
450 		filter->flags |= RTE_2TUPLE_FLAGS;
451 	}
452 
453 	return 0;
454 }
455 
456 /**
457  * Parse the rule to see if it is a ethertype rule.
458  * And get the ethertype filter info BTW.
459  * pattern:
460  * The first not void item can be ETH.
461  * The next not void item must be END.
462  * action:
463  * The first not void action should be QUEUE.
464  * The next not void action should be END.
465  * pattern example:
466  * ITEM		Spec			Mask
467  * ETH		type	0x0807		0xFFFF
468  * END
469  * other members in mask and spec should set to 0x00.
470  * item->last should be NULL.
471  */
472 static int
473 cons_parse_ethertype_filter(const struct rte_flow_attr *attr,
474 			    const struct rte_flow_item *pattern,
475 			    const struct rte_flow_action *actions,
476 			    struct rte_eth_ethertype_filter *filter,
477 			    struct rte_flow_error *error)
478 {
479 	const struct rte_flow_item *item;
480 	const struct rte_flow_action *act;
481 	const struct rte_flow_item_eth *eth_spec;
482 	const struct rte_flow_item_eth *eth_mask;
483 	const struct rte_flow_action_queue *act_q;
484 	uint32_t index;
485 
486 	if (!pattern) {
487 		rte_flow_error_set(error, EINVAL,
488 				RTE_FLOW_ERROR_TYPE_ITEM_NUM,
489 				NULL, "NULL pattern.");
490 		return -rte_errno;
491 	}
492 
493 	if (!actions) {
494 		rte_flow_error_set(error, EINVAL,
495 				RTE_FLOW_ERROR_TYPE_ACTION_NUM,
496 				NULL, "NULL action.");
497 		return -rte_errno;
498 	}
499 
500 	if (!attr) {
501 		rte_flow_error_set(error, EINVAL,
502 				   RTE_FLOW_ERROR_TYPE_ATTR,
503 				   NULL, "NULL attribute.");
504 		return -rte_errno;
505 	}
506 
507 	/* Parse pattern */
508 	index = 0;
509 
510 	/* The first non-void item should be MAC. */
511 	NEXT_ITEM_OF_PATTERN(item, pattern, index);
512 	if (item->type != RTE_FLOW_ITEM_TYPE_ETH) {
513 		rte_flow_error_set(error, EINVAL,
514 			RTE_FLOW_ERROR_TYPE_ITEM,
515 			item, "Not supported by ethertype filter");
516 		return -rte_errno;
517 	}
518 
519 	/*Not supported last point for range*/
520 	if (item->last) {
521 		rte_flow_error_set(error, EINVAL,
522 			RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
523 			item, "Not supported last point for range");
524 		return -rte_errno;
525 	}
526 
527 	/* Get the MAC info. */
528 	if (!item->spec || !item->mask) {
529 		rte_flow_error_set(error, EINVAL,
530 				RTE_FLOW_ERROR_TYPE_ITEM,
531 				item, "Not supported by ethertype filter");
532 		return -rte_errno;
533 	}
534 
535 	eth_spec = item->spec;
536 	eth_mask = item->mask;
537 
538 	/* Mask bits of source MAC address must be full of 0.
539 	 * Mask bits of destination MAC address must be full
540 	 * of 1 or full of 0.
541 	 */
542 	if (!is_zero_ether_addr(&eth_mask->src) ||
543 	    (!is_zero_ether_addr(&eth_mask->dst) &&
544 	     !is_broadcast_ether_addr(&eth_mask->dst))) {
545 		rte_flow_error_set(error, EINVAL,
546 				RTE_FLOW_ERROR_TYPE_ITEM,
547 				item, "Invalid ether address mask");
548 		return -rte_errno;
549 	}
550 
551 	if ((eth_mask->type & UINT16_MAX) != UINT16_MAX) {
552 		rte_flow_error_set(error, EINVAL,
553 				RTE_FLOW_ERROR_TYPE_ITEM,
554 				item, "Invalid ethertype mask");
555 		return -rte_errno;
556 	}
557 
558 	/* If mask bits of destination MAC address
559 	 * are full of 1, set RTE_ETHTYPE_FLAGS_MAC.
560 	 */
561 	if (is_broadcast_ether_addr(&eth_mask->dst)) {
562 		filter->mac_addr = eth_spec->dst;
563 		filter->flags |= RTE_ETHTYPE_FLAGS_MAC;
564 	} else {
565 		filter->flags &= ~RTE_ETHTYPE_FLAGS_MAC;
566 	}
567 	filter->ether_type = rte_be_to_cpu_16(eth_spec->type);
568 
569 	/* Check if the next non-void item is END. */
570 	index++;
571 	NEXT_ITEM_OF_PATTERN(item, pattern, index);
572 	if (item->type != RTE_FLOW_ITEM_TYPE_END) {
573 		rte_flow_error_set(error, EINVAL,
574 				RTE_FLOW_ERROR_TYPE_ITEM,
575 				item, "Not supported by ethertype filter.");
576 		return -rte_errno;
577 	}
578 
579 	/* Parse action */
580 
581 	index = 0;
582 	/* Check if the first non-void action is QUEUE or DROP. */
583 	NEXT_ITEM_OF_ACTION(act, actions, index);
584 	if (act->type != RTE_FLOW_ACTION_TYPE_QUEUE &&
585 	    act->type != RTE_FLOW_ACTION_TYPE_DROP) {
586 		rte_flow_error_set(error, EINVAL,
587 				RTE_FLOW_ERROR_TYPE_ACTION,
588 				act, "Not supported action.");
589 		return -rte_errno;
590 	}
591 
592 	if (act->type == RTE_FLOW_ACTION_TYPE_QUEUE) {
593 		act_q = (const struct rte_flow_action_queue *)act->conf;
594 		filter->queue = act_q->index;
595 	} else {
596 		filter->flags |= RTE_ETHTYPE_FLAGS_DROP;
597 	}
598 
599 	/* Check if the next non-void item is END */
600 	index++;
601 	NEXT_ITEM_OF_ACTION(act, actions, index);
602 	if (act->type != RTE_FLOW_ACTION_TYPE_END) {
603 		rte_flow_error_set(error, EINVAL,
604 				RTE_FLOW_ERROR_TYPE_ACTION,
605 				act, "Not supported action.");
606 		return -rte_errno;
607 	}
608 
609 	/* Parse attr */
610 	/* Must be input direction */
611 	if (!attr->ingress) {
612 		rte_flow_error_set(error, EINVAL,
613 				RTE_FLOW_ERROR_TYPE_ATTR_INGRESS,
614 				attr, "Only support ingress.");
615 		return -rte_errno;
616 	}
617 
618 	/* Not supported */
619 	if (attr->egress) {
620 		rte_flow_error_set(error, EINVAL,
621 				RTE_FLOW_ERROR_TYPE_ATTR_EGRESS,
622 				attr, "Not support egress.");
623 		return -rte_errno;
624 	}
625 
626 	/* Not supported */
627 	if (attr->priority) {
628 		rte_flow_error_set(error, EINVAL,
629 				RTE_FLOW_ERROR_TYPE_ATTR_PRIORITY,
630 				attr, "Not support priority.");
631 		return -rte_errno;
632 	}
633 
634 	/* Not supported */
635 	if (attr->group) {
636 		rte_flow_error_set(error, EINVAL,
637 				RTE_FLOW_ERROR_TYPE_ATTR_GROUP,
638 				attr, "Not support group.");
639 		return -rte_errno;
640 	}
641 
642 	return 0;
643 }
644 
645 static int
646 igb_parse_ethertype_filter(struct rte_eth_dev *dev,
647 				 const struct rte_flow_attr *attr,
648 			     const struct rte_flow_item pattern[],
649 			     const struct rte_flow_action actions[],
650 			     struct rte_eth_ethertype_filter *filter,
651 			     struct rte_flow_error *error)
652 {
653 	struct e1000_hw *hw = E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);
654 	int ret;
655 
656 	MAC_TYPE_FILTER_SUP(hw->mac.type);
657 
658 	ret = cons_parse_ethertype_filter(attr, pattern,
659 					actions, filter, error);
660 
661 	if (ret)
662 		return ret;
663 
664 	if (hw->mac.type == e1000_82576) {
665 		if (filter->queue >= IGB_MAX_RX_QUEUE_NUM_82576) {
666 			memset(filter, 0, sizeof(
667 					struct rte_eth_ethertype_filter));
668 			rte_flow_error_set(error, EINVAL,
669 				RTE_FLOW_ERROR_TYPE_ITEM,
670 				NULL, "queue number not supported "
671 					"by ethertype filter");
672 			return -rte_errno;
673 		}
674 	} else {
675 		if (filter->queue >= IGB_MAX_RX_QUEUE_NUM) {
676 			memset(filter, 0, sizeof(
677 					struct rte_eth_ethertype_filter));
678 			rte_flow_error_set(error, EINVAL,
679 				RTE_FLOW_ERROR_TYPE_ITEM,
680 				NULL, "queue number not supported "
681 					"by ethertype filter");
682 			return -rte_errno;
683 		}
684 	}
685 
686 	if (filter->ether_type == ETHER_TYPE_IPv4 ||
687 		filter->ether_type == ETHER_TYPE_IPv6) {
688 		memset(filter, 0, sizeof(struct rte_eth_ethertype_filter));
689 		rte_flow_error_set(error, EINVAL,
690 			RTE_FLOW_ERROR_TYPE_ITEM,
691 			NULL, "IPv4/IPv6 not supported by ethertype filter");
692 		return -rte_errno;
693 	}
694 
695 	if (filter->flags & RTE_ETHTYPE_FLAGS_MAC) {
696 		memset(filter, 0, sizeof(struct rte_eth_ethertype_filter));
697 		rte_flow_error_set(error, EINVAL,
698 			RTE_FLOW_ERROR_TYPE_ITEM,
699 			NULL, "mac compare is unsupported");
700 		return -rte_errno;
701 	}
702 
703 	if (filter->flags & RTE_ETHTYPE_FLAGS_DROP) {
704 		memset(filter, 0, sizeof(struct rte_eth_ethertype_filter));
705 		rte_flow_error_set(error, EINVAL,
706 			RTE_FLOW_ERROR_TYPE_ITEM,
707 			NULL, "drop option is unsupported");
708 		return -rte_errno;
709 	}
710 
711 	return 0;
712 }
713 
714 /**
715  * Parse the rule to see if it is a TCP SYN rule.
716  * And get the TCP SYN filter info BTW.
717  * pattern:
718  * The first not void item must be ETH.
719  * The second not void item must be IPV4 or IPV6.
720  * The third not void item must be TCP.
721  * The next not void item must be END.
722  * action:
723  * The first not void action should be QUEUE.
724  * The next not void action should be END.
725  * pattern example:
726  * ITEM		Spec			Mask
727  * ETH		NULL			NULL
728  * IPV4/IPV6	NULL			NULL
729  * TCP		tcp_flags	0x02	0xFF
730  * END
731  * other members in mask and spec should set to 0x00.
732  * item->last should be NULL.
733  */
734 static int
735 cons_parse_syn_filter(const struct rte_flow_attr *attr,
736 				const struct rte_flow_item pattern[],
737 				const struct rte_flow_action actions[],
738 				struct rte_eth_syn_filter *filter,
739 				struct rte_flow_error *error)
740 {
741 	const struct rte_flow_item *item;
742 	const struct rte_flow_action *act;
743 	const struct rte_flow_item_tcp *tcp_spec;
744 	const struct rte_flow_item_tcp *tcp_mask;
745 	const struct rte_flow_action_queue *act_q;
746 	uint32_t index;
747 
748 	if (!pattern) {
749 		rte_flow_error_set(error, EINVAL,
750 				RTE_FLOW_ERROR_TYPE_ITEM_NUM,
751 				NULL, "NULL pattern.");
752 		return -rte_errno;
753 	}
754 
755 	if (!actions) {
756 		rte_flow_error_set(error, EINVAL,
757 				RTE_FLOW_ERROR_TYPE_ACTION_NUM,
758 				NULL, "NULL action.");
759 		return -rte_errno;
760 	}
761 
762 	if (!attr) {
763 		rte_flow_error_set(error, EINVAL,
764 				   RTE_FLOW_ERROR_TYPE_ATTR,
765 				   NULL, "NULL attribute.");
766 		return -rte_errno;
767 	}
768 
769 	/* parse pattern */
770 	index = 0;
771 
772 	/* the first not void item should be MAC or IPv4 or IPv6 or TCP */
773 	NEXT_ITEM_OF_PATTERN(item, pattern, index);
774 	if (item->type != RTE_FLOW_ITEM_TYPE_ETH &&
775 	    item->type != RTE_FLOW_ITEM_TYPE_IPV4 &&
776 	    item->type != RTE_FLOW_ITEM_TYPE_IPV6 &&
777 	    item->type != RTE_FLOW_ITEM_TYPE_TCP) {
778 		rte_flow_error_set(error, EINVAL,
779 				RTE_FLOW_ERROR_TYPE_ITEM,
780 				item, "Not supported by syn filter");
781 		return -rte_errno;
782 	}
783 		/*Not supported last point for range*/
784 	if (item->last) {
785 		rte_flow_error_set(error, EINVAL,
786 			RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
787 			item, "Not supported last point for range");
788 		return -rte_errno;
789 	}
790 
791 	/* Skip Ethernet */
792 	if (item->type == RTE_FLOW_ITEM_TYPE_ETH) {
793 		/* if the item is MAC, the content should be NULL */
794 		if (item->spec || item->mask) {
795 			rte_flow_error_set(error, EINVAL,
796 				RTE_FLOW_ERROR_TYPE_ITEM,
797 				item, "Invalid SYN address mask");
798 			return -rte_errno;
799 		}
800 
801 		/* check if the next not void item is IPv4 or IPv6 */
802 		index++;
803 		NEXT_ITEM_OF_PATTERN(item, pattern, index);
804 		if (item->type != RTE_FLOW_ITEM_TYPE_IPV4 &&
805 		    item->type != RTE_FLOW_ITEM_TYPE_IPV6) {
806 			rte_flow_error_set(error, EINVAL,
807 				RTE_FLOW_ERROR_TYPE_ITEM,
808 				item, "Not supported by syn filter");
809 			return -rte_errno;
810 		}
811 	}
812 
813 	/* Skip IP */
814 	if (item->type == RTE_FLOW_ITEM_TYPE_IPV4 ||
815 	    item->type == RTE_FLOW_ITEM_TYPE_IPV6) {
816 		/* if the item is IP, the content should be NULL */
817 		if (item->spec || item->mask) {
818 			rte_flow_error_set(error, EINVAL,
819 				RTE_FLOW_ERROR_TYPE_ITEM,
820 				item, "Invalid SYN mask");
821 			return -rte_errno;
822 		}
823 
824 		/* check if the next not void item is TCP */
825 		index++;
826 		NEXT_ITEM_OF_PATTERN(item, pattern, index);
827 		if (item->type != RTE_FLOW_ITEM_TYPE_TCP) {
828 			rte_flow_error_set(error, EINVAL,
829 				RTE_FLOW_ERROR_TYPE_ITEM,
830 				item, "Not supported by syn filter");
831 			return -rte_errno;
832 		}
833 	}
834 
835 	/* Get the TCP info. Only support SYN. */
836 	if (!item->spec || !item->mask) {
837 		rte_flow_error_set(error, EINVAL,
838 				RTE_FLOW_ERROR_TYPE_ITEM,
839 				item, "Invalid SYN mask");
840 		return -rte_errno;
841 	}
842 	/*Not supported last point for range*/
843 	if (item->last) {
844 		rte_flow_error_set(error, EINVAL,
845 			RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
846 			item, "Not supported last point for range");
847 		return -rte_errno;
848 	}
849 
850 	tcp_spec = item->spec;
851 	tcp_mask = item->mask;
852 	if (!(tcp_spec->hdr.tcp_flags & TCP_SYN_FLAG) ||
853 	    tcp_mask->hdr.src_port ||
854 	    tcp_mask->hdr.dst_port ||
855 	    tcp_mask->hdr.sent_seq ||
856 	    tcp_mask->hdr.recv_ack ||
857 	    tcp_mask->hdr.data_off ||
858 	    tcp_mask->hdr.tcp_flags != TCP_SYN_FLAG ||
859 	    tcp_mask->hdr.rx_win ||
860 	    tcp_mask->hdr.cksum ||
861 	    tcp_mask->hdr.tcp_urp) {
862 		memset(filter, 0, sizeof(struct rte_eth_syn_filter));
863 		rte_flow_error_set(error, EINVAL,
864 				RTE_FLOW_ERROR_TYPE_ITEM,
865 				item, "Not supported by syn filter");
866 		return -rte_errno;
867 	}
868 
869 	/* check if the next not void item is END */
870 	index++;
871 	NEXT_ITEM_OF_PATTERN(item, pattern, index);
872 	if (item->type != RTE_FLOW_ITEM_TYPE_END) {
873 		memset(filter, 0, sizeof(struct rte_eth_syn_filter));
874 		rte_flow_error_set(error, EINVAL,
875 				RTE_FLOW_ERROR_TYPE_ITEM,
876 				item, "Not supported by syn filter");
877 		return -rte_errno;
878 	}
879 
880 	/* parse action */
881 	index = 0;
882 
883 	/* check if the first not void action is QUEUE. */
884 	NEXT_ITEM_OF_ACTION(act, actions, index);
885 	if (act->type != RTE_FLOW_ACTION_TYPE_QUEUE) {
886 		memset(filter, 0, sizeof(struct rte_eth_syn_filter));
887 		rte_flow_error_set(error, EINVAL,
888 				RTE_FLOW_ERROR_TYPE_ACTION,
889 				act, "Not supported action.");
890 		return -rte_errno;
891 	}
892 
893 	act_q = (const struct rte_flow_action_queue *)act->conf;
894 	filter->queue = act_q->index;
895 
896 	/* check if the next not void item is END */
897 	index++;
898 	NEXT_ITEM_OF_ACTION(act, actions, index);
899 	if (act->type != RTE_FLOW_ACTION_TYPE_END) {
900 		memset(filter, 0, sizeof(struct rte_eth_syn_filter));
901 		rte_flow_error_set(error, EINVAL,
902 				RTE_FLOW_ERROR_TYPE_ACTION,
903 				act, "Not supported action.");
904 		return -rte_errno;
905 	}
906 
907 	/* parse attr */
908 	/* must be input direction */
909 	if (!attr->ingress) {
910 		memset(filter, 0, sizeof(struct rte_eth_syn_filter));
911 		rte_flow_error_set(error, EINVAL,
912 			RTE_FLOW_ERROR_TYPE_ATTR_INGRESS,
913 			attr, "Only support ingress.");
914 		return -rte_errno;
915 	}
916 
917 	/* not supported */
918 	if (attr->egress) {
919 		memset(filter, 0, sizeof(struct rte_eth_syn_filter));
920 		rte_flow_error_set(error, EINVAL,
921 			RTE_FLOW_ERROR_TYPE_ATTR_EGRESS,
922 			attr, "Not support egress.");
923 		return -rte_errno;
924 	}
925 
926 	/* Support 2 priorities, the lowest or highest. */
927 	if (!attr->priority) {
928 		filter->hig_pri = 0;
929 	} else if (attr->priority == (uint32_t)~0U) {
930 		filter->hig_pri = 1;
931 	} else {
932 		memset(filter, 0, sizeof(struct rte_eth_syn_filter));
933 		rte_flow_error_set(error, EINVAL,
934 			RTE_FLOW_ERROR_TYPE_ATTR_PRIORITY,
935 			attr, "Not support priority.");
936 		return -rte_errno;
937 	}
938 
939 	return 0;
940 }
941 
942 static int
943 igb_parse_syn_filter(struct rte_eth_dev *dev,
944 				 const struct rte_flow_attr *attr,
945 			     const struct rte_flow_item pattern[],
946 			     const struct rte_flow_action actions[],
947 			     struct rte_eth_syn_filter *filter,
948 			     struct rte_flow_error *error)
949 {
950 	struct e1000_hw *hw = E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);
951 	int ret;
952 
953 	MAC_TYPE_FILTER_SUP(hw->mac.type);
954 
955 	ret = cons_parse_syn_filter(attr, pattern,
956 					actions, filter, error);
957 
958 	if (hw->mac.type == e1000_82576) {
959 		if (filter->queue >= IGB_MAX_RX_QUEUE_NUM_82576) {
960 			memset(filter, 0, sizeof(struct rte_eth_syn_filter));
961 			rte_flow_error_set(error, EINVAL,
962 				RTE_FLOW_ERROR_TYPE_ITEM,
963 				NULL, "queue number not "
964 					"supported by syn filter");
965 			return -rte_errno;
966 		}
967 	} else {
968 		if (filter->queue >= IGB_MAX_RX_QUEUE_NUM) {
969 			memset(filter, 0, sizeof(struct rte_eth_syn_filter));
970 			rte_flow_error_set(error, EINVAL,
971 				RTE_FLOW_ERROR_TYPE_ITEM,
972 				NULL, "queue number not "
973 					"supported by syn filter");
974 			return -rte_errno;
975 		}
976 	}
977 
978 	if (ret)
979 		return ret;
980 
981 	return 0;
982 }
983 
984 /**
985  * Parse the rule to see if it is a flex byte rule.
986  * And get the flex byte filter info BTW.
987  * pattern:
988  * The first not void item must be RAW.
989  * The second not void item can be RAW or END.
990  * The third not void item can be RAW or END.
991  * The last not void item must be END.
992  * action:
993  * The first not void action should be QUEUE.
994  * The next not void action should be END.
995  * pattern example:
996  * ITEM		Spec			Mask
997  * RAW		relative	0		0x1
998  *			offset	0		0xFFFFFFFF
999  *			pattern	{0x08, 0x06}		{0xFF, 0xFF}
1000  * RAW		relative	1		0x1
1001  *			offset	100		0xFFFFFFFF
1002  *			pattern	{0x11, 0x22, 0x33}	{0xFF, 0xFF, 0xFF}
1003  * END
1004  * other members in mask and spec should set to 0x00.
1005  * item->last should be NULL.
1006  */
1007 static int
1008 cons_parse_flex_filter(const struct rte_flow_attr *attr,
1009 				const struct rte_flow_item pattern[],
1010 				const struct rte_flow_action actions[],
1011 				struct rte_eth_flex_filter *filter,
1012 				struct rte_flow_error *error)
1013 {
1014 	const struct rte_flow_item *item;
1015 	const struct rte_flow_action *act;
1016 	const struct rte_flow_item_raw *raw_spec;
1017 	const struct rte_flow_item_raw *raw_mask;
1018 	const struct rte_flow_action_queue *act_q;
1019 	uint32_t index, i, offset, total_offset;
1020 	uint32_t max_offset = 0;
1021 	int32_t shift, j, raw_index = 0;
1022 	int32_t relative[IGB_FLEX_RAW_NUM] = {0};
1023 	int32_t	raw_offset[IGB_FLEX_RAW_NUM] = {0};
1024 
1025 	if (!pattern) {
1026 		rte_flow_error_set(error, EINVAL,
1027 				RTE_FLOW_ERROR_TYPE_ITEM_NUM,
1028 				NULL, "NULL pattern.");
1029 		return -rte_errno;
1030 	}
1031 
1032 	if (!actions) {
1033 		rte_flow_error_set(error, EINVAL,
1034 				RTE_FLOW_ERROR_TYPE_ACTION_NUM,
1035 				NULL, "NULL action.");
1036 		return -rte_errno;
1037 	}
1038 
1039 	if (!attr) {
1040 		rte_flow_error_set(error, EINVAL,
1041 				   RTE_FLOW_ERROR_TYPE_ATTR,
1042 				   NULL, "NULL attribute.");
1043 		return -rte_errno;
1044 	}
1045 
1046 	/* parse pattern */
1047 	index = 0;
1048 
1049 item_loop:
1050 
1051 	/* the first not void item should be RAW */
1052 	NEXT_ITEM_OF_PATTERN(item, pattern, index);
1053 	if (item->type != RTE_FLOW_ITEM_TYPE_RAW) {
1054 		rte_flow_error_set(error, EINVAL,
1055 				RTE_FLOW_ERROR_TYPE_ITEM,
1056 				item, "Not supported by flex filter");
1057 		return -rte_errno;
1058 	}
1059 		/*Not supported last point for range*/
1060 	if (item->last) {
1061 		rte_flow_error_set(error, EINVAL,
1062 			RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
1063 			item, "Not supported last point for range");
1064 		return -rte_errno;
1065 	}
1066 
1067 	raw_spec = item->spec;
1068 	raw_mask = item->mask;
1069 
1070 	if (!raw_mask->length ||
1071 	    !raw_mask->relative) {
1072 		memset(filter, 0, sizeof(struct rte_eth_flex_filter));
1073 		rte_flow_error_set(error, EINVAL,
1074 				RTE_FLOW_ERROR_TYPE_ITEM,
1075 				item, "Not supported by flex filter");
1076 		return -rte_errno;
1077 	}
1078 
1079 	if (raw_mask->offset)
1080 		offset = raw_spec->offset;
1081 	else
1082 		offset = 0;
1083 
1084 	for (j = 0; j < raw_spec->length; j++) {
1085 		if (raw_mask->pattern[j] != 0xFF) {
1086 			memset(filter, 0, sizeof(struct rte_eth_flex_filter));
1087 			rte_flow_error_set(error, EINVAL,
1088 					RTE_FLOW_ERROR_TYPE_ITEM,
1089 					item, "Not supported by flex filter");
1090 			return -rte_errno;
1091 		}
1092 	}
1093 
1094 	total_offset = 0;
1095 
1096 	if (raw_spec->relative) {
1097 		for (j = raw_index; j > 0; j--) {
1098 			total_offset += raw_offset[j - 1];
1099 			if (!relative[j - 1])
1100 				break;
1101 		}
1102 		if (total_offset + raw_spec->length + offset > max_offset)
1103 			max_offset = total_offset + raw_spec->length + offset;
1104 	} else {
1105 		if (raw_spec->length + offset > max_offset)
1106 			max_offset = raw_spec->length + offset;
1107 	}
1108 
1109 	if ((raw_spec->length + offset + total_offset) >
1110 			RTE_FLEX_FILTER_MAXLEN) {
1111 		memset(filter, 0, sizeof(struct rte_eth_flex_filter));
1112 		rte_flow_error_set(error, EINVAL,
1113 				RTE_FLOW_ERROR_TYPE_ITEM,
1114 				item, "Not supported by flex filter");
1115 		return -rte_errno;
1116 	}
1117 
1118 	if (raw_spec->relative == 0) {
1119 		for (j = 0; j < raw_spec->length; j++)
1120 			filter->bytes[offset + j] =
1121 			raw_spec->pattern[j];
1122 		j = offset / CHAR_BIT;
1123 		shift = offset % CHAR_BIT;
1124 	} else {
1125 		for (j = 0; j < raw_spec->length; j++)
1126 			filter->bytes[total_offset + offset + j] =
1127 				raw_spec->pattern[j];
1128 		j = (total_offset + offset) / CHAR_BIT;
1129 		shift = (total_offset + offset) % CHAR_BIT;
1130 	}
1131 
1132 	i = 0;
1133 
1134 	for ( ; shift < CHAR_BIT; shift++) {
1135 		filter->mask[j] |= (0x80 >> shift);
1136 		i++;
1137 		if (i == raw_spec->length)
1138 			break;
1139 		if (shift == (CHAR_BIT - 1)) {
1140 			j++;
1141 			shift = -1;
1142 		}
1143 	}
1144 
1145 	relative[raw_index] = raw_spec->relative;
1146 	raw_offset[raw_index] = offset + raw_spec->length;
1147 	raw_index++;
1148 
1149 	/* check if the next not void item is RAW */
1150 	index++;
1151 	NEXT_ITEM_OF_PATTERN(item, pattern, index);
1152 	if (item->type != RTE_FLOW_ITEM_TYPE_RAW &&
1153 		item->type != RTE_FLOW_ITEM_TYPE_END) {
1154 		rte_flow_error_set(error, EINVAL,
1155 				RTE_FLOW_ERROR_TYPE_ITEM,
1156 				item, "Not supported by flex filter");
1157 		return -rte_errno;
1158 	}
1159 
1160 	/* go back to parser */
1161 	if (item->type == RTE_FLOW_ITEM_TYPE_RAW) {
1162 		/* if the item is RAW, the content should be parse */
1163 		goto item_loop;
1164 	}
1165 
1166 	filter->len = RTE_ALIGN(max_offset, 8);
1167 
1168 	/* parse action */
1169 	index = 0;
1170 
1171 	/* check if the first not void action is QUEUE. */
1172 	NEXT_ITEM_OF_ACTION(act, actions, index);
1173 	if (act->type != RTE_FLOW_ACTION_TYPE_QUEUE) {
1174 		memset(filter, 0, sizeof(struct rte_eth_flex_filter));
1175 		rte_flow_error_set(error, EINVAL,
1176 				RTE_FLOW_ERROR_TYPE_ACTION,
1177 				act, "Not supported action.");
1178 		return -rte_errno;
1179 	}
1180 
1181 	act_q = (const struct rte_flow_action_queue *)act->conf;
1182 	filter->queue = act_q->index;
1183 
1184 	/* check if the next not void item is END */
1185 	index++;
1186 	NEXT_ITEM_OF_ACTION(act, actions, index);
1187 	if (act->type != RTE_FLOW_ACTION_TYPE_END) {
1188 		memset(filter, 0, sizeof(struct rte_eth_flex_filter));
1189 		rte_flow_error_set(error, EINVAL,
1190 				RTE_FLOW_ERROR_TYPE_ACTION,
1191 				act, "Not supported action.");
1192 		return -rte_errno;
1193 	}
1194 
1195 	/* parse attr */
1196 	/* must be input direction */
1197 	if (!attr->ingress) {
1198 		memset(filter, 0, sizeof(struct rte_eth_flex_filter));
1199 		rte_flow_error_set(error, EINVAL,
1200 			RTE_FLOW_ERROR_TYPE_ATTR_INGRESS,
1201 			attr, "Only support ingress.");
1202 		return -rte_errno;
1203 	}
1204 
1205 	/* not supported */
1206 	if (attr->egress) {
1207 		memset(filter, 0, sizeof(struct rte_eth_flex_filter));
1208 		rte_flow_error_set(error, EINVAL,
1209 			RTE_FLOW_ERROR_TYPE_ATTR_EGRESS,
1210 			attr, "Not support egress.");
1211 		return -rte_errno;
1212 	}
1213 
1214 	if (attr->priority > 0xFFFF) {
1215 		memset(filter, 0, sizeof(struct rte_eth_flex_filter));
1216 		rte_flow_error_set(error, EINVAL,
1217 				   RTE_FLOW_ERROR_TYPE_ATTR_PRIORITY,
1218 				   attr, "Error priority.");
1219 		return -rte_errno;
1220 	}
1221 
1222 	filter->priority = (uint16_t)attr->priority;
1223 
1224 	return 0;
1225 }
1226 
1227 static int
1228 igb_parse_flex_filter(struct rte_eth_dev *dev,
1229 				 const struct rte_flow_attr *attr,
1230 			     const struct rte_flow_item pattern[],
1231 			     const struct rte_flow_action actions[],
1232 			     struct rte_eth_flex_filter *filter,
1233 			     struct rte_flow_error *error)
1234 {
1235 	struct e1000_hw *hw = E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);
1236 	int ret;
1237 
1238 	MAC_TYPE_FILTER_SUP_EXT(hw->mac.type);
1239 
1240 	ret = cons_parse_flex_filter(attr, pattern,
1241 					actions, filter, error);
1242 
1243 	if (filter->queue >= IGB_MAX_RX_QUEUE_NUM) {
1244 		memset(filter, 0, sizeof(struct rte_eth_flex_filter));
1245 		rte_flow_error_set(error, EINVAL,
1246 			RTE_FLOW_ERROR_TYPE_ITEM,
1247 			NULL, "queue number not supported by flex filter");
1248 		return -rte_errno;
1249 	}
1250 
1251 	if (filter->len == 0 || filter->len > E1000_MAX_FLEX_FILTER_LEN ||
1252 		filter->len % sizeof(uint64_t) != 0) {
1253 		PMD_DRV_LOG(ERR, "filter's length is out of range");
1254 		return -EINVAL;
1255 	}
1256 
1257 	if (filter->priority > E1000_MAX_FLEX_FILTER_PRI) {
1258 		PMD_DRV_LOG(ERR, "filter's priority is out of range");
1259 		return -EINVAL;
1260 	}
1261 
1262 	if (ret)
1263 		return ret;
1264 
1265 	return 0;
1266 }
1267 
1268 static int
1269 igb_parse_rss_filter(struct rte_eth_dev *dev,
1270 			const struct rte_flow_attr *attr,
1271 			const struct rte_flow_action actions[],
1272 			struct igb_rte_flow_rss_conf *rss_conf,
1273 			struct rte_flow_error *error)
1274 {
1275 	const struct rte_flow_action *act;
1276 	const struct rte_flow_action_rss *rss;
1277 	uint16_t n, index;
1278 
1279 	/**
1280 	 * rss only supports forwarding,
1281 	 * check if the first not void action is RSS.
1282 	 */
1283 	index = 0;
1284 	NEXT_ITEM_OF_ACTION(act, actions, index);
1285 	if (act->type != RTE_FLOW_ACTION_TYPE_RSS) {
1286 		memset(rss_conf, 0, sizeof(struct igb_rte_flow_rss_conf));
1287 		rte_flow_error_set(error, EINVAL,
1288 			RTE_FLOW_ERROR_TYPE_ACTION,
1289 			act, "Not supported action.");
1290 		return -rte_errno;
1291 	}
1292 
1293 	rss = (const struct rte_flow_action_rss *)act->conf;
1294 
1295 	if (!rss || !rss->num) {
1296 		rte_flow_error_set(error, EINVAL,
1297 				RTE_FLOW_ERROR_TYPE_ACTION,
1298 				act,
1299 			   "no valid queues");
1300 		return -rte_errno;
1301 	}
1302 
1303 	for (n = 0; n < rss->num; n++) {
1304 		if (rss->queue[n] >= dev->data->nb_rx_queues) {
1305 			rte_flow_error_set(error, EINVAL,
1306 				   RTE_FLOW_ERROR_TYPE_ACTION,
1307 				   act,
1308 				   "queue id > max number of queues");
1309 			return -rte_errno;
1310 		}
1311 	}
1312 
1313 	if (rss->rss_conf)
1314 		rss_conf->rss_conf = *rss->rss_conf;
1315 	else
1316 		rss_conf->rss_conf.rss_hf = IGB_RSS_OFFLOAD_ALL;
1317 
1318 	for (n = 0; n < rss->num; ++n)
1319 		rss_conf->queue[n] = rss->queue[n];
1320 	rss_conf->num = rss->num;
1321 
1322 	/* check if the next not void item is END */
1323 	index++;
1324 	NEXT_ITEM_OF_ACTION(act, actions, index);
1325 	if (act->type != RTE_FLOW_ACTION_TYPE_END) {
1326 		memset(rss_conf, 0, sizeof(struct rte_eth_rss_conf));
1327 		rte_flow_error_set(error, EINVAL,
1328 			RTE_FLOW_ERROR_TYPE_ACTION,
1329 			act, "Not supported action.");
1330 		return -rte_errno;
1331 	}
1332 
1333 	/* parse attr */
1334 	/* must be input direction */
1335 	if (!attr->ingress) {
1336 		memset(rss_conf, 0, sizeof(struct igb_rte_flow_rss_conf));
1337 		rte_flow_error_set(error, EINVAL,
1338 				   RTE_FLOW_ERROR_TYPE_ATTR_INGRESS,
1339 				   attr, "Only support ingress.");
1340 		return -rte_errno;
1341 	}
1342 
1343 	/* not supported */
1344 	if (attr->egress) {
1345 		memset(rss_conf, 0, sizeof(struct igb_rte_flow_rss_conf));
1346 		rte_flow_error_set(error, EINVAL,
1347 				   RTE_FLOW_ERROR_TYPE_ATTR_EGRESS,
1348 				   attr, "Not support egress.");
1349 		return -rte_errno;
1350 	}
1351 
1352 	if (attr->priority > 0xFFFF) {
1353 		memset(rss_conf, 0, sizeof(struct igb_rte_flow_rss_conf));
1354 		rte_flow_error_set(error, EINVAL,
1355 				   RTE_FLOW_ERROR_TYPE_ATTR_PRIORITY,
1356 				   attr, "Error priority.");
1357 		return -rte_errno;
1358 	}
1359 
1360 	return 0;
1361 }
1362 
1363 /**
1364  * Create a flow rule.
1365  * Theorically one rule can match more than one filters.
1366  * We will let it use the filter which it hitt first.
1367  * So, the sequence matters.
1368  */
1369 static struct rte_flow *
1370 igb_flow_create(struct rte_eth_dev *dev,
1371 		  const struct rte_flow_attr *attr,
1372 		  const struct rte_flow_item pattern[],
1373 		  const struct rte_flow_action actions[],
1374 		  struct rte_flow_error *error)
1375 {
1376 	int ret;
1377 	struct rte_eth_ntuple_filter ntuple_filter;
1378 	struct rte_eth_ethertype_filter ethertype_filter;
1379 	struct rte_eth_syn_filter syn_filter;
1380 	struct rte_eth_flex_filter flex_filter;
1381 	struct igb_rte_flow_rss_conf rss_conf;
1382 	struct rte_flow *flow = NULL;
1383 	struct igb_ntuple_filter_ele *ntuple_filter_ptr;
1384 	struct igb_ethertype_filter_ele *ethertype_filter_ptr;
1385 	struct igb_eth_syn_filter_ele *syn_filter_ptr;
1386 	struct igb_flex_filter_ele *flex_filter_ptr;
1387 	struct igb_rss_conf_ele *rss_filter_ptr;
1388 	struct igb_flow_mem *igb_flow_mem_ptr;
1389 
1390 	flow = rte_zmalloc("igb_rte_flow", sizeof(struct rte_flow), 0);
1391 	if (!flow) {
1392 		PMD_DRV_LOG(ERR, "failed to allocate memory");
1393 		return (struct rte_flow *)flow;
1394 	}
1395 	igb_flow_mem_ptr = rte_zmalloc("igb_flow_mem",
1396 			sizeof(struct igb_flow_mem), 0);
1397 	if (!igb_flow_mem_ptr) {
1398 		PMD_DRV_LOG(ERR, "failed to allocate memory");
1399 		rte_free(flow);
1400 		return NULL;
1401 	}
1402 	igb_flow_mem_ptr->flow = flow;
1403 	igb_flow_mem_ptr->dev = dev;
1404 	TAILQ_INSERT_TAIL(&igb_flow_list,
1405 				igb_flow_mem_ptr, entries);
1406 
1407 	memset(&ntuple_filter, 0, sizeof(struct rte_eth_ntuple_filter));
1408 	ret = igb_parse_ntuple_filter(dev, attr, pattern,
1409 			actions, &ntuple_filter, error);
1410 	if (!ret) {
1411 		ret = igb_add_del_ntuple_filter(dev, &ntuple_filter, TRUE);
1412 		if (!ret) {
1413 			ntuple_filter_ptr = rte_zmalloc("igb_ntuple_filter",
1414 				sizeof(struct igb_ntuple_filter_ele), 0);
1415 			if (!ntuple_filter_ptr) {
1416 				PMD_DRV_LOG(ERR, "failed to allocate memory");
1417 				goto out;
1418 			}
1419 
1420 			rte_memcpy(&ntuple_filter_ptr->filter_info,
1421 				&ntuple_filter,
1422 				sizeof(struct rte_eth_ntuple_filter));
1423 			TAILQ_INSERT_TAIL(&igb_filter_ntuple_list,
1424 				ntuple_filter_ptr, entries);
1425 			flow->rule = ntuple_filter_ptr;
1426 			flow->filter_type = RTE_ETH_FILTER_NTUPLE;
1427 			return flow;
1428 		}
1429 		goto out;
1430 	}
1431 
1432 	memset(&ethertype_filter, 0, sizeof(struct rte_eth_ethertype_filter));
1433 	ret = igb_parse_ethertype_filter(dev, attr, pattern,
1434 				actions, &ethertype_filter, error);
1435 	if (!ret) {
1436 		ret = igb_add_del_ethertype_filter(dev,
1437 				&ethertype_filter, TRUE);
1438 		if (!ret) {
1439 			ethertype_filter_ptr = rte_zmalloc(
1440 				"igb_ethertype_filter",
1441 				sizeof(struct igb_ethertype_filter_ele), 0);
1442 			if (!ethertype_filter_ptr) {
1443 				PMD_DRV_LOG(ERR, "failed to allocate memory");
1444 				goto out;
1445 			}
1446 
1447 			rte_memcpy(&ethertype_filter_ptr->filter_info,
1448 				&ethertype_filter,
1449 				sizeof(struct rte_eth_ethertype_filter));
1450 			TAILQ_INSERT_TAIL(&igb_filter_ethertype_list,
1451 				ethertype_filter_ptr, entries);
1452 			flow->rule = ethertype_filter_ptr;
1453 			flow->filter_type = RTE_ETH_FILTER_ETHERTYPE;
1454 			return flow;
1455 		}
1456 		goto out;
1457 	}
1458 
1459 	memset(&syn_filter, 0, sizeof(struct rte_eth_syn_filter));
1460 	ret = igb_parse_syn_filter(dev, attr, pattern,
1461 				actions, &syn_filter, error);
1462 	if (!ret) {
1463 		ret = eth_igb_syn_filter_set(dev, &syn_filter, TRUE);
1464 		if (!ret) {
1465 			syn_filter_ptr = rte_zmalloc("igb_syn_filter",
1466 				sizeof(struct igb_eth_syn_filter_ele), 0);
1467 			if (!syn_filter_ptr) {
1468 				PMD_DRV_LOG(ERR, "failed to allocate memory");
1469 				goto out;
1470 			}
1471 
1472 			rte_memcpy(&syn_filter_ptr->filter_info,
1473 				&syn_filter,
1474 				sizeof(struct rte_eth_syn_filter));
1475 			TAILQ_INSERT_TAIL(&igb_filter_syn_list,
1476 				syn_filter_ptr,
1477 				entries);
1478 			flow->rule = syn_filter_ptr;
1479 			flow->filter_type = RTE_ETH_FILTER_SYN;
1480 			return flow;
1481 		}
1482 		goto out;
1483 	}
1484 
1485 	memset(&flex_filter, 0, sizeof(struct rte_eth_flex_filter));
1486 	ret = igb_parse_flex_filter(dev, attr, pattern,
1487 					actions, &flex_filter, error);
1488 	if (!ret) {
1489 		ret = eth_igb_add_del_flex_filter(dev, &flex_filter, TRUE);
1490 		if (!ret) {
1491 			flex_filter_ptr = rte_zmalloc("igb_flex_filter",
1492 				sizeof(struct igb_flex_filter_ele), 0);
1493 			if (!flex_filter_ptr) {
1494 				PMD_DRV_LOG(ERR, "failed to allocate memory");
1495 				goto out;
1496 			}
1497 
1498 			rte_memcpy(&flex_filter_ptr->filter_info,
1499 				&flex_filter,
1500 				sizeof(struct rte_eth_flex_filter));
1501 			TAILQ_INSERT_TAIL(&igb_filter_flex_list,
1502 				flex_filter_ptr, entries);
1503 			flow->rule = flex_filter_ptr;
1504 			flow->filter_type = RTE_ETH_FILTER_FLEXIBLE;
1505 			return flow;
1506 		}
1507 	}
1508 
1509 	memset(&rss_conf, 0, sizeof(struct igb_rte_flow_rss_conf));
1510 	ret = igb_parse_rss_filter(dev, attr,
1511 					actions, &rss_conf, error);
1512 	if (!ret) {
1513 		ret = igb_config_rss_filter(dev, &rss_conf, TRUE);
1514 		if (!ret) {
1515 			rss_filter_ptr = rte_zmalloc("igb_rss_filter",
1516 				sizeof(struct igb_rss_conf_ele), 0);
1517 			if (!rss_filter_ptr) {
1518 				PMD_DRV_LOG(ERR, "failed to allocate memory");
1519 				goto out;
1520 			}
1521 			rte_memcpy(&rss_filter_ptr->filter_info,
1522 				&rss_conf,
1523 				sizeof(struct igb_rte_flow_rss_conf));
1524 			TAILQ_INSERT_TAIL(&igb_filter_rss_list,
1525 				rss_filter_ptr, entries);
1526 			flow->rule = rss_filter_ptr;
1527 			flow->filter_type = RTE_ETH_FILTER_HASH;
1528 			return flow;
1529 		}
1530 	}
1531 
1532 out:
1533 	TAILQ_REMOVE(&igb_flow_list,
1534 		igb_flow_mem_ptr, entries);
1535 	rte_flow_error_set(error, -ret,
1536 			   RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
1537 			   "Failed to create flow.");
1538 	rte_free(igb_flow_mem_ptr);
1539 	rte_free(flow);
1540 	return NULL;
1541 }
1542 
1543 /**
1544  * Check if the flow rule is supported by igb.
1545  * It only checkes the format. Don't guarantee the rule can be programmed into
1546  * the HW. Because there can be no enough room for the rule.
1547  */
1548 static int
1549 igb_flow_validate(__rte_unused struct rte_eth_dev *dev,
1550 		const struct rte_flow_attr *attr,
1551 		const struct rte_flow_item pattern[],
1552 		const struct rte_flow_action actions[],
1553 		struct rte_flow_error *error)
1554 {
1555 	struct rte_eth_ntuple_filter ntuple_filter;
1556 	struct rte_eth_ethertype_filter ethertype_filter;
1557 	struct rte_eth_syn_filter syn_filter;
1558 	struct rte_eth_flex_filter flex_filter;
1559 	struct igb_rte_flow_rss_conf rss_conf;
1560 	int ret;
1561 
1562 	memset(&ntuple_filter, 0, sizeof(struct rte_eth_ntuple_filter));
1563 	ret = igb_parse_ntuple_filter(dev, attr, pattern,
1564 				actions, &ntuple_filter, error);
1565 	if (!ret)
1566 		return 0;
1567 
1568 	memset(&ethertype_filter, 0, sizeof(struct rte_eth_ethertype_filter));
1569 	ret = igb_parse_ethertype_filter(dev, attr, pattern,
1570 				actions, &ethertype_filter, error);
1571 	if (!ret)
1572 		return 0;
1573 
1574 	memset(&syn_filter, 0, sizeof(struct rte_eth_syn_filter));
1575 	ret = igb_parse_syn_filter(dev, attr, pattern,
1576 				actions, &syn_filter, error);
1577 	if (!ret)
1578 		return 0;
1579 
1580 	memset(&flex_filter, 0, sizeof(struct rte_eth_flex_filter));
1581 	ret = igb_parse_flex_filter(dev, attr, pattern,
1582 				actions, &flex_filter, error);
1583 	if (!ret)
1584 		return 0;
1585 
1586 	memset(&rss_conf, 0, sizeof(struct igb_rte_flow_rss_conf));
1587 	ret = igb_parse_rss_filter(dev, attr,
1588 					actions, &rss_conf, error);
1589 
1590 	return ret;
1591 }
1592 
1593 /* Destroy a flow rule on igb. */
1594 static int
1595 igb_flow_destroy(struct rte_eth_dev *dev,
1596 		struct rte_flow *flow,
1597 		struct rte_flow_error *error)
1598 {
1599 	int ret;
1600 	struct rte_flow *pmd_flow = flow;
1601 	enum rte_filter_type filter_type = pmd_flow->filter_type;
1602 	struct igb_ntuple_filter_ele *ntuple_filter_ptr;
1603 	struct igb_ethertype_filter_ele *ethertype_filter_ptr;
1604 	struct igb_eth_syn_filter_ele *syn_filter_ptr;
1605 	struct igb_flex_filter_ele *flex_filter_ptr;
1606 	struct igb_flow_mem *igb_flow_mem_ptr;
1607 	struct igb_rss_conf_ele *rss_filter_ptr;
1608 
1609 	switch (filter_type) {
1610 	case RTE_ETH_FILTER_NTUPLE:
1611 		ntuple_filter_ptr = (struct igb_ntuple_filter_ele *)
1612 					pmd_flow->rule;
1613 		ret = igb_add_del_ntuple_filter(dev,
1614 				&ntuple_filter_ptr->filter_info, FALSE);
1615 		if (!ret) {
1616 			TAILQ_REMOVE(&igb_filter_ntuple_list,
1617 			ntuple_filter_ptr, entries);
1618 			rte_free(ntuple_filter_ptr);
1619 		}
1620 		break;
1621 	case RTE_ETH_FILTER_ETHERTYPE:
1622 		ethertype_filter_ptr = (struct igb_ethertype_filter_ele *)
1623 					pmd_flow->rule;
1624 		ret = igb_add_del_ethertype_filter(dev,
1625 				&ethertype_filter_ptr->filter_info, FALSE);
1626 		if (!ret) {
1627 			TAILQ_REMOVE(&igb_filter_ethertype_list,
1628 				ethertype_filter_ptr, entries);
1629 			rte_free(ethertype_filter_ptr);
1630 		}
1631 		break;
1632 	case RTE_ETH_FILTER_SYN:
1633 		syn_filter_ptr = (struct igb_eth_syn_filter_ele *)
1634 				pmd_flow->rule;
1635 		ret = eth_igb_syn_filter_set(dev,
1636 				&syn_filter_ptr->filter_info, FALSE);
1637 		if (!ret) {
1638 			TAILQ_REMOVE(&igb_filter_syn_list,
1639 				syn_filter_ptr, entries);
1640 			rte_free(syn_filter_ptr);
1641 		}
1642 		break;
1643 	case RTE_ETH_FILTER_FLEXIBLE:
1644 		flex_filter_ptr = (struct igb_flex_filter_ele *)
1645 				pmd_flow->rule;
1646 		ret = eth_igb_add_del_flex_filter(dev,
1647 				&flex_filter_ptr->filter_info, FALSE);
1648 		if (!ret) {
1649 			TAILQ_REMOVE(&igb_filter_flex_list,
1650 				flex_filter_ptr, entries);
1651 			rte_free(flex_filter_ptr);
1652 		}
1653 		break;
1654 	case RTE_ETH_FILTER_HASH:
1655 		rss_filter_ptr = (struct igb_rss_conf_ele *)
1656 				pmd_flow->rule;
1657 		ret = igb_config_rss_filter(dev,
1658 					&rss_filter_ptr->filter_info, FALSE);
1659 		if (!ret) {
1660 			TAILQ_REMOVE(&igb_filter_rss_list,
1661 				rss_filter_ptr, entries);
1662 			rte_free(rss_filter_ptr);
1663 		}
1664 		break;
1665 	default:
1666 		PMD_DRV_LOG(WARNING, "Filter type (%d) not supported",
1667 			    filter_type);
1668 		ret = -EINVAL;
1669 		break;
1670 	}
1671 
1672 	if (ret) {
1673 		rte_flow_error_set(error, EINVAL,
1674 				RTE_FLOW_ERROR_TYPE_HANDLE,
1675 				NULL, "Failed to destroy flow");
1676 		return ret;
1677 	}
1678 
1679 	TAILQ_FOREACH(igb_flow_mem_ptr, &igb_flow_list, entries) {
1680 		if (igb_flow_mem_ptr->flow == pmd_flow) {
1681 			TAILQ_REMOVE(&igb_flow_list,
1682 				igb_flow_mem_ptr, entries);
1683 			rte_free(igb_flow_mem_ptr);
1684 		}
1685 	}
1686 	rte_free(flow);
1687 
1688 	return ret;
1689 }
1690 
1691 /* remove all the n-tuple filters */
1692 static void
1693 igb_clear_all_ntuple_filter(struct rte_eth_dev *dev)
1694 {
1695 	struct e1000_filter_info *filter_info =
1696 		E1000_DEV_PRIVATE_TO_FILTER_INFO(dev->data->dev_private);
1697 	struct e1000_5tuple_filter *p_5tuple;
1698 	struct e1000_2tuple_filter *p_2tuple;
1699 
1700 	while ((p_5tuple = TAILQ_FIRST(&filter_info->fivetuple_list)))
1701 		igb_delete_5tuple_filter_82576(dev, p_5tuple);
1702 
1703 	while ((p_2tuple = TAILQ_FIRST(&filter_info->twotuple_list)))
1704 		igb_delete_2tuple_filter(dev, p_2tuple);
1705 }
1706 
1707 /* remove all the ether type filters */
1708 static void
1709 igb_clear_all_ethertype_filter(struct rte_eth_dev *dev)
1710 {
1711 	struct e1000_hw *hw = E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);
1712 	struct e1000_filter_info *filter_info =
1713 		E1000_DEV_PRIVATE_TO_FILTER_INFO(dev->data->dev_private);
1714 	int i;
1715 
1716 	for (i = 0; i < E1000_MAX_ETQF_FILTERS; i++) {
1717 		if (filter_info->ethertype_mask & (1 << i)) {
1718 			(void)igb_ethertype_filter_remove(filter_info,
1719 							    (uint8_t)i);
1720 			E1000_WRITE_REG(hw, E1000_ETQF(i), 0);
1721 			E1000_WRITE_FLUSH(hw);
1722 		}
1723 	}
1724 }
1725 
1726 /* remove the SYN filter */
1727 static void
1728 igb_clear_syn_filter(struct rte_eth_dev *dev)
1729 {
1730 	struct e1000_hw *hw = E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);
1731 	struct e1000_filter_info *filter_info =
1732 		E1000_DEV_PRIVATE_TO_FILTER_INFO(dev->data->dev_private);
1733 
1734 	if (filter_info->syn_info & E1000_SYN_FILTER_ENABLE) {
1735 		filter_info->syn_info = 0;
1736 		E1000_WRITE_REG(hw, E1000_SYNQF(0), 0);
1737 		E1000_WRITE_FLUSH(hw);
1738 	}
1739 }
1740 
1741 /* remove all the flex filters */
1742 static void
1743 igb_clear_all_flex_filter(struct rte_eth_dev *dev)
1744 {
1745 	struct e1000_filter_info *filter_info =
1746 		E1000_DEV_PRIVATE_TO_FILTER_INFO(dev->data->dev_private);
1747 	struct e1000_flex_filter *flex_filter;
1748 
1749 	while ((flex_filter = TAILQ_FIRST(&filter_info->flex_list)))
1750 		igb_remove_flex_filter(dev, flex_filter);
1751 }
1752 
1753 /* remove the rss filter */
1754 static void
1755 igb_clear_rss_filter(struct rte_eth_dev *dev)
1756 {
1757 	struct e1000_filter_info *filter =
1758 		E1000_DEV_PRIVATE_TO_FILTER_INFO(dev->data->dev_private);
1759 
1760 	if (filter->rss_info.num)
1761 		igb_config_rss_filter(dev, &filter->rss_info, FALSE);
1762 }
1763 
1764 void
1765 igb_filterlist_flush(struct rte_eth_dev *dev)
1766 {
1767 	struct igb_ntuple_filter_ele *ntuple_filter_ptr;
1768 	struct igb_ethertype_filter_ele *ethertype_filter_ptr;
1769 	struct igb_eth_syn_filter_ele *syn_filter_ptr;
1770 	struct igb_flex_filter_ele *flex_filter_ptr;
1771 	struct igb_rss_conf_ele  *rss_filter_ptr;
1772 	struct igb_flow_mem *igb_flow_mem_ptr;
1773 	enum rte_filter_type filter_type;
1774 	struct rte_flow *pmd_flow;
1775 
1776 	TAILQ_FOREACH(igb_flow_mem_ptr, &igb_flow_list, entries) {
1777 		if (igb_flow_mem_ptr->dev == dev) {
1778 			pmd_flow = igb_flow_mem_ptr->flow;
1779 			filter_type = pmd_flow->filter_type;
1780 
1781 			switch (filter_type) {
1782 			case RTE_ETH_FILTER_NTUPLE:
1783 				ntuple_filter_ptr =
1784 				(struct igb_ntuple_filter_ele *)
1785 					pmd_flow->rule;
1786 				TAILQ_REMOVE(&igb_filter_ntuple_list,
1787 						ntuple_filter_ptr, entries);
1788 				rte_free(ntuple_filter_ptr);
1789 				break;
1790 			case RTE_ETH_FILTER_ETHERTYPE:
1791 				ethertype_filter_ptr =
1792 				(struct igb_ethertype_filter_ele *)
1793 					pmd_flow->rule;
1794 				TAILQ_REMOVE(&igb_filter_ethertype_list,
1795 						ethertype_filter_ptr, entries);
1796 				rte_free(ethertype_filter_ptr);
1797 				break;
1798 			case RTE_ETH_FILTER_SYN:
1799 				syn_filter_ptr =
1800 					(struct igb_eth_syn_filter_ele *)
1801 						pmd_flow->rule;
1802 				TAILQ_REMOVE(&igb_filter_syn_list,
1803 						syn_filter_ptr, entries);
1804 				rte_free(syn_filter_ptr);
1805 				break;
1806 			case RTE_ETH_FILTER_FLEXIBLE:
1807 				flex_filter_ptr =
1808 					(struct igb_flex_filter_ele *)
1809 						pmd_flow->rule;
1810 				TAILQ_REMOVE(&igb_filter_flex_list,
1811 						flex_filter_ptr, entries);
1812 				rte_free(flex_filter_ptr);
1813 				break;
1814 			case RTE_ETH_FILTER_HASH:
1815 				rss_filter_ptr =
1816 					(struct igb_rss_conf_ele *)
1817 						pmd_flow->rule;
1818 				TAILQ_REMOVE(&igb_filter_rss_list,
1819 						rss_filter_ptr, entries);
1820 				rte_free(rss_filter_ptr);
1821 				break;
1822 			default:
1823 				PMD_DRV_LOG(WARNING, "Filter type"
1824 					"(%d) not supported", filter_type);
1825 				break;
1826 			}
1827 			TAILQ_REMOVE(&igb_flow_list,
1828 				 igb_flow_mem_ptr,
1829 				 entries);
1830 			rte_free(igb_flow_mem_ptr->flow);
1831 			rte_free(igb_flow_mem_ptr);
1832 		}
1833 	}
1834 }
1835 
1836 /*  Destroy all flow rules associated with a port on igb. */
1837 static int
1838 igb_flow_flush(struct rte_eth_dev *dev,
1839 		__rte_unused struct rte_flow_error *error)
1840 {
1841 	igb_clear_all_ntuple_filter(dev);
1842 	igb_clear_all_ethertype_filter(dev);
1843 	igb_clear_syn_filter(dev);
1844 	igb_clear_all_flex_filter(dev);
1845 	igb_clear_rss_filter(dev);
1846 	igb_filterlist_flush(dev);
1847 
1848 	return 0;
1849 }
1850 
1851 const struct rte_flow_ops igb_flow_ops = {
1852 	.validate = igb_flow_validate,
1853 	.create = igb_flow_create,
1854 	.destroy = igb_flow_destroy,
1855 	.flush = igb_flow_flush,
1856 };
1857