xref: /dpdk/drivers/net/ice/ice_generic_flow.c (revision 85cf6dc3)
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2019 Intel Corporation
3  */
4 
5 #include <sys/queue.h>
6 #include <stdio.h>
7 #include <errno.h>
8 #include <stdint.h>
9 #include <string.h>
10 #include <unistd.h>
11 #include <stdarg.h>
12 
13 #include <rte_ether.h>
14 #include <rte_ethdev_driver.h>
15 #include <rte_malloc.h>
16 
17 #include "ice_ethdev.h"
18 #include "ice_generic_flow.h"
19 #include "ice_switch_filter.h"
20 
21 static int ice_flow_validate(struct rte_eth_dev *dev,
22 		const struct rte_flow_attr *attr,
23 		const struct rte_flow_item pattern[],
24 		const struct rte_flow_action actions[],
25 		struct rte_flow_error *error);
26 static struct rte_flow *ice_flow_create(struct rte_eth_dev *dev,
27 		const struct rte_flow_attr *attr,
28 		const struct rte_flow_item pattern[],
29 		const struct rte_flow_action actions[],
30 		struct rte_flow_error *error);
31 static int ice_flow_destroy(struct rte_eth_dev *dev,
32 		struct rte_flow *flow,
33 		struct rte_flow_error *error);
34 static int ice_flow_flush(struct rte_eth_dev *dev,
35 		struct rte_flow_error *error);
36 
37 const struct rte_flow_ops ice_flow_ops = {
38 	.validate = ice_flow_validate,
39 	.create = ice_flow_create,
40 	.destroy = ice_flow_destroy,
41 	.flush = ice_flow_flush,
42 };
43 
44 static int
45 ice_flow_valid_attr(const struct rte_flow_attr *attr,
46 		     struct rte_flow_error *error)
47 {
48 	/* Must be input direction */
49 	if (!attr->ingress) {
50 		rte_flow_error_set(error, EINVAL,
51 				   RTE_FLOW_ERROR_TYPE_ATTR_INGRESS,
52 				   attr, "Only support ingress.");
53 		return -rte_errno;
54 	}
55 
56 	/* Not supported */
57 	if (attr->egress) {
58 		rte_flow_error_set(error, EINVAL,
59 				   RTE_FLOW_ERROR_TYPE_ATTR_EGRESS,
60 				   attr, "Not support egress.");
61 		return -rte_errno;
62 	}
63 
64 	/* Not supported */
65 	if (attr->priority) {
66 		rte_flow_error_set(error, EINVAL,
67 				   RTE_FLOW_ERROR_TYPE_ATTR_PRIORITY,
68 				   attr, "Not support priority.");
69 		return -rte_errno;
70 	}
71 
72 	/* Not supported */
73 	if (attr->group) {
74 		rte_flow_error_set(error, EINVAL,
75 				   RTE_FLOW_ERROR_TYPE_ATTR_GROUP,
76 				   attr, "Not support group.");
77 		return -rte_errno;
78 	}
79 
80 	return 0;
81 }
82 
83 /* Find the first VOID or non-VOID item pointer */
84 static const struct rte_flow_item *
85 ice_find_first_item(const struct rte_flow_item *item, bool is_void)
86 {
87 	bool is_find;
88 
89 	while (item->type != RTE_FLOW_ITEM_TYPE_END) {
90 		if (is_void)
91 			is_find = item->type == RTE_FLOW_ITEM_TYPE_VOID;
92 		else
93 			is_find = item->type != RTE_FLOW_ITEM_TYPE_VOID;
94 		if (is_find)
95 			break;
96 		item++;
97 	}
98 	return item;
99 }
100 
101 /* Skip all VOID items of the pattern */
102 static void
103 ice_pattern_skip_void_item(struct rte_flow_item *items,
104 			    const struct rte_flow_item *pattern)
105 {
106 	uint32_t cpy_count = 0;
107 	const struct rte_flow_item *pb = pattern, *pe = pattern;
108 
109 	for (;;) {
110 		/* Find a non-void item first */
111 		pb = ice_find_first_item(pb, false);
112 		if (pb->type == RTE_FLOW_ITEM_TYPE_END) {
113 			pe = pb;
114 			break;
115 		}
116 
117 		/* Find a void item */
118 		pe = ice_find_first_item(pb + 1, true);
119 
120 		cpy_count = pe - pb;
121 		rte_memcpy(items, pb, sizeof(struct rte_flow_item) * cpy_count);
122 
123 		items += cpy_count;
124 
125 		if (pe->type == RTE_FLOW_ITEM_TYPE_END) {
126 			pb = pe;
127 			break;
128 		}
129 
130 		pb = pe + 1;
131 	}
132 	/* Copy the END item. */
133 	rte_memcpy(items, pe, sizeof(struct rte_flow_item));
134 }
135 
136 /* Check if the pattern matches a supported item type array */
137 static bool
138 ice_match_pattern(enum rte_flow_item_type *item_array,
139 		const struct rte_flow_item *pattern)
140 {
141 	const struct rte_flow_item *item = pattern;
142 
143 	while ((*item_array == item->type) &&
144 	       (*item_array != RTE_FLOW_ITEM_TYPE_END)) {
145 		item_array++;
146 		item++;
147 	}
148 
149 	return (*item_array == RTE_FLOW_ITEM_TYPE_END &&
150 		item->type == RTE_FLOW_ITEM_TYPE_END);
151 }
152 
153 static uint64_t ice_flow_valid_pattern(const struct rte_flow_item pattern[],
154 		struct rte_flow_error *error)
155 {
156 	uint16_t i = 0;
157 	uint64_t inset;
158 	struct rte_flow_item *items; /* used for pattern without VOID items */
159 	uint32_t item_num = 0; /* non-void item number */
160 
161 	/* Get the non-void item number of pattern */
162 	while ((pattern + i)->type != RTE_FLOW_ITEM_TYPE_END) {
163 		if ((pattern + i)->type != RTE_FLOW_ITEM_TYPE_VOID)
164 			item_num++;
165 		i++;
166 	}
167 	item_num++;
168 
169 	items = rte_zmalloc("ice_pattern",
170 			    item_num * sizeof(struct rte_flow_item), 0);
171 	if (!items) {
172 		rte_flow_error_set(error, ENOMEM, RTE_FLOW_ERROR_TYPE_ITEM_NUM,
173 				   NULL, "No memory for PMD internal items.");
174 		return -ENOMEM;
175 	}
176 
177 	ice_pattern_skip_void_item(items, pattern);
178 
179 	for (i = 0; i < RTE_DIM(ice_supported_patterns); i++)
180 		if (ice_match_pattern(ice_supported_patterns[i].items,
181 				      items)) {
182 			inset = ice_supported_patterns[i].sw_fields;
183 			rte_free(items);
184 			return inset;
185 		}
186 	rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_ITEM,
187 			   pattern, "Unsupported pattern");
188 
189 	rte_free(items);
190 	return 0;
191 }
192 
193 static uint64_t ice_get_flow_field(const struct rte_flow_item pattern[],
194 			struct rte_flow_error *error)
195 {
196 	const struct rte_flow_item *item = pattern;
197 	const struct rte_flow_item_eth *eth_spec, *eth_mask;
198 	const struct rte_flow_item_ipv4 *ipv4_spec, *ipv4_mask;
199 	const struct rte_flow_item_ipv6 *ipv6_spec, *ipv6_mask;
200 	const struct rte_flow_item_tcp *tcp_spec, *tcp_mask;
201 	const struct rte_flow_item_udp *udp_spec, *udp_mask;
202 	const struct rte_flow_item_sctp *sctp_spec, *sctp_mask;
203 	const struct rte_flow_item_icmp *icmp_mask;
204 	const struct rte_flow_item_icmp6 *icmp6_mask;
205 	const struct rte_flow_item_vxlan *vxlan_spec, *vxlan_mask;
206 	const struct rte_flow_item_nvgre *nvgre_spec, *nvgre_mask;
207 	enum rte_flow_item_type item_type;
208 	uint8_t  ipv6_addr_mask[16] = {
209 		0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
210 		0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
211 	uint64_t input_set = ICE_INSET_NONE;
212 	bool outer_ip = true;
213 	bool outer_l4 = true;
214 
215 	for (; item->type != RTE_FLOW_ITEM_TYPE_END; item++) {
216 		if (item->last) {
217 			rte_flow_error_set(error, EINVAL,
218 					   RTE_FLOW_ERROR_TYPE_ITEM,
219 					   item,
220 					   "Not support range");
221 			return 0;
222 		}
223 		item_type = item->type;
224 		switch (item_type) {
225 		case RTE_FLOW_ITEM_TYPE_ETH:
226 			eth_spec = item->spec;
227 			eth_mask = item->mask;
228 
229 			if (eth_spec && eth_mask) {
230 				if (rte_is_broadcast_ether_addr(&eth_mask->src))
231 					input_set |= ICE_INSET_SMAC;
232 				if (rte_is_broadcast_ether_addr(&eth_mask->dst))
233 					input_set |= ICE_INSET_DMAC;
234 				if (eth_mask->type == RTE_BE16(0xffff))
235 					input_set |= ICE_INSET_ETHERTYPE;
236 			}
237 			break;
238 		case RTE_FLOW_ITEM_TYPE_IPV4:
239 			ipv4_spec = item->spec;
240 			ipv4_mask = item->mask;
241 
242 			if (!(ipv4_spec && ipv4_mask)) {
243 				rte_flow_error_set(error, EINVAL,
244 					   RTE_FLOW_ERROR_TYPE_ITEM,
245 					   item,
246 					   "Invalid IPv4 spec or mask.");
247 				return 0;
248 			}
249 
250 			/* Check IPv4 mask and update input set */
251 			if (ipv4_mask->hdr.version_ihl ||
252 			    ipv4_mask->hdr.total_length ||
253 			    ipv4_mask->hdr.packet_id ||
254 			    ipv4_mask->hdr.hdr_checksum) {
255 				rte_flow_error_set(error, EINVAL,
256 					   RTE_FLOW_ERROR_TYPE_ITEM,
257 					   item,
258 					   "Invalid IPv4 mask.");
259 				return 0;
260 			}
261 
262 			if (outer_ip) {
263 				if (ipv4_mask->hdr.src_addr == UINT32_MAX)
264 					input_set |= ICE_INSET_IPV4_SRC;
265 				if (ipv4_mask->hdr.dst_addr == UINT32_MAX)
266 					input_set |= ICE_INSET_IPV4_DST;
267 				if (ipv4_mask->hdr.type_of_service == UINT8_MAX)
268 					input_set |= ICE_INSET_IPV4_TOS;
269 				if (ipv4_mask->hdr.time_to_live == UINT8_MAX)
270 					input_set |= ICE_INSET_IPV4_TTL;
271 				if (ipv4_mask->hdr.next_proto_id == UINT8_MAX)
272 					input_set |= ICE_INSET_IPV4_PROTO;
273 				outer_ip = false;
274 			} else {
275 				if (ipv4_mask->hdr.src_addr == UINT32_MAX)
276 					input_set |= ICE_INSET_TUN_IPV4_SRC;
277 				if (ipv4_mask->hdr.dst_addr == UINT32_MAX)
278 					input_set |= ICE_INSET_TUN_IPV4_DST;
279 				if (ipv4_mask->hdr.time_to_live == UINT8_MAX)
280 					input_set |= ICE_INSET_TUN_IPV4_TTL;
281 				if (ipv4_mask->hdr.next_proto_id == UINT8_MAX)
282 					input_set |= ICE_INSET_TUN_IPV4_PROTO;
283 			}
284 			break;
285 		case RTE_FLOW_ITEM_TYPE_IPV6:
286 			ipv6_spec = item->spec;
287 			ipv6_mask = item->mask;
288 
289 			if (!(ipv6_spec && ipv6_mask)) {
290 				rte_flow_error_set(error, EINVAL,
291 					RTE_FLOW_ERROR_TYPE_ITEM,
292 					item, "Invalid IPv6 spec or mask");
293 				return 0;
294 			}
295 
296 			if (ipv6_mask->hdr.payload_len ||
297 			    ipv6_mask->hdr.vtc_flow) {
298 				rte_flow_error_set(error, EINVAL,
299 					   RTE_FLOW_ERROR_TYPE_ITEM,
300 					   item,
301 					   "Invalid IPv6 mask");
302 				return 0;
303 			}
304 
305 			if (outer_ip) {
306 				if (!memcmp(ipv6_mask->hdr.src_addr,
307 					    ipv6_addr_mask,
308 					    RTE_DIM(ipv6_mask->hdr.src_addr)))
309 					input_set |= ICE_INSET_IPV6_SRC;
310 				if (!memcmp(ipv6_mask->hdr.dst_addr,
311 					    ipv6_addr_mask,
312 					    RTE_DIM(ipv6_mask->hdr.dst_addr)))
313 					input_set |= ICE_INSET_IPV6_DST;
314 				if (ipv6_mask->hdr.proto == UINT8_MAX)
315 					input_set |= ICE_INSET_IPV6_PROTO;
316 				if (ipv6_mask->hdr.hop_limits == UINT8_MAX)
317 					input_set |= ICE_INSET_IPV6_HOP_LIMIT;
318 				outer_ip = false;
319 			} else {
320 				if (!memcmp(ipv6_mask->hdr.src_addr,
321 					    ipv6_addr_mask,
322 					    RTE_DIM(ipv6_mask->hdr.src_addr)))
323 					input_set |= ICE_INSET_TUN_IPV6_SRC;
324 				if (!memcmp(ipv6_mask->hdr.dst_addr,
325 					    ipv6_addr_mask,
326 					    RTE_DIM(ipv6_mask->hdr.dst_addr)))
327 					input_set |= ICE_INSET_TUN_IPV6_DST;
328 				if (ipv6_mask->hdr.proto == UINT8_MAX)
329 					input_set |= ICE_INSET_TUN_IPV6_PROTO;
330 				if (ipv6_mask->hdr.hop_limits == UINT8_MAX)
331 					input_set |= ICE_INSET_TUN_IPV6_TTL;
332 			}
333 
334 			break;
335 		case RTE_FLOW_ITEM_TYPE_UDP:
336 			udp_spec = item->spec;
337 			udp_mask = item->mask;
338 
339 			if (!(udp_spec && udp_mask)) {
340 				rte_flow_error_set(error, EINVAL,
341 						   RTE_FLOW_ERROR_TYPE_ITEM,
342 						   item, "Invalid UDP mask");
343 				return 0;
344 			}
345 
346 			/* Check UDP mask and update input set*/
347 			if (udp_mask->hdr.dgram_len ||
348 			    udp_mask->hdr.dgram_cksum) {
349 				rte_flow_error_set(error, EINVAL,
350 						   RTE_FLOW_ERROR_TYPE_ITEM,
351 						   item,
352 						   "Invalid UDP mask");
353 				return 0;
354 			}
355 
356 			if (outer_l4) {
357 				if (udp_mask->hdr.src_port == UINT16_MAX)
358 					input_set |= ICE_INSET_SRC_PORT;
359 				if (udp_mask->hdr.dst_port == UINT16_MAX)
360 					input_set |= ICE_INSET_DST_PORT;
361 				outer_l4 = false;
362 			} else {
363 				if (udp_mask->hdr.src_port == UINT16_MAX)
364 					input_set |= ICE_INSET_TUN_SRC_PORT;
365 				if (udp_mask->hdr.dst_port == UINT16_MAX)
366 					input_set |= ICE_INSET_TUN_DST_PORT;
367 			}
368 
369 			break;
370 		case RTE_FLOW_ITEM_TYPE_TCP:
371 			tcp_spec = item->spec;
372 			tcp_mask = item->mask;
373 
374 			if (!(tcp_spec && tcp_mask)) {
375 				rte_flow_error_set(error, EINVAL,
376 						   RTE_FLOW_ERROR_TYPE_ITEM,
377 						   item, "Invalid TCP mask");
378 				return 0;
379 			}
380 
381 			/* Check TCP mask and update input set */
382 			if (tcp_mask->hdr.sent_seq ||
383 			    tcp_mask->hdr.recv_ack ||
384 			    tcp_mask->hdr.data_off ||
385 			    tcp_mask->hdr.tcp_flags ||
386 			    tcp_mask->hdr.rx_win ||
387 			    tcp_mask->hdr.cksum ||
388 			    tcp_mask->hdr.tcp_urp) {
389 				rte_flow_error_set(error, EINVAL,
390 						   RTE_FLOW_ERROR_TYPE_ITEM,
391 						   item,
392 						   "Invalid TCP mask");
393 				return 0;
394 			}
395 
396 			if (outer_l4) {
397 				if (tcp_mask->hdr.src_port == UINT16_MAX)
398 					input_set |= ICE_INSET_SRC_PORT;
399 				if (tcp_mask->hdr.dst_port == UINT16_MAX)
400 					input_set |= ICE_INSET_DST_PORT;
401 				outer_l4 = false;
402 			} else {
403 				if (tcp_mask->hdr.src_port == UINT16_MAX)
404 					input_set |= ICE_INSET_TUN_SRC_PORT;
405 				if (tcp_mask->hdr.dst_port == UINT16_MAX)
406 					input_set |= ICE_INSET_TUN_DST_PORT;
407 			}
408 
409 			break;
410 		case RTE_FLOW_ITEM_TYPE_SCTP:
411 			sctp_spec = item->spec;
412 			sctp_mask = item->mask;
413 
414 			if (!(sctp_spec && sctp_mask)) {
415 				rte_flow_error_set(error, EINVAL,
416 						   RTE_FLOW_ERROR_TYPE_ITEM,
417 						   item, "Invalid SCTP mask");
418 				return 0;
419 			}
420 
421 			/* Check SCTP mask and update input set */
422 			if (sctp_mask->hdr.cksum) {
423 				rte_flow_error_set(error, EINVAL,
424 					   RTE_FLOW_ERROR_TYPE_ITEM,
425 					   item,
426 					   "Invalid SCTP mask");
427 				return 0;
428 			}
429 
430 			if (outer_l4) {
431 				if (sctp_mask->hdr.src_port == UINT16_MAX)
432 					input_set |= ICE_INSET_SRC_PORT;
433 				if (sctp_mask->hdr.dst_port == UINT16_MAX)
434 					input_set |= ICE_INSET_DST_PORT;
435 				outer_l4 = false;
436 			} else {
437 				if (sctp_mask->hdr.src_port == UINT16_MAX)
438 					input_set |= ICE_INSET_TUN_SRC_PORT;
439 				if (sctp_mask->hdr.dst_port == UINT16_MAX)
440 					input_set |= ICE_INSET_TUN_DST_PORT;
441 			}
442 
443 			break;
444 		case RTE_FLOW_ITEM_TYPE_ICMP:
445 			icmp_mask = item->mask;
446 			if (icmp_mask->hdr.icmp_code ||
447 			    icmp_mask->hdr.icmp_cksum ||
448 			    icmp_mask->hdr.icmp_ident ||
449 			    icmp_mask->hdr.icmp_seq_nb) {
450 				rte_flow_error_set(error, EINVAL,
451 						   RTE_FLOW_ERROR_TYPE_ITEM,
452 						   item,
453 						   "Invalid ICMP mask");
454 				return 0;
455 			}
456 
457 			if (icmp_mask->hdr.icmp_type == UINT8_MAX)
458 				input_set |= ICE_INSET_ICMP;
459 			break;
460 		case RTE_FLOW_ITEM_TYPE_ICMP6:
461 			icmp6_mask = item->mask;
462 			if (icmp6_mask->code ||
463 			    icmp6_mask->checksum) {
464 				rte_flow_error_set(error, EINVAL,
465 						   RTE_FLOW_ERROR_TYPE_ITEM,
466 						   item,
467 						   "Invalid ICMP6 mask");
468 				return 0;
469 			}
470 
471 			if (icmp6_mask->type == UINT8_MAX)
472 				input_set |= ICE_INSET_ICMP6;
473 			break;
474 		case RTE_FLOW_ITEM_TYPE_VXLAN:
475 			vxlan_spec = item->spec;
476 			vxlan_mask = item->mask;
477 			/* Check if VXLAN item is used to describe protocol.
478 			 * If yes, both spec and mask should be NULL.
479 			 * If no, both spec and mask shouldn't be NULL.
480 			 */
481 			if ((!vxlan_spec && vxlan_mask) ||
482 			    (vxlan_spec && !vxlan_mask)) {
483 				rte_flow_error_set(error, EINVAL,
484 					   RTE_FLOW_ERROR_TYPE_ITEM,
485 					   item,
486 					   "Invalid VXLAN item");
487 				return 0;
488 			}
489 
490 			break;
491 		case RTE_FLOW_ITEM_TYPE_NVGRE:
492 			nvgre_spec = item->spec;
493 			nvgre_mask = item->mask;
494 			/* Check if VXLAN item is used to describe protocol.
495 			 * If yes, both spec and mask should be NULL.
496 			 * If no, both spec and mask shouldn't be NULL.
497 			 */
498 			if ((!nvgre_spec && nvgre_mask) ||
499 			    (nvgre_spec && !nvgre_mask)) {
500 				rte_flow_error_set(error, EINVAL,
501 					   RTE_FLOW_ERROR_TYPE_ITEM,
502 					   item,
503 					   "Invalid NVGRE item");
504 				return 0;
505 			}
506 
507 			break;
508 		default:
509 			rte_flow_error_set(error, EINVAL,
510 					   RTE_FLOW_ERROR_TYPE_ITEM,
511 					   item,
512 					   "Invalid mask no exist");
513 			break;
514 		}
515 	}
516 	return input_set;
517 }
518 
519 static int ice_flow_valid_inset(const struct rte_flow_item pattern[],
520 			uint64_t inset, struct rte_flow_error *error)
521 {
522 	uint64_t fields;
523 
524 	/* get valid field */
525 	fields = ice_get_flow_field(pattern, error);
526 	if (!fields || fields & (~inset)) {
527 		rte_flow_error_set(error, EINVAL,
528 				   RTE_FLOW_ERROR_TYPE_ITEM_SPEC,
529 				   pattern,
530 				   "Invalid input set");
531 		return -rte_errno;
532 	}
533 
534 	return 0;
535 }
536 
537 static int ice_flow_valid_action(struct rte_eth_dev *dev,
538 				const struct rte_flow_action *actions,
539 				struct rte_flow_error *error)
540 {
541 	const struct rte_flow_action_queue *act_q;
542 	uint16_t queue;
543 
544 	switch (actions->type) {
545 	case RTE_FLOW_ACTION_TYPE_QUEUE:
546 		act_q = actions->conf;
547 		queue = act_q->index;
548 		if (queue >= dev->data->nb_rx_queues) {
549 			rte_flow_error_set(error, EINVAL,
550 					   RTE_FLOW_ERROR_TYPE_ACTION,
551 					   actions, "Invalid queue ID for"
552 					   " ethertype_filter.");
553 			return -rte_errno;
554 		}
555 		break;
556 	case RTE_FLOW_ACTION_TYPE_DROP:
557 		break;
558 	default:
559 		rte_flow_error_set(error, EINVAL,
560 				   RTE_FLOW_ERROR_TYPE_ACTION, actions,
561 				   "Invalid action.");
562 		return -rte_errno;
563 	}
564 
565 	return 0;
566 }
567 
568 static int
569 ice_flow_validate(struct rte_eth_dev *dev,
570 		   const struct rte_flow_attr *attr,
571 		   const struct rte_flow_item pattern[],
572 		   const struct rte_flow_action actions[],
573 		   struct rte_flow_error *error)
574 {
575 	uint64_t inset = 0;
576 	int ret = ICE_ERR_NOT_SUPPORTED;
577 
578 	if (!pattern) {
579 		rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_ITEM_NUM,
580 				   NULL, "NULL pattern.");
581 		return -rte_errno;
582 	}
583 
584 	if (!actions) {
585 		rte_flow_error_set(error, EINVAL,
586 				   RTE_FLOW_ERROR_TYPE_ACTION_NUM,
587 				   NULL, "NULL action.");
588 		return -rte_errno;
589 	}
590 
591 	if (!attr) {
592 		rte_flow_error_set(error, EINVAL,
593 				   RTE_FLOW_ERROR_TYPE_ATTR,
594 				   NULL, "NULL attribute.");
595 		return -rte_errno;
596 	}
597 
598 	ret = ice_flow_valid_attr(attr, error);
599 	if (!ret)
600 		return ret;
601 
602 	inset = ice_flow_valid_pattern(pattern, error);
603 	if (!inset)
604 		return -rte_errno;
605 
606 	ret = ice_flow_valid_inset(pattern, inset, error);
607 	if (ret)
608 		return ret;
609 
610 	ret = ice_flow_valid_action(dev, actions, error);
611 	if (ret)
612 		return ret;
613 
614 	return 0;
615 }
616 
617 static struct rte_flow *
618 ice_flow_create(struct rte_eth_dev *dev,
619 		 const struct rte_flow_attr *attr,
620 		 const struct rte_flow_item pattern[],
621 		 const struct rte_flow_action actions[],
622 		 struct rte_flow_error *error)
623 {
624 	struct ice_pf *pf = ICE_DEV_PRIVATE_TO_PF(dev->data->dev_private);
625 	struct rte_flow *flow = NULL;
626 	int ret;
627 
628 	flow = rte_zmalloc("ice_flow", sizeof(struct rte_flow), 0);
629 	if (!flow) {
630 		rte_flow_error_set(error, ENOMEM,
631 				   RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
632 				   "Failed to allocate memory");
633 		return flow;
634 	}
635 
636 	ret = ice_flow_validate(dev, attr, pattern, actions, error);
637 	if (ret < 0)
638 		goto free_flow;
639 
640 	ret = ice_create_switch_filter(pf, pattern, actions, flow, error);
641 	if (ret)
642 		goto free_flow;
643 
644 	TAILQ_INSERT_TAIL(&pf->flow_list, flow, node);
645 	return flow;
646 
647 free_flow:
648 	rte_flow_error_set(error, -ret,
649 			   RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
650 			   "Failed to create flow.");
651 	rte_free(flow);
652 	return NULL;
653 }
654 
655 static int
656 ice_flow_destroy(struct rte_eth_dev *dev,
657 		 struct rte_flow *flow,
658 		 struct rte_flow_error *error)
659 {
660 	struct ice_pf *pf = ICE_DEV_PRIVATE_TO_PF(dev->data->dev_private);
661 	int ret = 0;
662 
663 	ret = ice_destroy_switch_filter(pf, flow, error);
664 
665 	if (!ret) {
666 		TAILQ_REMOVE(&pf->flow_list, flow, node);
667 		rte_free(flow);
668 	} else {
669 		rte_flow_error_set(error, -ret,
670 				   RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
671 				   "Failed to destroy flow.");
672 	}
673 
674 	return ret;
675 }
676 
677 static int
678 ice_flow_flush(struct rte_eth_dev *dev,
679 	       struct rte_flow_error *error)
680 {
681 	struct ice_pf *pf = ICE_DEV_PRIVATE_TO_PF(dev->data->dev_private);
682 	struct rte_flow *p_flow;
683 	int ret = 0;
684 
685 	TAILQ_FOREACH(p_flow, &pf->flow_list, node) {
686 		ret = ice_flow_destroy(dev, p_flow, error);
687 		if (ret) {
688 			rte_flow_error_set(error, -ret,
689 					   RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
690 					   "Failed to flush SW flows.");
691 			return -rte_errno;
692 		}
693 	}
694 
695 	return ret;
696 }
697