xref: /dpdk/drivers/net/e1000/igb_flow.c (revision 85cf6dc3)
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 	/* not supported */
383 	if (attr->transfer) {
384 		memset(filter, 0, sizeof(struct rte_eth_ntuple_filter));
385 		rte_flow_error_set(error, EINVAL,
386 				   RTE_FLOW_ERROR_TYPE_ATTR_TRANSFER,
387 				   attr, "No support for transfer.");
388 		return -rte_errno;
389 	}
390 
391 	if (attr->priority > 0xFFFF) {
392 		memset(filter, 0, sizeof(struct rte_eth_ntuple_filter));
393 		rte_flow_error_set(error, EINVAL,
394 				   RTE_FLOW_ERROR_TYPE_ATTR_PRIORITY,
395 				   attr, "Error priority.");
396 		return -rte_errno;
397 	}
398 	filter->priority = (uint16_t)attr->priority;
399 
400 	return 0;
401 }
402 
403 /* a specific function for igb because the flags is specific */
404 static int
405 igb_parse_ntuple_filter(struct rte_eth_dev *dev,
406 			  const struct rte_flow_attr *attr,
407 			  const struct rte_flow_item pattern[],
408 			  const struct rte_flow_action actions[],
409 			  struct rte_eth_ntuple_filter *filter,
410 			  struct rte_flow_error *error)
411 {
412 	struct e1000_hw *hw = E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);
413 	int ret;
414 
415 	MAC_TYPE_FILTER_SUP(hw->mac.type);
416 
417 	ret = cons_parse_ntuple_filter(attr, pattern, actions, filter, error);
418 
419 	if (ret)
420 		return ret;
421 
422 	/* Igb doesn't support many priorities. */
423 	if (filter->priority > E1000_2TUPLE_MAX_PRI) {
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, "Priority not supported by ntuple filter");
428 		return -rte_errno;
429 	}
430 
431 	if (hw->mac.type == e1000_82576) {
432 		if (filter->queue >= IGB_MAX_RX_QUEUE_NUM_82576) {
433 			memset(filter, 0, sizeof(struct rte_eth_ntuple_filter));
434 			rte_flow_error_set(error, EINVAL,
435 				RTE_FLOW_ERROR_TYPE_ITEM,
436 				NULL, "queue number not "
437 				"supported by ntuple filter");
438 			return -rte_errno;
439 		}
440 		filter->flags |= RTE_5TUPLE_FLAGS;
441 	} else {
442 		if (filter->src_ip_mask || filter->dst_ip_mask ||
443 			filter->src_port_mask) {
444 			memset(filter, 0, sizeof(struct rte_eth_ntuple_filter));
445 			rte_flow_error_set(error, EINVAL,
446 				RTE_FLOW_ERROR_TYPE_ITEM,
447 				NULL, "only two tuple are "
448 				"supported by this filter");
449 			return -rte_errno;
450 		}
451 		if (filter->queue >= IGB_MAX_RX_QUEUE_NUM) {
452 			memset(filter, 0, sizeof(struct rte_eth_ntuple_filter));
453 			rte_flow_error_set(error, EINVAL,
454 				RTE_FLOW_ERROR_TYPE_ITEM,
455 				NULL, "queue number not "
456 				"supported by ntuple filter");
457 			return -rte_errno;
458 		}
459 		filter->flags |= RTE_2TUPLE_FLAGS;
460 	}
461 
462 	return 0;
463 }
464 
465 /**
466  * Parse the rule to see if it is a ethertype rule.
467  * And get the ethertype filter info BTW.
468  * pattern:
469  * The first not void item can be ETH.
470  * The next not void item must be END.
471  * action:
472  * The first not void action should be QUEUE.
473  * The next not void action should be END.
474  * pattern example:
475  * ITEM		Spec			Mask
476  * ETH		type	0x0807		0xFFFF
477  * END
478  * other members in mask and spec should set to 0x00.
479  * item->last should be NULL.
480  */
481 static int
482 cons_parse_ethertype_filter(const struct rte_flow_attr *attr,
483 			    const struct rte_flow_item *pattern,
484 			    const struct rte_flow_action *actions,
485 			    struct rte_eth_ethertype_filter *filter,
486 			    struct rte_flow_error *error)
487 {
488 	const struct rte_flow_item *item;
489 	const struct rte_flow_action *act;
490 	const struct rte_flow_item_eth *eth_spec;
491 	const struct rte_flow_item_eth *eth_mask;
492 	const struct rte_flow_action_queue *act_q;
493 	uint32_t index;
494 
495 	if (!pattern) {
496 		rte_flow_error_set(error, EINVAL,
497 				RTE_FLOW_ERROR_TYPE_ITEM_NUM,
498 				NULL, "NULL pattern.");
499 		return -rte_errno;
500 	}
501 
502 	if (!actions) {
503 		rte_flow_error_set(error, EINVAL,
504 				RTE_FLOW_ERROR_TYPE_ACTION_NUM,
505 				NULL, "NULL action.");
506 		return -rte_errno;
507 	}
508 
509 	if (!attr) {
510 		rte_flow_error_set(error, EINVAL,
511 				   RTE_FLOW_ERROR_TYPE_ATTR,
512 				   NULL, "NULL attribute.");
513 		return -rte_errno;
514 	}
515 
516 	/* Parse pattern */
517 	index = 0;
518 
519 	/* The first non-void item should be MAC. */
520 	NEXT_ITEM_OF_PATTERN(item, pattern, index);
521 	if (item->type != RTE_FLOW_ITEM_TYPE_ETH) {
522 		rte_flow_error_set(error, EINVAL,
523 			RTE_FLOW_ERROR_TYPE_ITEM,
524 			item, "Not supported by ethertype filter");
525 		return -rte_errno;
526 	}
527 
528 	/*Not supported last point for range*/
529 	if (item->last) {
530 		rte_flow_error_set(error, EINVAL,
531 			RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
532 			item, "Not supported last point for range");
533 		return -rte_errno;
534 	}
535 
536 	/* Get the MAC info. */
537 	if (!item->spec || !item->mask) {
538 		rte_flow_error_set(error, EINVAL,
539 				RTE_FLOW_ERROR_TYPE_ITEM,
540 				item, "Not supported by ethertype filter");
541 		return -rte_errno;
542 	}
543 
544 	eth_spec = item->spec;
545 	eth_mask = item->mask;
546 
547 	/* Mask bits of source MAC address must be full of 0.
548 	 * Mask bits of destination MAC address must be full
549 	 * of 1 or full of 0.
550 	 */
551 	if (!rte_is_zero_ether_addr(&eth_mask->src) ||
552 	    (!rte_is_zero_ether_addr(&eth_mask->dst) &&
553 	     !rte_is_broadcast_ether_addr(&eth_mask->dst))) {
554 		rte_flow_error_set(error, EINVAL,
555 				RTE_FLOW_ERROR_TYPE_ITEM,
556 				item, "Invalid ether address mask");
557 		return -rte_errno;
558 	}
559 
560 	if ((eth_mask->type & UINT16_MAX) != UINT16_MAX) {
561 		rte_flow_error_set(error, EINVAL,
562 				RTE_FLOW_ERROR_TYPE_ITEM,
563 				item, "Invalid ethertype mask");
564 		return -rte_errno;
565 	}
566 
567 	/* If mask bits of destination MAC address
568 	 * are full of 1, set RTE_ETHTYPE_FLAGS_MAC.
569 	 */
570 	if (rte_is_broadcast_ether_addr(&eth_mask->dst)) {
571 		filter->mac_addr = eth_spec->dst;
572 		filter->flags |= RTE_ETHTYPE_FLAGS_MAC;
573 	} else {
574 		filter->flags &= ~RTE_ETHTYPE_FLAGS_MAC;
575 	}
576 	filter->ether_type = rte_be_to_cpu_16(eth_spec->type);
577 
578 	/* Check if the next non-void item is END. */
579 	index++;
580 	NEXT_ITEM_OF_PATTERN(item, pattern, index);
581 	if (item->type != RTE_FLOW_ITEM_TYPE_END) {
582 		rte_flow_error_set(error, EINVAL,
583 				RTE_FLOW_ERROR_TYPE_ITEM,
584 				item, "Not supported by ethertype filter.");
585 		return -rte_errno;
586 	}
587 
588 	/* Parse action */
589 
590 	index = 0;
591 	/* Check if the first non-void action is QUEUE or DROP. */
592 	NEXT_ITEM_OF_ACTION(act, actions, index);
593 	if (act->type != RTE_FLOW_ACTION_TYPE_QUEUE &&
594 	    act->type != RTE_FLOW_ACTION_TYPE_DROP) {
595 		rte_flow_error_set(error, EINVAL,
596 				RTE_FLOW_ERROR_TYPE_ACTION,
597 				act, "Not supported action.");
598 		return -rte_errno;
599 	}
600 
601 	if (act->type == RTE_FLOW_ACTION_TYPE_QUEUE) {
602 		act_q = (const struct rte_flow_action_queue *)act->conf;
603 		filter->queue = act_q->index;
604 	} else {
605 		filter->flags |= RTE_ETHTYPE_FLAGS_DROP;
606 	}
607 
608 	/* Check if the next non-void item is END */
609 	index++;
610 	NEXT_ITEM_OF_ACTION(act, actions, index);
611 	if (act->type != RTE_FLOW_ACTION_TYPE_END) {
612 		rte_flow_error_set(error, EINVAL,
613 				RTE_FLOW_ERROR_TYPE_ACTION,
614 				act, "Not supported action.");
615 		return -rte_errno;
616 	}
617 
618 	/* Parse attr */
619 	/* Must be input direction */
620 	if (!attr->ingress) {
621 		rte_flow_error_set(error, EINVAL,
622 				RTE_FLOW_ERROR_TYPE_ATTR_INGRESS,
623 				attr, "Only support ingress.");
624 		return -rte_errno;
625 	}
626 
627 	/* Not supported */
628 	if (attr->egress) {
629 		rte_flow_error_set(error, EINVAL,
630 				RTE_FLOW_ERROR_TYPE_ATTR_EGRESS,
631 				attr, "Not support egress.");
632 		return -rte_errno;
633 	}
634 
635 	/* Not supported */
636 	if (attr->transfer) {
637 		rte_flow_error_set(error, EINVAL,
638 				RTE_FLOW_ERROR_TYPE_ATTR_TRANSFER,
639 				attr, "No support for transfer.");
640 		return -rte_errno;
641 	}
642 
643 	/* Not supported */
644 	if (attr->priority) {
645 		rte_flow_error_set(error, EINVAL,
646 				RTE_FLOW_ERROR_TYPE_ATTR_PRIORITY,
647 				attr, "Not support priority.");
648 		return -rte_errno;
649 	}
650 
651 	/* Not supported */
652 	if (attr->group) {
653 		rte_flow_error_set(error, EINVAL,
654 				RTE_FLOW_ERROR_TYPE_ATTR_GROUP,
655 				attr, "Not support group.");
656 		return -rte_errno;
657 	}
658 
659 	return 0;
660 }
661 
662 static int
663 igb_parse_ethertype_filter(struct rte_eth_dev *dev,
664 				 const struct rte_flow_attr *attr,
665 			     const struct rte_flow_item pattern[],
666 			     const struct rte_flow_action actions[],
667 			     struct rte_eth_ethertype_filter *filter,
668 			     struct rte_flow_error *error)
669 {
670 	struct e1000_hw *hw = E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);
671 	int ret;
672 
673 	MAC_TYPE_FILTER_SUP(hw->mac.type);
674 
675 	ret = cons_parse_ethertype_filter(attr, pattern,
676 					actions, filter, error);
677 
678 	if (ret)
679 		return ret;
680 
681 	if (hw->mac.type == e1000_82576) {
682 		if (filter->queue >= IGB_MAX_RX_QUEUE_NUM_82576) {
683 			memset(filter, 0, sizeof(
684 					struct rte_eth_ethertype_filter));
685 			rte_flow_error_set(error, EINVAL,
686 				RTE_FLOW_ERROR_TYPE_ITEM,
687 				NULL, "queue number not supported "
688 					"by ethertype filter");
689 			return -rte_errno;
690 		}
691 	} else {
692 		if (filter->queue >= IGB_MAX_RX_QUEUE_NUM) {
693 			memset(filter, 0, sizeof(
694 					struct rte_eth_ethertype_filter));
695 			rte_flow_error_set(error, EINVAL,
696 				RTE_FLOW_ERROR_TYPE_ITEM,
697 				NULL, "queue number not supported "
698 					"by ethertype filter");
699 			return -rte_errno;
700 		}
701 	}
702 
703 	if (filter->ether_type == RTE_ETHER_TYPE_IPV4 ||
704 		filter->ether_type == RTE_ETHER_TYPE_IPV6) {
705 		memset(filter, 0, sizeof(struct rte_eth_ethertype_filter));
706 		rte_flow_error_set(error, EINVAL,
707 			RTE_FLOW_ERROR_TYPE_ITEM,
708 			NULL, "IPv4/IPv6 not supported by ethertype filter");
709 		return -rte_errno;
710 	}
711 
712 	if (filter->flags & RTE_ETHTYPE_FLAGS_MAC) {
713 		memset(filter, 0, sizeof(struct rte_eth_ethertype_filter));
714 		rte_flow_error_set(error, EINVAL,
715 			RTE_FLOW_ERROR_TYPE_ITEM,
716 			NULL, "mac compare is unsupported");
717 		return -rte_errno;
718 	}
719 
720 	if (filter->flags & RTE_ETHTYPE_FLAGS_DROP) {
721 		memset(filter, 0, sizeof(struct rte_eth_ethertype_filter));
722 		rte_flow_error_set(error, EINVAL,
723 			RTE_FLOW_ERROR_TYPE_ITEM,
724 			NULL, "drop option is unsupported");
725 		return -rte_errno;
726 	}
727 
728 	return 0;
729 }
730 
731 /**
732  * Parse the rule to see if it is a TCP SYN rule.
733  * And get the TCP SYN filter info BTW.
734  * pattern:
735  * The first not void item must be ETH.
736  * The second not void item must be IPV4 or IPV6.
737  * The third not void item must be TCP.
738  * The next not void item must be END.
739  * action:
740  * The first not void action should be QUEUE.
741  * The next not void action should be END.
742  * pattern example:
743  * ITEM		Spec			Mask
744  * ETH		NULL			NULL
745  * IPV4/IPV6	NULL			NULL
746  * TCP		tcp_flags	0x02	0xFF
747  * END
748  * other members in mask and spec should set to 0x00.
749  * item->last should be NULL.
750  */
751 static int
752 cons_parse_syn_filter(const struct rte_flow_attr *attr,
753 				const struct rte_flow_item pattern[],
754 				const struct rte_flow_action actions[],
755 				struct rte_eth_syn_filter *filter,
756 				struct rte_flow_error *error)
757 {
758 	const struct rte_flow_item *item;
759 	const struct rte_flow_action *act;
760 	const struct rte_flow_item_tcp *tcp_spec;
761 	const struct rte_flow_item_tcp *tcp_mask;
762 	const struct rte_flow_action_queue *act_q;
763 	uint32_t index;
764 
765 	if (!pattern) {
766 		rte_flow_error_set(error, EINVAL,
767 				RTE_FLOW_ERROR_TYPE_ITEM_NUM,
768 				NULL, "NULL pattern.");
769 		return -rte_errno;
770 	}
771 
772 	if (!actions) {
773 		rte_flow_error_set(error, EINVAL,
774 				RTE_FLOW_ERROR_TYPE_ACTION_NUM,
775 				NULL, "NULL action.");
776 		return -rte_errno;
777 	}
778 
779 	if (!attr) {
780 		rte_flow_error_set(error, EINVAL,
781 				   RTE_FLOW_ERROR_TYPE_ATTR,
782 				   NULL, "NULL attribute.");
783 		return -rte_errno;
784 	}
785 
786 	/* parse pattern */
787 	index = 0;
788 
789 	/* the first not void item should be MAC or IPv4 or IPv6 or TCP */
790 	NEXT_ITEM_OF_PATTERN(item, pattern, index);
791 	if (item->type != RTE_FLOW_ITEM_TYPE_ETH &&
792 	    item->type != RTE_FLOW_ITEM_TYPE_IPV4 &&
793 	    item->type != RTE_FLOW_ITEM_TYPE_IPV6 &&
794 	    item->type != RTE_FLOW_ITEM_TYPE_TCP) {
795 		rte_flow_error_set(error, EINVAL,
796 				RTE_FLOW_ERROR_TYPE_ITEM,
797 				item, "Not supported by syn filter");
798 		return -rte_errno;
799 	}
800 		/*Not supported last point for range*/
801 	if (item->last) {
802 		rte_flow_error_set(error, EINVAL,
803 			RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
804 			item, "Not supported last point for range");
805 		return -rte_errno;
806 	}
807 
808 	/* Skip Ethernet */
809 	if (item->type == RTE_FLOW_ITEM_TYPE_ETH) {
810 		/* if the item is MAC, the content should be NULL */
811 		if (item->spec || item->mask) {
812 			rte_flow_error_set(error, EINVAL,
813 				RTE_FLOW_ERROR_TYPE_ITEM,
814 				item, "Invalid SYN address mask");
815 			return -rte_errno;
816 		}
817 
818 		/* check if the next not void item is IPv4 or IPv6 */
819 		index++;
820 		NEXT_ITEM_OF_PATTERN(item, pattern, index);
821 		if (item->type != RTE_FLOW_ITEM_TYPE_IPV4 &&
822 		    item->type != RTE_FLOW_ITEM_TYPE_IPV6) {
823 			rte_flow_error_set(error, EINVAL,
824 				RTE_FLOW_ERROR_TYPE_ITEM,
825 				item, "Not supported by syn filter");
826 			return -rte_errno;
827 		}
828 	}
829 
830 	/* Skip IP */
831 	if (item->type == RTE_FLOW_ITEM_TYPE_IPV4 ||
832 	    item->type == RTE_FLOW_ITEM_TYPE_IPV6) {
833 		/* if the item is IP, the content should be NULL */
834 		if (item->spec || item->mask) {
835 			rte_flow_error_set(error, EINVAL,
836 				RTE_FLOW_ERROR_TYPE_ITEM,
837 				item, "Invalid SYN mask");
838 			return -rte_errno;
839 		}
840 
841 		/* check if the next not void item is TCP */
842 		index++;
843 		NEXT_ITEM_OF_PATTERN(item, pattern, index);
844 		if (item->type != RTE_FLOW_ITEM_TYPE_TCP) {
845 			rte_flow_error_set(error, EINVAL,
846 				RTE_FLOW_ERROR_TYPE_ITEM,
847 				item, "Not supported by syn filter");
848 			return -rte_errno;
849 		}
850 	}
851 
852 	/* Get the TCP info. Only support SYN. */
853 	if (!item->spec || !item->mask) {
854 		rte_flow_error_set(error, EINVAL,
855 				RTE_FLOW_ERROR_TYPE_ITEM,
856 				item, "Invalid SYN mask");
857 		return -rte_errno;
858 	}
859 	/*Not supported last point for range*/
860 	if (item->last) {
861 		rte_flow_error_set(error, EINVAL,
862 			RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
863 			item, "Not supported last point for range");
864 		return -rte_errno;
865 	}
866 
867 	tcp_spec = item->spec;
868 	tcp_mask = item->mask;
869 	if (!(tcp_spec->hdr.tcp_flags & RTE_TCP_SYN_FLAG) ||
870 	    tcp_mask->hdr.src_port ||
871 	    tcp_mask->hdr.dst_port ||
872 	    tcp_mask->hdr.sent_seq ||
873 	    tcp_mask->hdr.recv_ack ||
874 	    tcp_mask->hdr.data_off ||
875 	    tcp_mask->hdr.tcp_flags != RTE_TCP_SYN_FLAG ||
876 	    tcp_mask->hdr.rx_win ||
877 	    tcp_mask->hdr.cksum ||
878 	    tcp_mask->hdr.tcp_urp) {
879 		memset(filter, 0, sizeof(struct rte_eth_syn_filter));
880 		rte_flow_error_set(error, EINVAL,
881 				RTE_FLOW_ERROR_TYPE_ITEM,
882 				item, "Not supported by syn filter");
883 		return -rte_errno;
884 	}
885 
886 	/* check if the next not void item is END */
887 	index++;
888 	NEXT_ITEM_OF_PATTERN(item, pattern, index);
889 	if (item->type != RTE_FLOW_ITEM_TYPE_END) {
890 		memset(filter, 0, sizeof(struct rte_eth_syn_filter));
891 		rte_flow_error_set(error, EINVAL,
892 				RTE_FLOW_ERROR_TYPE_ITEM,
893 				item, "Not supported by syn filter");
894 		return -rte_errno;
895 	}
896 
897 	/* parse action */
898 	index = 0;
899 
900 	/* check if the first not void action is QUEUE. */
901 	NEXT_ITEM_OF_ACTION(act, actions, index);
902 	if (act->type != RTE_FLOW_ACTION_TYPE_QUEUE) {
903 		memset(filter, 0, sizeof(struct rte_eth_syn_filter));
904 		rte_flow_error_set(error, EINVAL,
905 				RTE_FLOW_ERROR_TYPE_ACTION,
906 				act, "Not supported action.");
907 		return -rte_errno;
908 	}
909 
910 	act_q = (const struct rte_flow_action_queue *)act->conf;
911 	filter->queue = act_q->index;
912 
913 	/* check if the next not void item is END */
914 	index++;
915 	NEXT_ITEM_OF_ACTION(act, actions, index);
916 	if (act->type != RTE_FLOW_ACTION_TYPE_END) {
917 		memset(filter, 0, sizeof(struct rte_eth_syn_filter));
918 		rte_flow_error_set(error, EINVAL,
919 				RTE_FLOW_ERROR_TYPE_ACTION,
920 				act, "Not supported action.");
921 		return -rte_errno;
922 	}
923 
924 	/* parse attr */
925 	/* must be input direction */
926 	if (!attr->ingress) {
927 		memset(filter, 0, sizeof(struct rte_eth_syn_filter));
928 		rte_flow_error_set(error, EINVAL,
929 			RTE_FLOW_ERROR_TYPE_ATTR_INGRESS,
930 			attr, "Only support ingress.");
931 		return -rte_errno;
932 	}
933 
934 	/* not supported */
935 	if (attr->egress) {
936 		memset(filter, 0, sizeof(struct rte_eth_syn_filter));
937 		rte_flow_error_set(error, EINVAL,
938 			RTE_FLOW_ERROR_TYPE_ATTR_EGRESS,
939 			attr, "Not support egress.");
940 		return -rte_errno;
941 	}
942 
943 	/* not supported */
944 	if (attr->transfer) {
945 		memset(filter, 0, sizeof(struct rte_eth_syn_filter));
946 		rte_flow_error_set(error, EINVAL,
947 			RTE_FLOW_ERROR_TYPE_ATTR_TRANSFER,
948 			attr, "No support for transfer.");
949 		return -rte_errno;
950 	}
951 
952 	/* Support 2 priorities, the lowest or highest. */
953 	if (!attr->priority) {
954 		filter->hig_pri = 0;
955 	} else if (attr->priority == (uint32_t)~0U) {
956 		filter->hig_pri = 1;
957 	} else {
958 		memset(filter, 0, sizeof(struct rte_eth_syn_filter));
959 		rte_flow_error_set(error, EINVAL,
960 			RTE_FLOW_ERROR_TYPE_ATTR_PRIORITY,
961 			attr, "Not support priority.");
962 		return -rte_errno;
963 	}
964 
965 	return 0;
966 }
967 
968 static int
969 igb_parse_syn_filter(struct rte_eth_dev *dev,
970 				 const struct rte_flow_attr *attr,
971 			     const struct rte_flow_item pattern[],
972 			     const struct rte_flow_action actions[],
973 			     struct rte_eth_syn_filter *filter,
974 			     struct rte_flow_error *error)
975 {
976 	struct e1000_hw *hw = E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);
977 	int ret;
978 
979 	MAC_TYPE_FILTER_SUP(hw->mac.type);
980 
981 	ret = cons_parse_syn_filter(attr, pattern,
982 					actions, filter, error);
983 
984 	if (hw->mac.type == e1000_82576) {
985 		if (filter->queue >= IGB_MAX_RX_QUEUE_NUM_82576) {
986 			memset(filter, 0, sizeof(struct rte_eth_syn_filter));
987 			rte_flow_error_set(error, EINVAL,
988 				RTE_FLOW_ERROR_TYPE_ITEM,
989 				NULL, "queue number not "
990 					"supported by syn filter");
991 			return -rte_errno;
992 		}
993 	} else {
994 		if (filter->queue >= IGB_MAX_RX_QUEUE_NUM) {
995 			memset(filter, 0, sizeof(struct rte_eth_syn_filter));
996 			rte_flow_error_set(error, EINVAL,
997 				RTE_FLOW_ERROR_TYPE_ITEM,
998 				NULL, "queue number not "
999 					"supported by syn filter");
1000 			return -rte_errno;
1001 		}
1002 	}
1003 
1004 	if (ret)
1005 		return ret;
1006 
1007 	return 0;
1008 }
1009 
1010 /**
1011  * Parse the rule to see if it is a flex byte rule.
1012  * And get the flex byte filter info BTW.
1013  * pattern:
1014  * The first not void item must be RAW.
1015  * The second not void item can be RAW or END.
1016  * The third not void item can be RAW or END.
1017  * The last not void item must be END.
1018  * action:
1019  * The first not void action should be QUEUE.
1020  * The next not void action should be END.
1021  * pattern example:
1022  * ITEM		Spec			Mask
1023  * RAW		relative	0		0x1
1024  *			offset	0		0xFFFFFFFF
1025  *			pattern	{0x08, 0x06}		{0xFF, 0xFF}
1026  * RAW		relative	1		0x1
1027  *			offset	100		0xFFFFFFFF
1028  *			pattern	{0x11, 0x22, 0x33}	{0xFF, 0xFF, 0xFF}
1029  * END
1030  * other members in mask and spec should set to 0x00.
1031  * item->last should be NULL.
1032  */
1033 static int
1034 cons_parse_flex_filter(const struct rte_flow_attr *attr,
1035 				const struct rte_flow_item pattern[],
1036 				const struct rte_flow_action actions[],
1037 				struct rte_eth_flex_filter *filter,
1038 				struct rte_flow_error *error)
1039 {
1040 	const struct rte_flow_item *item;
1041 	const struct rte_flow_action *act;
1042 	const struct rte_flow_item_raw *raw_spec;
1043 	const struct rte_flow_item_raw *raw_mask;
1044 	const struct rte_flow_action_queue *act_q;
1045 	uint32_t index, i, offset, total_offset;
1046 	uint32_t max_offset = 0;
1047 	int32_t shift, j, raw_index = 0;
1048 	int32_t relative[IGB_FLEX_RAW_NUM] = {0};
1049 	int32_t	raw_offset[IGB_FLEX_RAW_NUM] = {0};
1050 
1051 	if (!pattern) {
1052 		rte_flow_error_set(error, EINVAL,
1053 				RTE_FLOW_ERROR_TYPE_ITEM_NUM,
1054 				NULL, "NULL pattern.");
1055 		return -rte_errno;
1056 	}
1057 
1058 	if (!actions) {
1059 		rte_flow_error_set(error, EINVAL,
1060 				RTE_FLOW_ERROR_TYPE_ACTION_NUM,
1061 				NULL, "NULL action.");
1062 		return -rte_errno;
1063 	}
1064 
1065 	if (!attr) {
1066 		rte_flow_error_set(error, EINVAL,
1067 				   RTE_FLOW_ERROR_TYPE_ATTR,
1068 				   NULL, "NULL attribute.");
1069 		return -rte_errno;
1070 	}
1071 
1072 	/* parse pattern */
1073 	index = 0;
1074 
1075 item_loop:
1076 
1077 	/* the first not void item should be RAW */
1078 	NEXT_ITEM_OF_PATTERN(item, pattern, index);
1079 	if (item->type != RTE_FLOW_ITEM_TYPE_RAW) {
1080 		rte_flow_error_set(error, EINVAL,
1081 				RTE_FLOW_ERROR_TYPE_ITEM,
1082 				item, "Not supported by flex filter");
1083 		return -rte_errno;
1084 	}
1085 		/*Not supported last point for range*/
1086 	if (item->last) {
1087 		rte_flow_error_set(error, EINVAL,
1088 			RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
1089 			item, "Not supported last point for range");
1090 		return -rte_errno;
1091 	}
1092 
1093 	raw_spec = item->spec;
1094 	raw_mask = item->mask;
1095 
1096 	if (!raw_mask->length ||
1097 	    !raw_mask->relative) {
1098 		memset(filter, 0, sizeof(struct rte_eth_flex_filter));
1099 		rte_flow_error_set(error, EINVAL,
1100 				RTE_FLOW_ERROR_TYPE_ITEM,
1101 				item, "Not supported by flex filter");
1102 		return -rte_errno;
1103 	}
1104 
1105 	if (raw_mask->offset)
1106 		offset = raw_spec->offset;
1107 	else
1108 		offset = 0;
1109 
1110 	for (j = 0; j < raw_spec->length; j++) {
1111 		if (raw_mask->pattern[j] != 0xFF) {
1112 			memset(filter, 0, sizeof(struct rte_eth_flex_filter));
1113 			rte_flow_error_set(error, EINVAL,
1114 					RTE_FLOW_ERROR_TYPE_ITEM,
1115 					item, "Not supported by flex filter");
1116 			return -rte_errno;
1117 		}
1118 	}
1119 
1120 	total_offset = 0;
1121 
1122 	if (raw_spec->relative) {
1123 		for (j = raw_index; j > 0; j--) {
1124 			total_offset += raw_offset[j - 1];
1125 			if (!relative[j - 1])
1126 				break;
1127 		}
1128 		if (total_offset + raw_spec->length + offset > max_offset)
1129 			max_offset = total_offset + raw_spec->length + offset;
1130 	} else {
1131 		if (raw_spec->length + offset > max_offset)
1132 			max_offset = raw_spec->length + offset;
1133 	}
1134 
1135 	if ((raw_spec->length + offset + total_offset) >
1136 			RTE_FLEX_FILTER_MAXLEN) {
1137 		memset(filter, 0, sizeof(struct rte_eth_flex_filter));
1138 		rte_flow_error_set(error, EINVAL,
1139 				RTE_FLOW_ERROR_TYPE_ITEM,
1140 				item, "Not supported by flex filter");
1141 		return -rte_errno;
1142 	}
1143 
1144 	if (raw_spec->relative == 0) {
1145 		for (j = 0; j < raw_spec->length; j++)
1146 			filter->bytes[offset + j] =
1147 			raw_spec->pattern[j];
1148 		j = offset / CHAR_BIT;
1149 		shift = offset % CHAR_BIT;
1150 	} else {
1151 		for (j = 0; j < raw_spec->length; j++)
1152 			filter->bytes[total_offset + offset + j] =
1153 				raw_spec->pattern[j];
1154 		j = (total_offset + offset) / CHAR_BIT;
1155 		shift = (total_offset + offset) % CHAR_BIT;
1156 	}
1157 
1158 	i = 0;
1159 
1160 	for ( ; shift < CHAR_BIT; shift++) {
1161 		filter->mask[j] |= (0x80 >> shift);
1162 		i++;
1163 		if (i == raw_spec->length)
1164 			break;
1165 		if (shift == (CHAR_BIT - 1)) {
1166 			j++;
1167 			shift = -1;
1168 		}
1169 	}
1170 
1171 	relative[raw_index] = raw_spec->relative;
1172 	raw_offset[raw_index] = offset + raw_spec->length;
1173 	raw_index++;
1174 
1175 	/* check if the next not void item is RAW */
1176 	index++;
1177 	NEXT_ITEM_OF_PATTERN(item, pattern, index);
1178 	if (item->type != RTE_FLOW_ITEM_TYPE_RAW &&
1179 		item->type != RTE_FLOW_ITEM_TYPE_END) {
1180 		rte_flow_error_set(error, EINVAL,
1181 				RTE_FLOW_ERROR_TYPE_ITEM,
1182 				item, "Not supported by flex filter");
1183 		return -rte_errno;
1184 	}
1185 
1186 	/* go back to parser */
1187 	if (item->type == RTE_FLOW_ITEM_TYPE_RAW) {
1188 		/* if the item is RAW, the content should be parse */
1189 		goto item_loop;
1190 	}
1191 
1192 	filter->len = RTE_ALIGN(max_offset, 8);
1193 
1194 	/* parse action */
1195 	index = 0;
1196 
1197 	/* check if the first not void action is QUEUE. */
1198 	NEXT_ITEM_OF_ACTION(act, actions, index);
1199 	if (act->type != RTE_FLOW_ACTION_TYPE_QUEUE) {
1200 		memset(filter, 0, sizeof(struct rte_eth_flex_filter));
1201 		rte_flow_error_set(error, EINVAL,
1202 				RTE_FLOW_ERROR_TYPE_ACTION,
1203 				act, "Not supported action.");
1204 		return -rte_errno;
1205 	}
1206 
1207 	act_q = (const struct rte_flow_action_queue *)act->conf;
1208 	filter->queue = act_q->index;
1209 
1210 	/* check if the next not void item is END */
1211 	index++;
1212 	NEXT_ITEM_OF_ACTION(act, actions, index);
1213 	if (act->type != RTE_FLOW_ACTION_TYPE_END) {
1214 		memset(filter, 0, sizeof(struct rte_eth_flex_filter));
1215 		rte_flow_error_set(error, EINVAL,
1216 				RTE_FLOW_ERROR_TYPE_ACTION,
1217 				act, "Not supported action.");
1218 		return -rte_errno;
1219 	}
1220 
1221 	/* parse attr */
1222 	/* must be input direction */
1223 	if (!attr->ingress) {
1224 		memset(filter, 0, sizeof(struct rte_eth_flex_filter));
1225 		rte_flow_error_set(error, EINVAL,
1226 			RTE_FLOW_ERROR_TYPE_ATTR_INGRESS,
1227 			attr, "Only support ingress.");
1228 		return -rte_errno;
1229 	}
1230 
1231 	/* not supported */
1232 	if (attr->egress) {
1233 		memset(filter, 0, sizeof(struct rte_eth_flex_filter));
1234 		rte_flow_error_set(error, EINVAL,
1235 			RTE_FLOW_ERROR_TYPE_ATTR_EGRESS,
1236 			attr, "Not support egress.");
1237 		return -rte_errno;
1238 	}
1239 
1240 	/* not supported */
1241 	if (attr->transfer) {
1242 		memset(filter, 0, sizeof(struct rte_eth_flex_filter));
1243 		rte_flow_error_set(error, EINVAL,
1244 			RTE_FLOW_ERROR_TYPE_ATTR_TRANSFER,
1245 			attr, "No support for transfer.");
1246 		return -rte_errno;
1247 	}
1248 
1249 	if (attr->priority > 0xFFFF) {
1250 		memset(filter, 0, sizeof(struct rte_eth_flex_filter));
1251 		rte_flow_error_set(error, EINVAL,
1252 				   RTE_FLOW_ERROR_TYPE_ATTR_PRIORITY,
1253 				   attr, "Error priority.");
1254 		return -rte_errno;
1255 	}
1256 
1257 	filter->priority = (uint16_t)attr->priority;
1258 
1259 	return 0;
1260 }
1261 
1262 static int
1263 igb_parse_flex_filter(struct rte_eth_dev *dev,
1264 				 const struct rte_flow_attr *attr,
1265 			     const struct rte_flow_item pattern[],
1266 			     const struct rte_flow_action actions[],
1267 			     struct rte_eth_flex_filter *filter,
1268 			     struct rte_flow_error *error)
1269 {
1270 	struct e1000_hw *hw = E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);
1271 	int ret;
1272 
1273 	MAC_TYPE_FILTER_SUP_EXT(hw->mac.type);
1274 
1275 	ret = cons_parse_flex_filter(attr, pattern,
1276 					actions, filter, error);
1277 
1278 	if (filter->queue >= IGB_MAX_RX_QUEUE_NUM) {
1279 		memset(filter, 0, sizeof(struct rte_eth_flex_filter));
1280 		rte_flow_error_set(error, EINVAL,
1281 			RTE_FLOW_ERROR_TYPE_ITEM,
1282 			NULL, "queue number not supported by flex filter");
1283 		return -rte_errno;
1284 	}
1285 
1286 	if (filter->len == 0 || filter->len > E1000_MAX_FLEX_FILTER_LEN ||
1287 		filter->len % sizeof(uint64_t) != 0) {
1288 		PMD_DRV_LOG(ERR, "filter's length is out of range");
1289 		return -EINVAL;
1290 	}
1291 
1292 	if (filter->priority > E1000_MAX_FLEX_FILTER_PRI) {
1293 		PMD_DRV_LOG(ERR, "filter's priority is out of range");
1294 		return -EINVAL;
1295 	}
1296 
1297 	if (ret)
1298 		return ret;
1299 
1300 	return 0;
1301 }
1302 
1303 static int
1304 igb_parse_rss_filter(struct rte_eth_dev *dev,
1305 			const struct rte_flow_attr *attr,
1306 			const struct rte_flow_action actions[],
1307 			struct igb_rte_flow_rss_conf *rss_conf,
1308 			struct rte_flow_error *error)
1309 {
1310 	struct e1000_hw *hw = E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);
1311 	const struct rte_flow_action *act;
1312 	const struct rte_flow_action_rss *rss;
1313 	uint16_t n, index;
1314 
1315 	/**
1316 	 * rss only supports forwarding,
1317 	 * check if the first not void action is RSS.
1318 	 */
1319 	index = 0;
1320 	NEXT_ITEM_OF_ACTION(act, actions, index);
1321 	if (act->type != RTE_FLOW_ACTION_TYPE_RSS) {
1322 		memset(rss_conf, 0, sizeof(struct igb_rte_flow_rss_conf));
1323 		rte_flow_error_set(error, EINVAL,
1324 			RTE_FLOW_ERROR_TYPE_ACTION,
1325 			act, "Not supported action.");
1326 		return -rte_errno;
1327 	}
1328 
1329 	rss = (const struct rte_flow_action_rss *)act->conf;
1330 
1331 	if (!rss || !rss->queue_num) {
1332 		rte_flow_error_set(error, EINVAL,
1333 				RTE_FLOW_ERROR_TYPE_ACTION,
1334 				act,
1335 			   "no valid queues");
1336 		return -rte_errno;
1337 	}
1338 
1339 	for (n = 0; n < rss->queue_num; n++) {
1340 		if (rss->queue[n] >= dev->data->nb_rx_queues) {
1341 			rte_flow_error_set(error, EINVAL,
1342 				   RTE_FLOW_ERROR_TYPE_ACTION,
1343 				   act,
1344 				   "queue id > max number of queues");
1345 			return -rte_errno;
1346 		}
1347 	}
1348 
1349 	if (rss->func != RTE_ETH_HASH_FUNCTION_DEFAULT)
1350 		return rte_flow_error_set
1351 			(error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ACTION, act,
1352 			 "non-default RSS hash functions are not supported");
1353 	if (rss->level)
1354 		return rte_flow_error_set
1355 			(error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ACTION, act,
1356 			 "a nonzero RSS encapsulation level is not supported");
1357 	if (rss->key_len && rss->key_len != RTE_DIM(rss_conf->key))
1358 		return rte_flow_error_set
1359 			(error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ACTION, act,
1360 			 "RSS hash key must be exactly 40 bytes");
1361 	if (((hw->mac.type == e1000_82576) &&
1362 	     (rss->queue_num > IGB_MAX_RX_QUEUE_NUM_82576)) ||
1363 	    ((hw->mac.type != e1000_82576) &&
1364 	     (rss->queue_num > IGB_MAX_RX_QUEUE_NUM)))
1365 		return rte_flow_error_set
1366 			(error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ACTION, act,
1367 			 "too many queues for RSS context");
1368 	if (igb_rss_conf_init(dev, rss_conf, rss))
1369 		return rte_flow_error_set
1370 			(error, EINVAL, RTE_FLOW_ERROR_TYPE_ACTION, act,
1371 			 "RSS context initialization failure");
1372 
1373 	/* check if the next not void item is END */
1374 	index++;
1375 	NEXT_ITEM_OF_ACTION(act, actions, index);
1376 	if (act->type != RTE_FLOW_ACTION_TYPE_END) {
1377 		memset(rss_conf, 0, sizeof(struct rte_eth_rss_conf));
1378 		rte_flow_error_set(error, EINVAL,
1379 			RTE_FLOW_ERROR_TYPE_ACTION,
1380 			act, "Not supported action.");
1381 		return -rte_errno;
1382 	}
1383 
1384 	/* parse attr */
1385 	/* must be input direction */
1386 	if (!attr->ingress) {
1387 		memset(rss_conf, 0, sizeof(struct igb_rte_flow_rss_conf));
1388 		rte_flow_error_set(error, EINVAL,
1389 				   RTE_FLOW_ERROR_TYPE_ATTR_INGRESS,
1390 				   attr, "Only support ingress.");
1391 		return -rte_errno;
1392 	}
1393 
1394 	/* not supported */
1395 	if (attr->egress) {
1396 		memset(rss_conf, 0, sizeof(struct igb_rte_flow_rss_conf));
1397 		rte_flow_error_set(error, EINVAL,
1398 				   RTE_FLOW_ERROR_TYPE_ATTR_EGRESS,
1399 				   attr, "Not support egress.");
1400 		return -rte_errno;
1401 	}
1402 
1403 	/* not supported */
1404 	if (attr->transfer) {
1405 		memset(rss_conf, 0, sizeof(struct igb_rte_flow_rss_conf));
1406 		rte_flow_error_set(error, EINVAL,
1407 				   RTE_FLOW_ERROR_TYPE_ATTR_TRANSFER,
1408 				   attr, "No support for transfer.");
1409 		return -rte_errno;
1410 	}
1411 
1412 	if (attr->priority > 0xFFFF) {
1413 		memset(rss_conf, 0, sizeof(struct igb_rte_flow_rss_conf));
1414 		rte_flow_error_set(error, EINVAL,
1415 				   RTE_FLOW_ERROR_TYPE_ATTR_PRIORITY,
1416 				   attr, "Error priority.");
1417 		return -rte_errno;
1418 	}
1419 
1420 	return 0;
1421 }
1422 
1423 /**
1424  * Create a flow rule.
1425  * Theorically one rule can match more than one filters.
1426  * We will let it use the filter which it hitt first.
1427  * So, the sequence matters.
1428  */
1429 static struct rte_flow *
1430 igb_flow_create(struct rte_eth_dev *dev,
1431 		  const struct rte_flow_attr *attr,
1432 		  const struct rte_flow_item pattern[],
1433 		  const struct rte_flow_action actions[],
1434 		  struct rte_flow_error *error)
1435 {
1436 	int ret;
1437 	struct rte_eth_ntuple_filter ntuple_filter;
1438 	struct rte_eth_ethertype_filter ethertype_filter;
1439 	struct rte_eth_syn_filter syn_filter;
1440 	struct rte_eth_flex_filter flex_filter;
1441 	struct igb_rte_flow_rss_conf rss_conf;
1442 	struct rte_flow *flow = NULL;
1443 	struct igb_ntuple_filter_ele *ntuple_filter_ptr;
1444 	struct igb_ethertype_filter_ele *ethertype_filter_ptr;
1445 	struct igb_eth_syn_filter_ele *syn_filter_ptr;
1446 	struct igb_flex_filter_ele *flex_filter_ptr;
1447 	struct igb_rss_conf_ele *rss_filter_ptr;
1448 	struct igb_flow_mem *igb_flow_mem_ptr;
1449 
1450 	flow = rte_zmalloc("igb_rte_flow", sizeof(struct rte_flow), 0);
1451 	if (!flow) {
1452 		PMD_DRV_LOG(ERR, "failed to allocate memory");
1453 		return (struct rte_flow *)flow;
1454 	}
1455 	igb_flow_mem_ptr = rte_zmalloc("igb_flow_mem",
1456 			sizeof(struct igb_flow_mem), 0);
1457 	if (!igb_flow_mem_ptr) {
1458 		PMD_DRV_LOG(ERR, "failed to allocate memory");
1459 		rte_free(flow);
1460 		return NULL;
1461 	}
1462 	igb_flow_mem_ptr->flow = flow;
1463 	igb_flow_mem_ptr->dev = dev;
1464 	TAILQ_INSERT_TAIL(&igb_flow_list,
1465 				igb_flow_mem_ptr, entries);
1466 
1467 	memset(&ntuple_filter, 0, sizeof(struct rte_eth_ntuple_filter));
1468 	ret = igb_parse_ntuple_filter(dev, attr, pattern,
1469 			actions, &ntuple_filter, error);
1470 	if (!ret) {
1471 		ret = igb_add_del_ntuple_filter(dev, &ntuple_filter, TRUE);
1472 		if (!ret) {
1473 			ntuple_filter_ptr = rte_zmalloc("igb_ntuple_filter",
1474 				sizeof(struct igb_ntuple_filter_ele), 0);
1475 			if (!ntuple_filter_ptr) {
1476 				PMD_DRV_LOG(ERR, "failed to allocate memory");
1477 				goto out;
1478 			}
1479 
1480 			rte_memcpy(&ntuple_filter_ptr->filter_info,
1481 				&ntuple_filter,
1482 				sizeof(struct rte_eth_ntuple_filter));
1483 			TAILQ_INSERT_TAIL(&igb_filter_ntuple_list,
1484 				ntuple_filter_ptr, entries);
1485 			flow->rule = ntuple_filter_ptr;
1486 			flow->filter_type = RTE_ETH_FILTER_NTUPLE;
1487 			return flow;
1488 		}
1489 		goto out;
1490 	}
1491 
1492 	memset(&ethertype_filter, 0, sizeof(struct rte_eth_ethertype_filter));
1493 	ret = igb_parse_ethertype_filter(dev, attr, pattern,
1494 				actions, &ethertype_filter, error);
1495 	if (!ret) {
1496 		ret = igb_add_del_ethertype_filter(dev,
1497 				&ethertype_filter, TRUE);
1498 		if (!ret) {
1499 			ethertype_filter_ptr = rte_zmalloc(
1500 				"igb_ethertype_filter",
1501 				sizeof(struct igb_ethertype_filter_ele), 0);
1502 			if (!ethertype_filter_ptr) {
1503 				PMD_DRV_LOG(ERR, "failed to allocate memory");
1504 				goto out;
1505 			}
1506 
1507 			rte_memcpy(&ethertype_filter_ptr->filter_info,
1508 				&ethertype_filter,
1509 				sizeof(struct rte_eth_ethertype_filter));
1510 			TAILQ_INSERT_TAIL(&igb_filter_ethertype_list,
1511 				ethertype_filter_ptr, entries);
1512 			flow->rule = ethertype_filter_ptr;
1513 			flow->filter_type = RTE_ETH_FILTER_ETHERTYPE;
1514 			return flow;
1515 		}
1516 		goto out;
1517 	}
1518 
1519 	memset(&syn_filter, 0, sizeof(struct rte_eth_syn_filter));
1520 	ret = igb_parse_syn_filter(dev, attr, pattern,
1521 				actions, &syn_filter, error);
1522 	if (!ret) {
1523 		ret = eth_igb_syn_filter_set(dev, &syn_filter, TRUE);
1524 		if (!ret) {
1525 			syn_filter_ptr = rte_zmalloc("igb_syn_filter",
1526 				sizeof(struct igb_eth_syn_filter_ele), 0);
1527 			if (!syn_filter_ptr) {
1528 				PMD_DRV_LOG(ERR, "failed to allocate memory");
1529 				goto out;
1530 			}
1531 
1532 			rte_memcpy(&syn_filter_ptr->filter_info,
1533 				&syn_filter,
1534 				sizeof(struct rte_eth_syn_filter));
1535 			TAILQ_INSERT_TAIL(&igb_filter_syn_list,
1536 				syn_filter_ptr,
1537 				entries);
1538 			flow->rule = syn_filter_ptr;
1539 			flow->filter_type = RTE_ETH_FILTER_SYN;
1540 			return flow;
1541 		}
1542 		goto out;
1543 	}
1544 
1545 	memset(&flex_filter, 0, sizeof(struct rte_eth_flex_filter));
1546 	ret = igb_parse_flex_filter(dev, attr, pattern,
1547 					actions, &flex_filter, error);
1548 	if (!ret) {
1549 		ret = eth_igb_add_del_flex_filter(dev, &flex_filter, TRUE);
1550 		if (!ret) {
1551 			flex_filter_ptr = rte_zmalloc("igb_flex_filter",
1552 				sizeof(struct igb_flex_filter_ele), 0);
1553 			if (!flex_filter_ptr) {
1554 				PMD_DRV_LOG(ERR, "failed to allocate memory");
1555 				goto out;
1556 			}
1557 
1558 			rte_memcpy(&flex_filter_ptr->filter_info,
1559 				&flex_filter,
1560 				sizeof(struct rte_eth_flex_filter));
1561 			TAILQ_INSERT_TAIL(&igb_filter_flex_list,
1562 				flex_filter_ptr, entries);
1563 			flow->rule = flex_filter_ptr;
1564 			flow->filter_type = RTE_ETH_FILTER_FLEXIBLE;
1565 			return flow;
1566 		}
1567 	}
1568 
1569 	memset(&rss_conf, 0, sizeof(struct igb_rte_flow_rss_conf));
1570 	ret = igb_parse_rss_filter(dev, attr,
1571 					actions, &rss_conf, error);
1572 	if (!ret) {
1573 		ret = igb_config_rss_filter(dev, &rss_conf, TRUE);
1574 		if (!ret) {
1575 			rss_filter_ptr = rte_zmalloc("igb_rss_filter",
1576 				sizeof(struct igb_rss_conf_ele), 0);
1577 			if (!rss_filter_ptr) {
1578 				PMD_DRV_LOG(ERR, "failed to allocate memory");
1579 				goto out;
1580 			}
1581 			igb_rss_conf_init(dev, &rss_filter_ptr->filter_info,
1582 					  &rss_conf.conf);
1583 			TAILQ_INSERT_TAIL(&igb_filter_rss_list,
1584 				rss_filter_ptr, entries);
1585 			flow->rule = rss_filter_ptr;
1586 			flow->filter_type = RTE_ETH_FILTER_HASH;
1587 			return flow;
1588 		}
1589 	}
1590 
1591 out:
1592 	TAILQ_REMOVE(&igb_flow_list,
1593 		igb_flow_mem_ptr, entries);
1594 	rte_flow_error_set(error, -ret,
1595 			   RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
1596 			   "Failed to create flow.");
1597 	rte_free(igb_flow_mem_ptr);
1598 	rte_free(flow);
1599 	return NULL;
1600 }
1601 
1602 /**
1603  * Check if the flow rule is supported by igb.
1604  * It only checkes the format. Don't guarantee the rule can be programmed into
1605  * the HW. Because there can be no enough room for the rule.
1606  */
1607 static int
1608 igb_flow_validate(__rte_unused struct rte_eth_dev *dev,
1609 		const struct rte_flow_attr *attr,
1610 		const struct rte_flow_item pattern[],
1611 		const struct rte_flow_action actions[],
1612 		struct rte_flow_error *error)
1613 {
1614 	struct rte_eth_ntuple_filter ntuple_filter;
1615 	struct rte_eth_ethertype_filter ethertype_filter;
1616 	struct rte_eth_syn_filter syn_filter;
1617 	struct rte_eth_flex_filter flex_filter;
1618 	struct igb_rte_flow_rss_conf rss_conf;
1619 	int ret;
1620 
1621 	memset(&ntuple_filter, 0, sizeof(struct rte_eth_ntuple_filter));
1622 	ret = igb_parse_ntuple_filter(dev, attr, pattern,
1623 				actions, &ntuple_filter, error);
1624 	if (!ret)
1625 		return 0;
1626 
1627 	memset(&ethertype_filter, 0, sizeof(struct rte_eth_ethertype_filter));
1628 	ret = igb_parse_ethertype_filter(dev, attr, pattern,
1629 				actions, &ethertype_filter, error);
1630 	if (!ret)
1631 		return 0;
1632 
1633 	memset(&syn_filter, 0, sizeof(struct rte_eth_syn_filter));
1634 	ret = igb_parse_syn_filter(dev, attr, pattern,
1635 				actions, &syn_filter, error);
1636 	if (!ret)
1637 		return 0;
1638 
1639 	memset(&flex_filter, 0, sizeof(struct rte_eth_flex_filter));
1640 	ret = igb_parse_flex_filter(dev, attr, pattern,
1641 				actions, &flex_filter, error);
1642 	if (!ret)
1643 		return 0;
1644 
1645 	memset(&rss_conf, 0, sizeof(struct igb_rte_flow_rss_conf));
1646 	ret = igb_parse_rss_filter(dev, attr,
1647 					actions, &rss_conf, error);
1648 
1649 	return ret;
1650 }
1651 
1652 /* Destroy a flow rule on igb. */
1653 static int
1654 igb_flow_destroy(struct rte_eth_dev *dev,
1655 		struct rte_flow *flow,
1656 		struct rte_flow_error *error)
1657 {
1658 	int ret;
1659 	struct rte_flow *pmd_flow = flow;
1660 	enum rte_filter_type filter_type = pmd_flow->filter_type;
1661 	struct igb_ntuple_filter_ele *ntuple_filter_ptr;
1662 	struct igb_ethertype_filter_ele *ethertype_filter_ptr;
1663 	struct igb_eth_syn_filter_ele *syn_filter_ptr;
1664 	struct igb_flex_filter_ele *flex_filter_ptr;
1665 	struct igb_flow_mem *igb_flow_mem_ptr;
1666 	struct igb_rss_conf_ele *rss_filter_ptr;
1667 
1668 	switch (filter_type) {
1669 	case RTE_ETH_FILTER_NTUPLE:
1670 		ntuple_filter_ptr = (struct igb_ntuple_filter_ele *)
1671 					pmd_flow->rule;
1672 		ret = igb_add_del_ntuple_filter(dev,
1673 				&ntuple_filter_ptr->filter_info, FALSE);
1674 		if (!ret) {
1675 			TAILQ_REMOVE(&igb_filter_ntuple_list,
1676 			ntuple_filter_ptr, entries);
1677 			rte_free(ntuple_filter_ptr);
1678 		}
1679 		break;
1680 	case RTE_ETH_FILTER_ETHERTYPE:
1681 		ethertype_filter_ptr = (struct igb_ethertype_filter_ele *)
1682 					pmd_flow->rule;
1683 		ret = igb_add_del_ethertype_filter(dev,
1684 				&ethertype_filter_ptr->filter_info, FALSE);
1685 		if (!ret) {
1686 			TAILQ_REMOVE(&igb_filter_ethertype_list,
1687 				ethertype_filter_ptr, entries);
1688 			rte_free(ethertype_filter_ptr);
1689 		}
1690 		break;
1691 	case RTE_ETH_FILTER_SYN:
1692 		syn_filter_ptr = (struct igb_eth_syn_filter_ele *)
1693 				pmd_flow->rule;
1694 		ret = eth_igb_syn_filter_set(dev,
1695 				&syn_filter_ptr->filter_info, FALSE);
1696 		if (!ret) {
1697 			TAILQ_REMOVE(&igb_filter_syn_list,
1698 				syn_filter_ptr, entries);
1699 			rte_free(syn_filter_ptr);
1700 		}
1701 		break;
1702 	case RTE_ETH_FILTER_FLEXIBLE:
1703 		flex_filter_ptr = (struct igb_flex_filter_ele *)
1704 				pmd_flow->rule;
1705 		ret = eth_igb_add_del_flex_filter(dev,
1706 				&flex_filter_ptr->filter_info, FALSE);
1707 		if (!ret) {
1708 			TAILQ_REMOVE(&igb_filter_flex_list,
1709 				flex_filter_ptr, entries);
1710 			rte_free(flex_filter_ptr);
1711 		}
1712 		break;
1713 	case RTE_ETH_FILTER_HASH:
1714 		rss_filter_ptr = (struct igb_rss_conf_ele *)
1715 				pmd_flow->rule;
1716 		ret = igb_config_rss_filter(dev,
1717 					&rss_filter_ptr->filter_info, FALSE);
1718 		if (!ret) {
1719 			TAILQ_REMOVE(&igb_filter_rss_list,
1720 				rss_filter_ptr, entries);
1721 			rte_free(rss_filter_ptr);
1722 		}
1723 		break;
1724 	default:
1725 		PMD_DRV_LOG(WARNING, "Filter type (%d) not supported",
1726 			    filter_type);
1727 		ret = -EINVAL;
1728 		break;
1729 	}
1730 
1731 	if (ret) {
1732 		rte_flow_error_set(error, EINVAL,
1733 				RTE_FLOW_ERROR_TYPE_HANDLE,
1734 				NULL, "Failed to destroy flow");
1735 		return ret;
1736 	}
1737 
1738 	TAILQ_FOREACH(igb_flow_mem_ptr, &igb_flow_list, entries) {
1739 		if (igb_flow_mem_ptr->flow == pmd_flow) {
1740 			TAILQ_REMOVE(&igb_flow_list,
1741 				igb_flow_mem_ptr, entries);
1742 			rte_free(igb_flow_mem_ptr);
1743 		}
1744 	}
1745 	rte_free(flow);
1746 
1747 	return ret;
1748 }
1749 
1750 /* remove all the n-tuple filters */
1751 static void
1752 igb_clear_all_ntuple_filter(struct rte_eth_dev *dev)
1753 {
1754 	struct e1000_filter_info *filter_info =
1755 		E1000_DEV_PRIVATE_TO_FILTER_INFO(dev->data->dev_private);
1756 	struct e1000_5tuple_filter *p_5tuple;
1757 	struct e1000_2tuple_filter *p_2tuple;
1758 
1759 	while ((p_5tuple = TAILQ_FIRST(&filter_info->fivetuple_list)))
1760 		igb_delete_5tuple_filter_82576(dev, p_5tuple);
1761 
1762 	while ((p_2tuple = TAILQ_FIRST(&filter_info->twotuple_list)))
1763 		igb_delete_2tuple_filter(dev, p_2tuple);
1764 }
1765 
1766 /* remove all the ether type filters */
1767 static void
1768 igb_clear_all_ethertype_filter(struct rte_eth_dev *dev)
1769 {
1770 	struct e1000_hw *hw = E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);
1771 	struct e1000_filter_info *filter_info =
1772 		E1000_DEV_PRIVATE_TO_FILTER_INFO(dev->data->dev_private);
1773 	int i;
1774 
1775 	for (i = 0; i < E1000_MAX_ETQF_FILTERS; i++) {
1776 		if (filter_info->ethertype_mask & (1 << i)) {
1777 			(void)igb_ethertype_filter_remove(filter_info,
1778 							    (uint8_t)i);
1779 			E1000_WRITE_REG(hw, E1000_ETQF(i), 0);
1780 			E1000_WRITE_FLUSH(hw);
1781 		}
1782 	}
1783 }
1784 
1785 /* remove the SYN filter */
1786 static void
1787 igb_clear_syn_filter(struct rte_eth_dev *dev)
1788 {
1789 	struct e1000_hw *hw = E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);
1790 	struct e1000_filter_info *filter_info =
1791 		E1000_DEV_PRIVATE_TO_FILTER_INFO(dev->data->dev_private);
1792 
1793 	if (filter_info->syn_info & E1000_SYN_FILTER_ENABLE) {
1794 		filter_info->syn_info = 0;
1795 		E1000_WRITE_REG(hw, E1000_SYNQF(0), 0);
1796 		E1000_WRITE_FLUSH(hw);
1797 	}
1798 }
1799 
1800 /* remove all the flex filters */
1801 static void
1802 igb_clear_all_flex_filter(struct rte_eth_dev *dev)
1803 {
1804 	struct e1000_filter_info *filter_info =
1805 		E1000_DEV_PRIVATE_TO_FILTER_INFO(dev->data->dev_private);
1806 	struct e1000_flex_filter *flex_filter;
1807 
1808 	while ((flex_filter = TAILQ_FIRST(&filter_info->flex_list)))
1809 		igb_remove_flex_filter(dev, flex_filter);
1810 }
1811 
1812 /* remove the rss filter */
1813 static void
1814 igb_clear_rss_filter(struct rte_eth_dev *dev)
1815 {
1816 	struct e1000_filter_info *filter =
1817 		E1000_DEV_PRIVATE_TO_FILTER_INFO(dev->data->dev_private);
1818 
1819 	if (filter->rss_info.conf.queue_num)
1820 		igb_config_rss_filter(dev, &filter->rss_info, FALSE);
1821 }
1822 
1823 void
1824 igb_filterlist_flush(struct rte_eth_dev *dev)
1825 {
1826 	struct igb_ntuple_filter_ele *ntuple_filter_ptr;
1827 	struct igb_ethertype_filter_ele *ethertype_filter_ptr;
1828 	struct igb_eth_syn_filter_ele *syn_filter_ptr;
1829 	struct igb_flex_filter_ele *flex_filter_ptr;
1830 	struct igb_rss_conf_ele  *rss_filter_ptr;
1831 	struct igb_flow_mem *igb_flow_mem_ptr;
1832 	enum rte_filter_type filter_type;
1833 	struct rte_flow *pmd_flow;
1834 
1835 	TAILQ_FOREACH(igb_flow_mem_ptr, &igb_flow_list, entries) {
1836 		if (igb_flow_mem_ptr->dev == dev) {
1837 			pmd_flow = igb_flow_mem_ptr->flow;
1838 			filter_type = pmd_flow->filter_type;
1839 
1840 			switch (filter_type) {
1841 			case RTE_ETH_FILTER_NTUPLE:
1842 				ntuple_filter_ptr =
1843 				(struct igb_ntuple_filter_ele *)
1844 					pmd_flow->rule;
1845 				TAILQ_REMOVE(&igb_filter_ntuple_list,
1846 						ntuple_filter_ptr, entries);
1847 				rte_free(ntuple_filter_ptr);
1848 				break;
1849 			case RTE_ETH_FILTER_ETHERTYPE:
1850 				ethertype_filter_ptr =
1851 				(struct igb_ethertype_filter_ele *)
1852 					pmd_flow->rule;
1853 				TAILQ_REMOVE(&igb_filter_ethertype_list,
1854 						ethertype_filter_ptr, entries);
1855 				rte_free(ethertype_filter_ptr);
1856 				break;
1857 			case RTE_ETH_FILTER_SYN:
1858 				syn_filter_ptr =
1859 					(struct igb_eth_syn_filter_ele *)
1860 						pmd_flow->rule;
1861 				TAILQ_REMOVE(&igb_filter_syn_list,
1862 						syn_filter_ptr, entries);
1863 				rte_free(syn_filter_ptr);
1864 				break;
1865 			case RTE_ETH_FILTER_FLEXIBLE:
1866 				flex_filter_ptr =
1867 					(struct igb_flex_filter_ele *)
1868 						pmd_flow->rule;
1869 				TAILQ_REMOVE(&igb_filter_flex_list,
1870 						flex_filter_ptr, entries);
1871 				rte_free(flex_filter_ptr);
1872 				break;
1873 			case RTE_ETH_FILTER_HASH:
1874 				rss_filter_ptr =
1875 					(struct igb_rss_conf_ele *)
1876 						pmd_flow->rule;
1877 				TAILQ_REMOVE(&igb_filter_rss_list,
1878 						rss_filter_ptr, entries);
1879 				rte_free(rss_filter_ptr);
1880 				break;
1881 			default:
1882 				PMD_DRV_LOG(WARNING, "Filter type"
1883 					"(%d) not supported", filter_type);
1884 				break;
1885 			}
1886 			TAILQ_REMOVE(&igb_flow_list,
1887 				 igb_flow_mem_ptr,
1888 				 entries);
1889 			rte_free(igb_flow_mem_ptr->flow);
1890 			rte_free(igb_flow_mem_ptr);
1891 		}
1892 	}
1893 }
1894 
1895 /*  Destroy all flow rules associated with a port on igb. */
1896 static int
1897 igb_flow_flush(struct rte_eth_dev *dev,
1898 		__rte_unused struct rte_flow_error *error)
1899 {
1900 	igb_clear_all_ntuple_filter(dev);
1901 	igb_clear_all_ethertype_filter(dev);
1902 	igb_clear_syn_filter(dev);
1903 	igb_clear_all_flex_filter(dev);
1904 	igb_clear_rss_filter(dev);
1905 	igb_filterlist_flush(dev);
1906 
1907 	return 0;
1908 }
1909 
1910 const struct rte_flow_ops igb_flow_ops = {
1911 	.validate = igb_flow_validate,
1912 	.create = igb_flow_create,
1913 	.destroy = igb_flow_destroy,
1914 	.flush = igb_flow_flush,
1915 };
1916