xref: /dpdk/drivers/net/sfc/sfc_flow.c (revision 9cd9d3e702fba4700539c1a2eddac13dd14ecf70)
1 /* SPDX-License-Identifier: BSD-3-Clause
2  *
3  * Copyright (c) 2017-2018 Solarflare Communications Inc.
4  * All rights reserved.
5  *
6  * This software was jointly developed between OKTET Labs (under contract
7  * for Solarflare) and Solarflare Communications, Inc.
8  */
9 
10 #include <rte_byteorder.h>
11 #include <rte_tailq.h>
12 #include <rte_common.h>
13 #include <rte_ethdev_driver.h>
14 #include <rte_ether.h>
15 #include <rte_flow.h>
16 #include <rte_flow_driver.h>
17 
18 #include "efx.h"
19 
20 #include "sfc.h"
21 #include "sfc_rx.h"
22 #include "sfc_filter.h"
23 #include "sfc_flow.h"
24 #include "sfc_log.h"
25 #include "sfc_dp_rx.h"
26 
27 struct sfc_flow_ops_by_spec {
28 	sfc_flow_parse_cb_t	*parse;
29 	sfc_flow_insert_cb_t	*insert;
30 	sfc_flow_remove_cb_t	*remove;
31 };
32 
33 static sfc_flow_parse_cb_t sfc_flow_parse_rte_to_filter;
34 static sfc_flow_insert_cb_t sfc_flow_filter_insert;
35 static sfc_flow_remove_cb_t sfc_flow_filter_remove;
36 
37 static const struct sfc_flow_ops_by_spec sfc_flow_ops_filter = {
38 	.parse = sfc_flow_parse_rte_to_filter,
39 	.insert = sfc_flow_filter_insert,
40 	.remove = sfc_flow_filter_remove,
41 };
42 
43 static const struct sfc_flow_ops_by_spec *
44 sfc_flow_get_ops_by_spec(struct rte_flow *flow)
45 {
46 	struct sfc_flow_spec *spec = &flow->spec;
47 	const struct sfc_flow_ops_by_spec *ops = NULL;
48 
49 	switch (spec->type) {
50 	case SFC_FLOW_SPEC_FILTER:
51 		ops = &sfc_flow_ops_filter;
52 		break;
53 	default:
54 		SFC_ASSERT(false);
55 		break;
56 	}
57 
58 	return ops;
59 }
60 
61 /*
62  * Currently, filter-based (VNIC) flow API is implemented in such a manner
63  * that each flow rule is converted to one or more hardware filters.
64  * All elements of flow rule (attributes, pattern items, actions)
65  * correspond to one or more fields in the efx_filter_spec_s structure
66  * that is responsible for the hardware filter.
67  * If some required field is unset in the flow rule, then a handful
68  * of filter copies will be created to cover all possible values
69  * of such a field.
70  */
71 
72 static sfc_flow_item_parse sfc_flow_parse_void;
73 static sfc_flow_item_parse sfc_flow_parse_eth;
74 static sfc_flow_item_parse sfc_flow_parse_vlan;
75 static sfc_flow_item_parse sfc_flow_parse_ipv4;
76 static sfc_flow_item_parse sfc_flow_parse_ipv6;
77 static sfc_flow_item_parse sfc_flow_parse_tcp;
78 static sfc_flow_item_parse sfc_flow_parse_udp;
79 static sfc_flow_item_parse sfc_flow_parse_vxlan;
80 static sfc_flow_item_parse sfc_flow_parse_geneve;
81 static sfc_flow_item_parse sfc_flow_parse_nvgre;
82 
83 typedef int (sfc_flow_spec_set_vals)(struct sfc_flow_spec *spec,
84 				     unsigned int filters_count_for_one_val,
85 				     struct rte_flow_error *error);
86 
87 typedef boolean_t (sfc_flow_spec_check)(efx_filter_match_flags_t match,
88 					efx_filter_spec_t *spec,
89 					struct sfc_filter *filter);
90 
91 struct sfc_flow_copy_flag {
92 	/* EFX filter specification match flag */
93 	efx_filter_match_flags_t flag;
94 	/* Number of values of corresponding field */
95 	unsigned int vals_count;
96 	/* Function to set values in specifications */
97 	sfc_flow_spec_set_vals *set_vals;
98 	/*
99 	 * Function to check that the specification is suitable
100 	 * for adding this match flag
101 	 */
102 	sfc_flow_spec_check *spec_check;
103 };
104 
105 static sfc_flow_spec_set_vals sfc_flow_set_unknown_dst_flags;
106 static sfc_flow_spec_check sfc_flow_check_unknown_dst_flags;
107 static sfc_flow_spec_set_vals sfc_flow_set_ethertypes;
108 static sfc_flow_spec_set_vals sfc_flow_set_ifrm_unknown_dst_flags;
109 static sfc_flow_spec_check sfc_flow_check_ifrm_unknown_dst_flags;
110 static sfc_flow_spec_set_vals sfc_flow_set_outer_vid_flag;
111 static sfc_flow_spec_check sfc_flow_check_outer_vid_flag;
112 
113 static boolean_t
114 sfc_flow_is_zero(const uint8_t *buf, unsigned int size)
115 {
116 	uint8_t sum = 0;
117 	unsigned int i;
118 
119 	for (i = 0; i < size; i++)
120 		sum |= buf[i];
121 
122 	return (sum == 0) ? B_TRUE : B_FALSE;
123 }
124 
125 /*
126  * Validate item and prepare structures spec and mask for parsing
127  */
128 int
129 sfc_flow_parse_init(const struct rte_flow_item *item,
130 		    const void **spec_ptr,
131 		    const void **mask_ptr,
132 		    const void *supp_mask,
133 		    const void *def_mask,
134 		    unsigned int size,
135 		    struct rte_flow_error *error)
136 {
137 	const uint8_t *spec;
138 	const uint8_t *mask;
139 	const uint8_t *last;
140 	uint8_t supp;
141 	unsigned int i;
142 
143 	if (item == NULL) {
144 		rte_flow_error_set(error, EINVAL,
145 				   RTE_FLOW_ERROR_TYPE_ITEM, NULL,
146 				   "NULL item");
147 		return -rte_errno;
148 	}
149 
150 	if ((item->last != NULL || item->mask != NULL) && item->spec == NULL) {
151 		rte_flow_error_set(error, EINVAL,
152 				   RTE_FLOW_ERROR_TYPE_ITEM, item,
153 				   "Mask or last is set without spec");
154 		return -rte_errno;
155 	}
156 
157 	/*
158 	 * If "mask" is not set, default mask is used,
159 	 * but if default mask is NULL, "mask" should be set
160 	 */
161 	if (item->mask == NULL) {
162 		if (def_mask == NULL) {
163 			rte_flow_error_set(error, EINVAL,
164 				RTE_FLOW_ERROR_TYPE_ITEM, NULL,
165 				"Mask should be specified");
166 			return -rte_errno;
167 		}
168 
169 		mask = def_mask;
170 	} else {
171 		mask = item->mask;
172 	}
173 
174 	spec = item->spec;
175 	last = item->last;
176 
177 	if (spec == NULL)
178 		goto exit;
179 
180 	/*
181 	 * If field values in "last" are either 0 or equal to the corresponding
182 	 * values in "spec" then they are ignored
183 	 */
184 	if (last != NULL &&
185 	    !sfc_flow_is_zero(last, size) &&
186 	    memcmp(last, spec, size) != 0) {
187 		rte_flow_error_set(error, ENOTSUP,
188 				   RTE_FLOW_ERROR_TYPE_ITEM, item,
189 				   "Ranging is not supported");
190 		return -rte_errno;
191 	}
192 
193 	if (supp_mask == NULL) {
194 		rte_flow_error_set(error, EINVAL,
195 			RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
196 			"Supported mask for item should be specified");
197 		return -rte_errno;
198 	}
199 
200 	/* Check that mask does not ask for more match than supp_mask */
201 	for (i = 0; i < size; i++) {
202 		supp = ((const uint8_t *)supp_mask)[i];
203 
204 		if (~supp & mask[i]) {
205 			rte_flow_error_set(error, ENOTSUP,
206 					   RTE_FLOW_ERROR_TYPE_ITEM, item,
207 					   "Item's field is not supported");
208 			return -rte_errno;
209 		}
210 	}
211 
212 exit:
213 	*spec_ptr = spec;
214 	*mask_ptr = mask;
215 	return 0;
216 }
217 
218 /*
219  * Protocol parsers.
220  * Masking is not supported, so masks in items should be either
221  * full or empty (zeroed) and set only for supported fields which
222  * are specified in the supp_mask.
223  */
224 
225 static int
226 sfc_flow_parse_void(__rte_unused const struct rte_flow_item *item,
227 		    __rte_unused struct sfc_flow_parse_ctx *parse_ctx,
228 		    __rte_unused struct rte_flow_error *error)
229 {
230 	return 0;
231 }
232 
233 /**
234  * Convert Ethernet item to EFX filter specification.
235  *
236  * @param item[in]
237  *   Item specification. Outer frame specification may only comprise
238  *   source/destination addresses and Ethertype field.
239  *   Inner frame specification may contain destination address only.
240  *   There is support for individual/group mask as well as for empty and full.
241  *   If the mask is NULL, default mask will be used. Ranging is not supported.
242  * @param efx_spec[in, out]
243  *   EFX filter specification to update.
244  * @param[out] error
245  *   Perform verbose error reporting if not NULL.
246  */
247 static int
248 sfc_flow_parse_eth(const struct rte_flow_item *item,
249 		   struct sfc_flow_parse_ctx *parse_ctx,
250 		   struct rte_flow_error *error)
251 {
252 	int rc;
253 	efx_filter_spec_t *efx_spec = parse_ctx->filter;
254 	const struct rte_flow_item_eth *spec = NULL;
255 	const struct rte_flow_item_eth *mask = NULL;
256 	const struct rte_flow_item_eth supp_mask = {
257 		.dst.addr_bytes = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff },
258 		.src.addr_bytes = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff },
259 		.type = 0xffff,
260 	};
261 	const struct rte_flow_item_eth ifrm_supp_mask = {
262 		.dst.addr_bytes = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff },
263 	};
264 	const uint8_t ig_mask[EFX_MAC_ADDR_LEN] = {
265 		0x01, 0x00, 0x00, 0x00, 0x00, 0x00
266 	};
267 	const struct rte_flow_item_eth *supp_mask_p;
268 	const struct rte_flow_item_eth *def_mask_p;
269 	uint8_t *loc_mac = NULL;
270 	boolean_t is_ifrm = (efx_spec->efs_encap_type !=
271 		EFX_TUNNEL_PROTOCOL_NONE);
272 
273 	if (is_ifrm) {
274 		supp_mask_p = &ifrm_supp_mask;
275 		def_mask_p = &ifrm_supp_mask;
276 		loc_mac = efx_spec->efs_ifrm_loc_mac;
277 	} else {
278 		supp_mask_p = &supp_mask;
279 		def_mask_p = &rte_flow_item_eth_mask;
280 		loc_mac = efx_spec->efs_loc_mac;
281 	}
282 
283 	rc = sfc_flow_parse_init(item,
284 				 (const void **)&spec,
285 				 (const void **)&mask,
286 				 supp_mask_p, def_mask_p,
287 				 sizeof(struct rte_flow_item_eth),
288 				 error);
289 	if (rc != 0)
290 		return rc;
291 
292 	/* If "spec" is not set, could be any Ethernet */
293 	if (spec == NULL)
294 		return 0;
295 
296 	if (rte_is_same_ether_addr(&mask->dst, &supp_mask.dst)) {
297 		efx_spec->efs_match_flags |= is_ifrm ?
298 			EFX_FILTER_MATCH_IFRM_LOC_MAC :
299 			EFX_FILTER_MATCH_LOC_MAC;
300 		rte_memcpy(loc_mac, spec->dst.addr_bytes,
301 			   EFX_MAC_ADDR_LEN);
302 	} else if (memcmp(mask->dst.addr_bytes, ig_mask,
303 			  EFX_MAC_ADDR_LEN) == 0) {
304 		if (rte_is_unicast_ether_addr(&spec->dst))
305 			efx_spec->efs_match_flags |= is_ifrm ?
306 				EFX_FILTER_MATCH_IFRM_UNKNOWN_UCAST_DST :
307 				EFX_FILTER_MATCH_UNKNOWN_UCAST_DST;
308 		else
309 			efx_spec->efs_match_flags |= is_ifrm ?
310 				EFX_FILTER_MATCH_IFRM_UNKNOWN_MCAST_DST :
311 				EFX_FILTER_MATCH_UNKNOWN_MCAST_DST;
312 	} else if (!rte_is_zero_ether_addr(&mask->dst)) {
313 		goto fail_bad_mask;
314 	}
315 
316 	/*
317 	 * ifrm_supp_mask ensures that the source address and
318 	 * ethertype masks are equal to zero in inner frame,
319 	 * so these fields are filled in only for the outer frame
320 	 */
321 	if (rte_is_same_ether_addr(&mask->src, &supp_mask.src)) {
322 		efx_spec->efs_match_flags |= EFX_FILTER_MATCH_REM_MAC;
323 		rte_memcpy(efx_spec->efs_rem_mac, spec->src.addr_bytes,
324 			   EFX_MAC_ADDR_LEN);
325 	} else if (!rte_is_zero_ether_addr(&mask->src)) {
326 		goto fail_bad_mask;
327 	}
328 
329 	/*
330 	 * Ether type is in big-endian byte order in item and
331 	 * in little-endian in efx_spec, so byte swap is used
332 	 */
333 	if (mask->type == supp_mask.type) {
334 		efx_spec->efs_match_flags |= EFX_FILTER_MATCH_ETHER_TYPE;
335 		efx_spec->efs_ether_type = rte_bswap16(spec->type);
336 	} else if (mask->type != 0) {
337 		goto fail_bad_mask;
338 	}
339 
340 	return 0;
341 
342 fail_bad_mask:
343 	rte_flow_error_set(error, EINVAL,
344 			   RTE_FLOW_ERROR_TYPE_ITEM, item,
345 			   "Bad mask in the ETH pattern item");
346 	return -rte_errno;
347 }
348 
349 /**
350  * Convert VLAN item to EFX filter specification.
351  *
352  * @param item[in]
353  *   Item specification. Only VID field is supported.
354  *   The mask can not be NULL. Ranging is not supported.
355  * @param efx_spec[in, out]
356  *   EFX filter specification to update.
357  * @param[out] error
358  *   Perform verbose error reporting if not NULL.
359  */
360 static int
361 sfc_flow_parse_vlan(const struct rte_flow_item *item,
362 		    struct sfc_flow_parse_ctx *parse_ctx,
363 		    struct rte_flow_error *error)
364 {
365 	int rc;
366 	uint16_t vid;
367 	efx_filter_spec_t *efx_spec = parse_ctx->filter;
368 	const struct rte_flow_item_vlan *spec = NULL;
369 	const struct rte_flow_item_vlan *mask = NULL;
370 	const struct rte_flow_item_vlan supp_mask = {
371 		.tci = rte_cpu_to_be_16(ETH_VLAN_ID_MAX),
372 		.inner_type = RTE_BE16(0xffff),
373 	};
374 
375 	rc = sfc_flow_parse_init(item,
376 				 (const void **)&spec,
377 				 (const void **)&mask,
378 				 &supp_mask,
379 				 NULL,
380 				 sizeof(struct rte_flow_item_vlan),
381 				 error);
382 	if (rc != 0)
383 		return rc;
384 
385 	/*
386 	 * VID is in big-endian byte order in item and
387 	 * in little-endian in efx_spec, so byte swap is used.
388 	 * If two VLAN items are included, the first matches
389 	 * the outer tag and the next matches the inner tag.
390 	 */
391 	if (mask->tci == supp_mask.tci) {
392 		/* Apply mask to keep VID only */
393 		vid = rte_bswap16(spec->tci & mask->tci);
394 
395 		if (!(efx_spec->efs_match_flags &
396 		      EFX_FILTER_MATCH_OUTER_VID)) {
397 			efx_spec->efs_match_flags |= EFX_FILTER_MATCH_OUTER_VID;
398 			efx_spec->efs_outer_vid = vid;
399 		} else if (!(efx_spec->efs_match_flags &
400 			     EFX_FILTER_MATCH_INNER_VID)) {
401 			efx_spec->efs_match_flags |= EFX_FILTER_MATCH_INNER_VID;
402 			efx_spec->efs_inner_vid = vid;
403 		} else {
404 			rte_flow_error_set(error, EINVAL,
405 					   RTE_FLOW_ERROR_TYPE_ITEM, item,
406 					   "More than two VLAN items");
407 			return -rte_errno;
408 		}
409 	} else {
410 		rte_flow_error_set(error, EINVAL,
411 				   RTE_FLOW_ERROR_TYPE_ITEM, item,
412 				   "VLAN ID in TCI match is required");
413 		return -rte_errno;
414 	}
415 
416 	if (efx_spec->efs_match_flags & EFX_FILTER_MATCH_ETHER_TYPE) {
417 		rte_flow_error_set(error, EINVAL,
418 				   RTE_FLOW_ERROR_TYPE_ITEM, item,
419 				   "VLAN TPID matching is not supported");
420 		return -rte_errno;
421 	}
422 	if (mask->inner_type == supp_mask.inner_type) {
423 		efx_spec->efs_match_flags |= EFX_FILTER_MATCH_ETHER_TYPE;
424 		efx_spec->efs_ether_type = rte_bswap16(spec->inner_type);
425 	} else if (mask->inner_type) {
426 		rte_flow_error_set(error, EINVAL,
427 				   RTE_FLOW_ERROR_TYPE_ITEM, item,
428 				   "Bad mask for VLAN inner_type");
429 		return -rte_errno;
430 	}
431 
432 	return 0;
433 }
434 
435 /**
436  * Convert IPv4 item to EFX filter specification.
437  *
438  * @param item[in]
439  *   Item specification. Only source and destination addresses and
440  *   protocol fields are supported. If the mask is NULL, default
441  *   mask will be used. Ranging is not supported.
442  * @param efx_spec[in, out]
443  *   EFX filter specification to update.
444  * @param[out] error
445  *   Perform verbose error reporting if not NULL.
446  */
447 static int
448 sfc_flow_parse_ipv4(const struct rte_flow_item *item,
449 		    struct sfc_flow_parse_ctx *parse_ctx,
450 		    struct rte_flow_error *error)
451 {
452 	int rc;
453 	efx_filter_spec_t *efx_spec = parse_ctx->filter;
454 	const struct rte_flow_item_ipv4 *spec = NULL;
455 	const struct rte_flow_item_ipv4 *mask = NULL;
456 	const uint16_t ether_type_ipv4 = rte_cpu_to_le_16(EFX_ETHER_TYPE_IPV4);
457 	const struct rte_flow_item_ipv4 supp_mask = {
458 		.hdr = {
459 			.src_addr = 0xffffffff,
460 			.dst_addr = 0xffffffff,
461 			.next_proto_id = 0xff,
462 		}
463 	};
464 
465 	rc = sfc_flow_parse_init(item,
466 				 (const void **)&spec,
467 				 (const void **)&mask,
468 				 &supp_mask,
469 				 &rte_flow_item_ipv4_mask,
470 				 sizeof(struct rte_flow_item_ipv4),
471 				 error);
472 	if (rc != 0)
473 		return rc;
474 
475 	/*
476 	 * Filtering by IPv4 source and destination addresses requires
477 	 * the appropriate ETHER_TYPE in hardware filters
478 	 */
479 	if (!(efx_spec->efs_match_flags & EFX_FILTER_MATCH_ETHER_TYPE)) {
480 		efx_spec->efs_match_flags |= EFX_FILTER_MATCH_ETHER_TYPE;
481 		efx_spec->efs_ether_type = ether_type_ipv4;
482 	} else if (efx_spec->efs_ether_type != ether_type_ipv4) {
483 		rte_flow_error_set(error, EINVAL,
484 			RTE_FLOW_ERROR_TYPE_ITEM, item,
485 			"Ethertype in pattern with IPV4 item should be appropriate");
486 		return -rte_errno;
487 	}
488 
489 	if (spec == NULL)
490 		return 0;
491 
492 	/*
493 	 * IPv4 addresses are in big-endian byte order in item and in
494 	 * efx_spec
495 	 */
496 	if (mask->hdr.src_addr == supp_mask.hdr.src_addr) {
497 		efx_spec->efs_match_flags |= EFX_FILTER_MATCH_REM_HOST;
498 		efx_spec->efs_rem_host.eo_u32[0] = spec->hdr.src_addr;
499 	} else if (mask->hdr.src_addr != 0) {
500 		goto fail_bad_mask;
501 	}
502 
503 	if (mask->hdr.dst_addr == supp_mask.hdr.dst_addr) {
504 		efx_spec->efs_match_flags |= EFX_FILTER_MATCH_LOC_HOST;
505 		efx_spec->efs_loc_host.eo_u32[0] = spec->hdr.dst_addr;
506 	} else if (mask->hdr.dst_addr != 0) {
507 		goto fail_bad_mask;
508 	}
509 
510 	if (mask->hdr.next_proto_id == supp_mask.hdr.next_proto_id) {
511 		efx_spec->efs_match_flags |= EFX_FILTER_MATCH_IP_PROTO;
512 		efx_spec->efs_ip_proto = spec->hdr.next_proto_id;
513 	} else if (mask->hdr.next_proto_id != 0) {
514 		goto fail_bad_mask;
515 	}
516 
517 	return 0;
518 
519 fail_bad_mask:
520 	rte_flow_error_set(error, EINVAL,
521 			   RTE_FLOW_ERROR_TYPE_ITEM, item,
522 			   "Bad mask in the IPV4 pattern item");
523 	return -rte_errno;
524 }
525 
526 /**
527  * Convert IPv6 item to EFX filter specification.
528  *
529  * @param item[in]
530  *   Item specification. Only source and destination addresses and
531  *   next header fields are supported. If the mask is NULL, default
532  *   mask will be used. Ranging is not supported.
533  * @param efx_spec[in, out]
534  *   EFX filter specification to update.
535  * @param[out] error
536  *   Perform verbose error reporting if not NULL.
537  */
538 static int
539 sfc_flow_parse_ipv6(const struct rte_flow_item *item,
540 		    struct sfc_flow_parse_ctx *parse_ctx,
541 		    struct rte_flow_error *error)
542 {
543 	int rc;
544 	efx_filter_spec_t *efx_spec = parse_ctx->filter;
545 	const struct rte_flow_item_ipv6 *spec = NULL;
546 	const struct rte_flow_item_ipv6 *mask = NULL;
547 	const uint16_t ether_type_ipv6 = rte_cpu_to_le_16(EFX_ETHER_TYPE_IPV6);
548 	const struct rte_flow_item_ipv6 supp_mask = {
549 		.hdr = {
550 			.src_addr = { 0xff, 0xff, 0xff, 0xff,
551 				      0xff, 0xff, 0xff, 0xff,
552 				      0xff, 0xff, 0xff, 0xff,
553 				      0xff, 0xff, 0xff, 0xff },
554 			.dst_addr = { 0xff, 0xff, 0xff, 0xff,
555 				      0xff, 0xff, 0xff, 0xff,
556 				      0xff, 0xff, 0xff, 0xff,
557 				      0xff, 0xff, 0xff, 0xff },
558 			.proto = 0xff,
559 		}
560 	};
561 
562 	rc = sfc_flow_parse_init(item,
563 				 (const void **)&spec,
564 				 (const void **)&mask,
565 				 &supp_mask,
566 				 &rte_flow_item_ipv6_mask,
567 				 sizeof(struct rte_flow_item_ipv6),
568 				 error);
569 	if (rc != 0)
570 		return rc;
571 
572 	/*
573 	 * Filtering by IPv6 source and destination addresses requires
574 	 * the appropriate ETHER_TYPE in hardware filters
575 	 */
576 	if (!(efx_spec->efs_match_flags & EFX_FILTER_MATCH_ETHER_TYPE)) {
577 		efx_spec->efs_match_flags |= EFX_FILTER_MATCH_ETHER_TYPE;
578 		efx_spec->efs_ether_type = ether_type_ipv6;
579 	} else if (efx_spec->efs_ether_type != ether_type_ipv6) {
580 		rte_flow_error_set(error, EINVAL,
581 			RTE_FLOW_ERROR_TYPE_ITEM, item,
582 			"Ethertype in pattern with IPV6 item should be appropriate");
583 		return -rte_errno;
584 	}
585 
586 	if (spec == NULL)
587 		return 0;
588 
589 	/*
590 	 * IPv6 addresses are in big-endian byte order in item and in
591 	 * efx_spec
592 	 */
593 	if (memcmp(mask->hdr.src_addr, supp_mask.hdr.src_addr,
594 		   sizeof(mask->hdr.src_addr)) == 0) {
595 		efx_spec->efs_match_flags |= EFX_FILTER_MATCH_REM_HOST;
596 
597 		RTE_BUILD_BUG_ON(sizeof(efx_spec->efs_rem_host) !=
598 				 sizeof(spec->hdr.src_addr));
599 		rte_memcpy(&efx_spec->efs_rem_host, spec->hdr.src_addr,
600 			   sizeof(efx_spec->efs_rem_host));
601 	} else if (!sfc_flow_is_zero(mask->hdr.src_addr,
602 				     sizeof(mask->hdr.src_addr))) {
603 		goto fail_bad_mask;
604 	}
605 
606 	if (memcmp(mask->hdr.dst_addr, supp_mask.hdr.dst_addr,
607 		   sizeof(mask->hdr.dst_addr)) == 0) {
608 		efx_spec->efs_match_flags |= EFX_FILTER_MATCH_LOC_HOST;
609 
610 		RTE_BUILD_BUG_ON(sizeof(efx_spec->efs_loc_host) !=
611 				 sizeof(spec->hdr.dst_addr));
612 		rte_memcpy(&efx_spec->efs_loc_host, spec->hdr.dst_addr,
613 			   sizeof(efx_spec->efs_loc_host));
614 	} else if (!sfc_flow_is_zero(mask->hdr.dst_addr,
615 				     sizeof(mask->hdr.dst_addr))) {
616 		goto fail_bad_mask;
617 	}
618 
619 	if (mask->hdr.proto == supp_mask.hdr.proto) {
620 		efx_spec->efs_match_flags |= EFX_FILTER_MATCH_IP_PROTO;
621 		efx_spec->efs_ip_proto = spec->hdr.proto;
622 	} else if (mask->hdr.proto != 0) {
623 		goto fail_bad_mask;
624 	}
625 
626 	return 0;
627 
628 fail_bad_mask:
629 	rte_flow_error_set(error, EINVAL,
630 			   RTE_FLOW_ERROR_TYPE_ITEM, item,
631 			   "Bad mask in the IPV6 pattern item");
632 	return -rte_errno;
633 }
634 
635 /**
636  * Convert TCP item to EFX filter specification.
637  *
638  * @param item[in]
639  *   Item specification. Only source and destination ports fields
640  *   are supported. If the mask is NULL, default mask will be used.
641  *   Ranging is not supported.
642  * @param efx_spec[in, out]
643  *   EFX filter specification to update.
644  * @param[out] error
645  *   Perform verbose error reporting if not NULL.
646  */
647 static int
648 sfc_flow_parse_tcp(const struct rte_flow_item *item,
649 		   struct sfc_flow_parse_ctx *parse_ctx,
650 		   struct rte_flow_error *error)
651 {
652 	int rc;
653 	efx_filter_spec_t *efx_spec = parse_ctx->filter;
654 	const struct rte_flow_item_tcp *spec = NULL;
655 	const struct rte_flow_item_tcp *mask = NULL;
656 	const struct rte_flow_item_tcp supp_mask = {
657 		.hdr = {
658 			.src_port = 0xffff,
659 			.dst_port = 0xffff,
660 		}
661 	};
662 
663 	rc = sfc_flow_parse_init(item,
664 				 (const void **)&spec,
665 				 (const void **)&mask,
666 				 &supp_mask,
667 				 &rte_flow_item_tcp_mask,
668 				 sizeof(struct rte_flow_item_tcp),
669 				 error);
670 	if (rc != 0)
671 		return rc;
672 
673 	/*
674 	 * Filtering by TCP source and destination ports requires
675 	 * the appropriate IP_PROTO in hardware filters
676 	 */
677 	if (!(efx_spec->efs_match_flags & EFX_FILTER_MATCH_IP_PROTO)) {
678 		efx_spec->efs_match_flags |= EFX_FILTER_MATCH_IP_PROTO;
679 		efx_spec->efs_ip_proto = EFX_IPPROTO_TCP;
680 	} else if (efx_spec->efs_ip_proto != EFX_IPPROTO_TCP) {
681 		rte_flow_error_set(error, EINVAL,
682 			RTE_FLOW_ERROR_TYPE_ITEM, item,
683 			"IP proto in pattern with TCP item should be appropriate");
684 		return -rte_errno;
685 	}
686 
687 	if (spec == NULL)
688 		return 0;
689 
690 	/*
691 	 * Source and destination ports are in big-endian byte order in item and
692 	 * in little-endian in efx_spec, so byte swap is used
693 	 */
694 	if (mask->hdr.src_port == supp_mask.hdr.src_port) {
695 		efx_spec->efs_match_flags |= EFX_FILTER_MATCH_REM_PORT;
696 		efx_spec->efs_rem_port = rte_bswap16(spec->hdr.src_port);
697 	} else if (mask->hdr.src_port != 0) {
698 		goto fail_bad_mask;
699 	}
700 
701 	if (mask->hdr.dst_port == supp_mask.hdr.dst_port) {
702 		efx_spec->efs_match_flags |= EFX_FILTER_MATCH_LOC_PORT;
703 		efx_spec->efs_loc_port = rte_bswap16(spec->hdr.dst_port);
704 	} else if (mask->hdr.dst_port != 0) {
705 		goto fail_bad_mask;
706 	}
707 
708 	return 0;
709 
710 fail_bad_mask:
711 	rte_flow_error_set(error, EINVAL,
712 			   RTE_FLOW_ERROR_TYPE_ITEM, item,
713 			   "Bad mask in the TCP pattern item");
714 	return -rte_errno;
715 }
716 
717 /**
718  * Convert UDP item to EFX filter specification.
719  *
720  * @param item[in]
721  *   Item specification. Only source and destination ports fields
722  *   are supported. If the mask is NULL, default mask will be used.
723  *   Ranging is not supported.
724  * @param efx_spec[in, out]
725  *   EFX filter specification to update.
726  * @param[out] error
727  *   Perform verbose error reporting if not NULL.
728  */
729 static int
730 sfc_flow_parse_udp(const struct rte_flow_item *item,
731 		   struct sfc_flow_parse_ctx *parse_ctx,
732 		   struct rte_flow_error *error)
733 {
734 	int rc;
735 	efx_filter_spec_t *efx_spec = parse_ctx->filter;
736 	const struct rte_flow_item_udp *spec = NULL;
737 	const struct rte_flow_item_udp *mask = NULL;
738 	const struct rte_flow_item_udp supp_mask = {
739 		.hdr = {
740 			.src_port = 0xffff,
741 			.dst_port = 0xffff,
742 		}
743 	};
744 
745 	rc = sfc_flow_parse_init(item,
746 				 (const void **)&spec,
747 				 (const void **)&mask,
748 				 &supp_mask,
749 				 &rte_flow_item_udp_mask,
750 				 sizeof(struct rte_flow_item_udp),
751 				 error);
752 	if (rc != 0)
753 		return rc;
754 
755 	/*
756 	 * Filtering by UDP source and destination ports requires
757 	 * the appropriate IP_PROTO in hardware filters
758 	 */
759 	if (!(efx_spec->efs_match_flags & EFX_FILTER_MATCH_IP_PROTO)) {
760 		efx_spec->efs_match_flags |= EFX_FILTER_MATCH_IP_PROTO;
761 		efx_spec->efs_ip_proto = EFX_IPPROTO_UDP;
762 	} else if (efx_spec->efs_ip_proto != EFX_IPPROTO_UDP) {
763 		rte_flow_error_set(error, EINVAL,
764 			RTE_FLOW_ERROR_TYPE_ITEM, item,
765 			"IP proto in pattern with UDP item should be appropriate");
766 		return -rte_errno;
767 	}
768 
769 	if (spec == NULL)
770 		return 0;
771 
772 	/*
773 	 * Source and destination ports are in big-endian byte order in item and
774 	 * in little-endian in efx_spec, so byte swap is used
775 	 */
776 	if (mask->hdr.src_port == supp_mask.hdr.src_port) {
777 		efx_spec->efs_match_flags |= EFX_FILTER_MATCH_REM_PORT;
778 		efx_spec->efs_rem_port = rte_bswap16(spec->hdr.src_port);
779 	} else if (mask->hdr.src_port != 0) {
780 		goto fail_bad_mask;
781 	}
782 
783 	if (mask->hdr.dst_port == supp_mask.hdr.dst_port) {
784 		efx_spec->efs_match_flags |= EFX_FILTER_MATCH_LOC_PORT;
785 		efx_spec->efs_loc_port = rte_bswap16(spec->hdr.dst_port);
786 	} else if (mask->hdr.dst_port != 0) {
787 		goto fail_bad_mask;
788 	}
789 
790 	return 0;
791 
792 fail_bad_mask:
793 	rte_flow_error_set(error, EINVAL,
794 			   RTE_FLOW_ERROR_TYPE_ITEM, item,
795 			   "Bad mask in the UDP pattern item");
796 	return -rte_errno;
797 }
798 
799 /*
800  * Filters for encapsulated packets match based on the EtherType and IP
801  * protocol in the outer frame.
802  */
803 static int
804 sfc_flow_set_match_flags_for_encap_pkts(const struct rte_flow_item *item,
805 					efx_filter_spec_t *efx_spec,
806 					uint8_t ip_proto,
807 					struct rte_flow_error *error)
808 {
809 	if (!(efx_spec->efs_match_flags & EFX_FILTER_MATCH_IP_PROTO)) {
810 		efx_spec->efs_match_flags |= EFX_FILTER_MATCH_IP_PROTO;
811 		efx_spec->efs_ip_proto = ip_proto;
812 	} else if (efx_spec->efs_ip_proto != ip_proto) {
813 		switch (ip_proto) {
814 		case EFX_IPPROTO_UDP:
815 			rte_flow_error_set(error, EINVAL,
816 				RTE_FLOW_ERROR_TYPE_ITEM, item,
817 				"Outer IP header protocol must be UDP "
818 				"in VxLAN/GENEVE pattern");
819 			return -rte_errno;
820 
821 		case EFX_IPPROTO_GRE:
822 			rte_flow_error_set(error, EINVAL,
823 				RTE_FLOW_ERROR_TYPE_ITEM, item,
824 				"Outer IP header protocol must be GRE "
825 				"in NVGRE pattern");
826 			return -rte_errno;
827 
828 		default:
829 			rte_flow_error_set(error, EINVAL,
830 				RTE_FLOW_ERROR_TYPE_ITEM, item,
831 				"Only VxLAN/GENEVE/NVGRE tunneling patterns "
832 				"are supported");
833 			return -rte_errno;
834 		}
835 	}
836 
837 	if (efx_spec->efs_match_flags & EFX_FILTER_MATCH_ETHER_TYPE &&
838 	    efx_spec->efs_ether_type != EFX_ETHER_TYPE_IPV4 &&
839 	    efx_spec->efs_ether_type != EFX_ETHER_TYPE_IPV6) {
840 		rte_flow_error_set(error, EINVAL,
841 			RTE_FLOW_ERROR_TYPE_ITEM, item,
842 			"Outer frame EtherType in pattern with tunneling "
843 			"must be IPv4 or IPv6");
844 		return -rte_errno;
845 	}
846 
847 	return 0;
848 }
849 
850 static int
851 sfc_flow_set_efx_spec_vni_or_vsid(efx_filter_spec_t *efx_spec,
852 				  const uint8_t *vni_or_vsid_val,
853 				  const uint8_t *vni_or_vsid_mask,
854 				  const struct rte_flow_item *item,
855 				  struct rte_flow_error *error)
856 {
857 	const uint8_t vni_or_vsid_full_mask[EFX_VNI_OR_VSID_LEN] = {
858 		0xff, 0xff, 0xff
859 	};
860 
861 	if (memcmp(vni_or_vsid_mask, vni_or_vsid_full_mask,
862 		   EFX_VNI_OR_VSID_LEN) == 0) {
863 		efx_spec->efs_match_flags |= EFX_FILTER_MATCH_VNI_OR_VSID;
864 		rte_memcpy(efx_spec->efs_vni_or_vsid, vni_or_vsid_val,
865 			   EFX_VNI_OR_VSID_LEN);
866 	} else if (!sfc_flow_is_zero(vni_or_vsid_mask, EFX_VNI_OR_VSID_LEN)) {
867 		rte_flow_error_set(error, EINVAL,
868 				   RTE_FLOW_ERROR_TYPE_ITEM, item,
869 				   "Unsupported VNI/VSID mask");
870 		return -rte_errno;
871 	}
872 
873 	return 0;
874 }
875 
876 /**
877  * Convert VXLAN item to EFX filter specification.
878  *
879  * @param item[in]
880  *   Item specification. Only VXLAN network identifier field is supported.
881  *   If the mask is NULL, default mask will be used.
882  *   Ranging is not supported.
883  * @param efx_spec[in, out]
884  *   EFX filter specification to update.
885  * @param[out] error
886  *   Perform verbose error reporting if not NULL.
887  */
888 static int
889 sfc_flow_parse_vxlan(const struct rte_flow_item *item,
890 		     struct sfc_flow_parse_ctx *parse_ctx,
891 		     struct rte_flow_error *error)
892 {
893 	int rc;
894 	efx_filter_spec_t *efx_spec = parse_ctx->filter;
895 	const struct rte_flow_item_vxlan *spec = NULL;
896 	const struct rte_flow_item_vxlan *mask = NULL;
897 	const struct rte_flow_item_vxlan supp_mask = {
898 		.vni = { 0xff, 0xff, 0xff }
899 	};
900 
901 	rc = sfc_flow_parse_init(item,
902 				 (const void **)&spec,
903 				 (const void **)&mask,
904 				 &supp_mask,
905 				 &rte_flow_item_vxlan_mask,
906 				 sizeof(struct rte_flow_item_vxlan),
907 				 error);
908 	if (rc != 0)
909 		return rc;
910 
911 	rc = sfc_flow_set_match_flags_for_encap_pkts(item, efx_spec,
912 						     EFX_IPPROTO_UDP, error);
913 	if (rc != 0)
914 		return rc;
915 
916 	efx_spec->efs_encap_type = EFX_TUNNEL_PROTOCOL_VXLAN;
917 	efx_spec->efs_match_flags |= EFX_FILTER_MATCH_ENCAP_TYPE;
918 
919 	if (spec == NULL)
920 		return 0;
921 
922 	rc = sfc_flow_set_efx_spec_vni_or_vsid(efx_spec, spec->vni,
923 					       mask->vni, item, error);
924 
925 	return rc;
926 }
927 
928 /**
929  * Convert GENEVE item to EFX filter specification.
930  *
931  * @param item[in]
932  *   Item specification. Only Virtual Network Identifier and protocol type
933  *   fields are supported. But protocol type can be only Ethernet (0x6558).
934  *   If the mask is NULL, default mask will be used.
935  *   Ranging is not supported.
936  * @param efx_spec[in, out]
937  *   EFX filter specification to update.
938  * @param[out] error
939  *   Perform verbose error reporting if not NULL.
940  */
941 static int
942 sfc_flow_parse_geneve(const struct rte_flow_item *item,
943 		      struct sfc_flow_parse_ctx *parse_ctx,
944 		      struct rte_flow_error *error)
945 {
946 	int rc;
947 	efx_filter_spec_t *efx_spec = parse_ctx->filter;
948 	const struct rte_flow_item_geneve *spec = NULL;
949 	const struct rte_flow_item_geneve *mask = NULL;
950 	const struct rte_flow_item_geneve supp_mask = {
951 		.protocol = RTE_BE16(0xffff),
952 		.vni = { 0xff, 0xff, 0xff }
953 	};
954 
955 	rc = sfc_flow_parse_init(item,
956 				 (const void **)&spec,
957 				 (const void **)&mask,
958 				 &supp_mask,
959 				 &rte_flow_item_geneve_mask,
960 				 sizeof(struct rte_flow_item_geneve),
961 				 error);
962 	if (rc != 0)
963 		return rc;
964 
965 	rc = sfc_flow_set_match_flags_for_encap_pkts(item, efx_spec,
966 						     EFX_IPPROTO_UDP, error);
967 	if (rc != 0)
968 		return rc;
969 
970 	efx_spec->efs_encap_type = EFX_TUNNEL_PROTOCOL_GENEVE;
971 	efx_spec->efs_match_flags |= EFX_FILTER_MATCH_ENCAP_TYPE;
972 
973 	if (spec == NULL)
974 		return 0;
975 
976 	if (mask->protocol == supp_mask.protocol) {
977 		if (spec->protocol != rte_cpu_to_be_16(RTE_ETHER_TYPE_TEB)) {
978 			rte_flow_error_set(error, EINVAL,
979 				RTE_FLOW_ERROR_TYPE_ITEM, item,
980 				"GENEVE encap. protocol must be Ethernet "
981 				"(0x6558) in the GENEVE pattern item");
982 			return -rte_errno;
983 		}
984 	} else if (mask->protocol != 0) {
985 		rte_flow_error_set(error, EINVAL,
986 			RTE_FLOW_ERROR_TYPE_ITEM, item,
987 			"Unsupported mask for GENEVE encap. protocol");
988 		return -rte_errno;
989 	}
990 
991 	rc = sfc_flow_set_efx_spec_vni_or_vsid(efx_spec, spec->vni,
992 					       mask->vni, item, error);
993 
994 	return rc;
995 }
996 
997 /**
998  * Convert NVGRE item to EFX filter specification.
999  *
1000  * @param item[in]
1001  *   Item specification. Only virtual subnet ID field is supported.
1002  *   If the mask is NULL, default mask will be used.
1003  *   Ranging is not supported.
1004  * @param efx_spec[in, out]
1005  *   EFX filter specification to update.
1006  * @param[out] error
1007  *   Perform verbose error reporting if not NULL.
1008  */
1009 static int
1010 sfc_flow_parse_nvgre(const struct rte_flow_item *item,
1011 		     struct sfc_flow_parse_ctx *parse_ctx,
1012 		     struct rte_flow_error *error)
1013 {
1014 	int rc;
1015 	efx_filter_spec_t *efx_spec = parse_ctx->filter;
1016 	const struct rte_flow_item_nvgre *spec = NULL;
1017 	const struct rte_flow_item_nvgre *mask = NULL;
1018 	const struct rte_flow_item_nvgre supp_mask = {
1019 		.tni = { 0xff, 0xff, 0xff }
1020 	};
1021 
1022 	rc = sfc_flow_parse_init(item,
1023 				 (const void **)&spec,
1024 				 (const void **)&mask,
1025 				 &supp_mask,
1026 				 &rte_flow_item_nvgre_mask,
1027 				 sizeof(struct rte_flow_item_nvgre),
1028 				 error);
1029 	if (rc != 0)
1030 		return rc;
1031 
1032 	rc = sfc_flow_set_match_flags_for_encap_pkts(item, efx_spec,
1033 						     EFX_IPPROTO_GRE, error);
1034 	if (rc != 0)
1035 		return rc;
1036 
1037 	efx_spec->efs_encap_type = EFX_TUNNEL_PROTOCOL_NVGRE;
1038 	efx_spec->efs_match_flags |= EFX_FILTER_MATCH_ENCAP_TYPE;
1039 
1040 	if (spec == NULL)
1041 		return 0;
1042 
1043 	rc = sfc_flow_set_efx_spec_vni_or_vsid(efx_spec, spec->tni,
1044 					       mask->tni, item, error);
1045 
1046 	return rc;
1047 }
1048 
1049 static const struct sfc_flow_item sfc_flow_items[] = {
1050 	{
1051 		.type = RTE_FLOW_ITEM_TYPE_VOID,
1052 		.prev_layer = SFC_FLOW_ITEM_ANY_LAYER,
1053 		.layer = SFC_FLOW_ITEM_ANY_LAYER,
1054 		.ctx_type = SFC_FLOW_PARSE_CTX_FILTER,
1055 		.parse = sfc_flow_parse_void,
1056 	},
1057 	{
1058 		.type = RTE_FLOW_ITEM_TYPE_ETH,
1059 		.prev_layer = SFC_FLOW_ITEM_START_LAYER,
1060 		.layer = SFC_FLOW_ITEM_L2,
1061 		.ctx_type = SFC_FLOW_PARSE_CTX_FILTER,
1062 		.parse = sfc_flow_parse_eth,
1063 	},
1064 	{
1065 		.type = RTE_FLOW_ITEM_TYPE_VLAN,
1066 		.prev_layer = SFC_FLOW_ITEM_L2,
1067 		.layer = SFC_FLOW_ITEM_L2,
1068 		.ctx_type = SFC_FLOW_PARSE_CTX_FILTER,
1069 		.parse = sfc_flow_parse_vlan,
1070 	},
1071 	{
1072 		.type = RTE_FLOW_ITEM_TYPE_IPV4,
1073 		.prev_layer = SFC_FLOW_ITEM_L2,
1074 		.layer = SFC_FLOW_ITEM_L3,
1075 		.ctx_type = SFC_FLOW_PARSE_CTX_FILTER,
1076 		.parse = sfc_flow_parse_ipv4,
1077 	},
1078 	{
1079 		.type = RTE_FLOW_ITEM_TYPE_IPV6,
1080 		.prev_layer = SFC_FLOW_ITEM_L2,
1081 		.layer = SFC_FLOW_ITEM_L3,
1082 		.ctx_type = SFC_FLOW_PARSE_CTX_FILTER,
1083 		.parse = sfc_flow_parse_ipv6,
1084 	},
1085 	{
1086 		.type = RTE_FLOW_ITEM_TYPE_TCP,
1087 		.prev_layer = SFC_FLOW_ITEM_L3,
1088 		.layer = SFC_FLOW_ITEM_L4,
1089 		.ctx_type = SFC_FLOW_PARSE_CTX_FILTER,
1090 		.parse = sfc_flow_parse_tcp,
1091 	},
1092 	{
1093 		.type = RTE_FLOW_ITEM_TYPE_UDP,
1094 		.prev_layer = SFC_FLOW_ITEM_L3,
1095 		.layer = SFC_FLOW_ITEM_L4,
1096 		.ctx_type = SFC_FLOW_PARSE_CTX_FILTER,
1097 		.parse = sfc_flow_parse_udp,
1098 	},
1099 	{
1100 		.type = RTE_FLOW_ITEM_TYPE_VXLAN,
1101 		.prev_layer = SFC_FLOW_ITEM_L4,
1102 		.layer = SFC_FLOW_ITEM_START_LAYER,
1103 		.ctx_type = SFC_FLOW_PARSE_CTX_FILTER,
1104 		.parse = sfc_flow_parse_vxlan,
1105 	},
1106 	{
1107 		.type = RTE_FLOW_ITEM_TYPE_GENEVE,
1108 		.prev_layer = SFC_FLOW_ITEM_L4,
1109 		.layer = SFC_FLOW_ITEM_START_LAYER,
1110 		.ctx_type = SFC_FLOW_PARSE_CTX_FILTER,
1111 		.parse = sfc_flow_parse_geneve,
1112 	},
1113 	{
1114 		.type = RTE_FLOW_ITEM_TYPE_NVGRE,
1115 		.prev_layer = SFC_FLOW_ITEM_L3,
1116 		.layer = SFC_FLOW_ITEM_START_LAYER,
1117 		.ctx_type = SFC_FLOW_PARSE_CTX_FILTER,
1118 		.parse = sfc_flow_parse_nvgre,
1119 	},
1120 };
1121 
1122 /*
1123  * Protocol-independent flow API support
1124  */
1125 static int
1126 sfc_flow_parse_attr(const struct rte_flow_attr *attr,
1127 		    struct rte_flow *flow,
1128 		    struct rte_flow_error *error)
1129 {
1130 	struct sfc_flow_spec *spec = &flow->spec;
1131 	struct sfc_flow_spec_filter *spec_filter = &spec->filter;
1132 
1133 	if (attr == NULL) {
1134 		rte_flow_error_set(error, EINVAL,
1135 				   RTE_FLOW_ERROR_TYPE_ATTR, NULL,
1136 				   "NULL attribute");
1137 		return -rte_errno;
1138 	}
1139 	if (attr->group != 0) {
1140 		rte_flow_error_set(error, ENOTSUP,
1141 				   RTE_FLOW_ERROR_TYPE_ATTR_GROUP, attr,
1142 				   "Groups are not supported");
1143 		return -rte_errno;
1144 	}
1145 	if (attr->egress != 0) {
1146 		rte_flow_error_set(error, ENOTSUP,
1147 				   RTE_FLOW_ERROR_TYPE_ATTR_EGRESS, attr,
1148 				   "Egress is not supported");
1149 		return -rte_errno;
1150 	}
1151 	if (attr->ingress == 0) {
1152 		rte_flow_error_set(error, ENOTSUP,
1153 				   RTE_FLOW_ERROR_TYPE_ATTR_INGRESS, attr,
1154 				   "Ingress is compulsory");
1155 		return -rte_errno;
1156 	}
1157 	if (attr->transfer == 0) {
1158 		if (attr->priority != 0) {
1159 			rte_flow_error_set(error, ENOTSUP,
1160 					   RTE_FLOW_ERROR_TYPE_ATTR_PRIORITY,
1161 					   attr, "Priorities are unsupported");
1162 			return -rte_errno;
1163 		}
1164 		spec->type = SFC_FLOW_SPEC_FILTER;
1165 		spec_filter->template.efs_flags |= EFX_FILTER_FLAG_RX;
1166 		spec_filter->template.efs_rss_context = EFX_RSS_CONTEXT_DEFAULT;
1167 		spec_filter->template.efs_priority = EFX_FILTER_PRI_MANUAL;
1168 	} else {
1169 		rte_flow_error_set(error, ENOTSUP,
1170 				   RTE_FLOW_ERROR_TYPE_ATTR_TRANSFER, attr,
1171 				   "Transfer is not supported");
1172 		return -rte_errno;
1173 	}
1174 
1175 	return 0;
1176 }
1177 
1178 /* Get item from array sfc_flow_items */
1179 static const struct sfc_flow_item *
1180 sfc_flow_get_item(const struct sfc_flow_item *items,
1181 		  unsigned int nb_items,
1182 		  enum rte_flow_item_type type)
1183 {
1184 	unsigned int i;
1185 
1186 	for (i = 0; i < nb_items; i++)
1187 		if (items[i].type == type)
1188 			return &items[i];
1189 
1190 	return NULL;
1191 }
1192 
1193 int
1194 sfc_flow_parse_pattern(const struct sfc_flow_item *flow_items,
1195 		       unsigned int nb_flow_items,
1196 		       const struct rte_flow_item pattern[],
1197 		       struct sfc_flow_parse_ctx *parse_ctx,
1198 		       struct rte_flow_error *error)
1199 {
1200 	int rc;
1201 	unsigned int prev_layer = SFC_FLOW_ITEM_ANY_LAYER;
1202 	boolean_t is_ifrm = B_FALSE;
1203 	const struct sfc_flow_item *item;
1204 
1205 	if (pattern == NULL) {
1206 		rte_flow_error_set(error, EINVAL,
1207 				   RTE_FLOW_ERROR_TYPE_ITEM_NUM, NULL,
1208 				   "NULL pattern");
1209 		return -rte_errno;
1210 	}
1211 
1212 	for (; pattern->type != RTE_FLOW_ITEM_TYPE_END; pattern++) {
1213 		item = sfc_flow_get_item(flow_items, nb_flow_items,
1214 					 pattern->type);
1215 		if (item == NULL) {
1216 			rte_flow_error_set(error, ENOTSUP,
1217 					   RTE_FLOW_ERROR_TYPE_ITEM, pattern,
1218 					   "Unsupported pattern item");
1219 			return -rte_errno;
1220 		}
1221 
1222 		/*
1223 		 * Omitting one or several protocol layers at the beginning
1224 		 * of pattern is supported
1225 		 */
1226 		if (item->prev_layer != SFC_FLOW_ITEM_ANY_LAYER &&
1227 		    prev_layer != SFC_FLOW_ITEM_ANY_LAYER &&
1228 		    item->prev_layer != prev_layer) {
1229 			rte_flow_error_set(error, ENOTSUP,
1230 					   RTE_FLOW_ERROR_TYPE_ITEM, pattern,
1231 					   "Unexpected sequence of pattern items");
1232 			return -rte_errno;
1233 		}
1234 
1235 		/*
1236 		 * Allow only VOID and ETH pattern items in the inner frame.
1237 		 * Also check that there is only one tunneling protocol.
1238 		 */
1239 		switch (item->type) {
1240 		case RTE_FLOW_ITEM_TYPE_VOID:
1241 		case RTE_FLOW_ITEM_TYPE_ETH:
1242 			break;
1243 
1244 		case RTE_FLOW_ITEM_TYPE_VXLAN:
1245 		case RTE_FLOW_ITEM_TYPE_GENEVE:
1246 		case RTE_FLOW_ITEM_TYPE_NVGRE:
1247 			if (is_ifrm) {
1248 				rte_flow_error_set(error, EINVAL,
1249 					RTE_FLOW_ERROR_TYPE_ITEM,
1250 					pattern,
1251 					"More than one tunneling protocol");
1252 				return -rte_errno;
1253 			}
1254 			is_ifrm = B_TRUE;
1255 			break;
1256 
1257 		default:
1258 			if (is_ifrm) {
1259 				rte_flow_error_set(error, EINVAL,
1260 					RTE_FLOW_ERROR_TYPE_ITEM,
1261 					pattern,
1262 					"There is an unsupported pattern item "
1263 					"in the inner frame");
1264 				return -rte_errno;
1265 			}
1266 			break;
1267 		}
1268 
1269 		if (parse_ctx->type != item->ctx_type) {
1270 			rte_flow_error_set(error, EINVAL,
1271 					RTE_FLOW_ERROR_TYPE_ITEM, pattern,
1272 					"Parse context type mismatch");
1273 			return -rte_errno;
1274 		}
1275 
1276 		rc = item->parse(pattern, parse_ctx, error);
1277 		if (rc != 0)
1278 			return rc;
1279 
1280 		if (item->layer != SFC_FLOW_ITEM_ANY_LAYER)
1281 			prev_layer = item->layer;
1282 	}
1283 
1284 	return 0;
1285 }
1286 
1287 static int
1288 sfc_flow_parse_queue(struct sfc_adapter *sa,
1289 		     const struct rte_flow_action_queue *queue,
1290 		     struct rte_flow *flow)
1291 {
1292 	struct sfc_flow_spec *spec = &flow->spec;
1293 	struct sfc_flow_spec_filter *spec_filter = &spec->filter;
1294 	struct sfc_rxq *rxq;
1295 
1296 	if (queue->index >= sfc_sa2shared(sa)->rxq_count)
1297 		return -EINVAL;
1298 
1299 	rxq = &sa->rxq_ctrl[queue->index];
1300 	spec_filter->template.efs_dmaq_id = (uint16_t)rxq->hw_index;
1301 
1302 	return 0;
1303 }
1304 
1305 static int
1306 sfc_flow_parse_rss(struct sfc_adapter *sa,
1307 		   const struct rte_flow_action_rss *action_rss,
1308 		   struct rte_flow *flow)
1309 {
1310 	struct sfc_adapter_shared * const sas = sfc_sa2shared(sa);
1311 	struct sfc_rss *rss = &sas->rss;
1312 	unsigned int rxq_sw_index;
1313 	struct sfc_rxq *rxq;
1314 	unsigned int rxq_hw_index_min;
1315 	unsigned int rxq_hw_index_max;
1316 	efx_rx_hash_type_t efx_hash_types;
1317 	const uint8_t *rss_key;
1318 	struct sfc_flow_spec *spec = &flow->spec;
1319 	struct sfc_flow_spec_filter *spec_filter = &spec->filter;
1320 	struct sfc_flow_rss *sfc_rss_conf = &spec_filter->rss_conf;
1321 	unsigned int i;
1322 
1323 	if (action_rss->queue_num == 0)
1324 		return -EINVAL;
1325 
1326 	rxq_sw_index = sfc_sa2shared(sa)->rxq_count - 1;
1327 	rxq = &sa->rxq_ctrl[rxq_sw_index];
1328 	rxq_hw_index_min = rxq->hw_index;
1329 	rxq_hw_index_max = 0;
1330 
1331 	for (i = 0; i < action_rss->queue_num; ++i) {
1332 		rxq_sw_index = action_rss->queue[i];
1333 
1334 		if (rxq_sw_index >= sfc_sa2shared(sa)->rxq_count)
1335 			return -EINVAL;
1336 
1337 		rxq = &sa->rxq_ctrl[rxq_sw_index];
1338 
1339 		if (rxq->hw_index < rxq_hw_index_min)
1340 			rxq_hw_index_min = rxq->hw_index;
1341 
1342 		if (rxq->hw_index > rxq_hw_index_max)
1343 			rxq_hw_index_max = rxq->hw_index;
1344 	}
1345 
1346 	switch (action_rss->func) {
1347 	case RTE_ETH_HASH_FUNCTION_DEFAULT:
1348 	case RTE_ETH_HASH_FUNCTION_TOEPLITZ:
1349 		break;
1350 	default:
1351 		return -EINVAL;
1352 	}
1353 
1354 	if (action_rss->level)
1355 		return -EINVAL;
1356 
1357 	/*
1358 	 * Dummy RSS action with only one queue and no specific settings
1359 	 * for hash types and key does not require dedicated RSS context
1360 	 * and may be simplified to single queue action.
1361 	 */
1362 	if (action_rss->queue_num == 1 && action_rss->types == 0 &&
1363 	    action_rss->key_len == 0) {
1364 		spec_filter->template.efs_dmaq_id = rxq_hw_index_min;
1365 		return 0;
1366 	}
1367 
1368 	if (action_rss->types) {
1369 		int rc;
1370 
1371 		rc = sfc_rx_hf_rte_to_efx(sa, action_rss->types,
1372 					  &efx_hash_types);
1373 		if (rc != 0)
1374 			return -rc;
1375 	} else {
1376 		unsigned int i;
1377 
1378 		efx_hash_types = 0;
1379 		for (i = 0; i < rss->hf_map_nb_entries; ++i)
1380 			efx_hash_types |= rss->hf_map[i].efx;
1381 	}
1382 
1383 	if (action_rss->key_len) {
1384 		if (action_rss->key_len != sizeof(rss->key))
1385 			return -EINVAL;
1386 
1387 		rss_key = action_rss->key;
1388 	} else {
1389 		rss_key = rss->key;
1390 	}
1391 
1392 	spec_filter->rss = B_TRUE;
1393 
1394 	sfc_rss_conf->rxq_hw_index_min = rxq_hw_index_min;
1395 	sfc_rss_conf->rxq_hw_index_max = rxq_hw_index_max;
1396 	sfc_rss_conf->rss_hash_types = efx_hash_types;
1397 	rte_memcpy(sfc_rss_conf->rss_key, rss_key, sizeof(rss->key));
1398 
1399 	for (i = 0; i < RTE_DIM(sfc_rss_conf->rss_tbl); ++i) {
1400 		unsigned int nb_queues = action_rss->queue_num;
1401 		unsigned int rxq_sw_index = action_rss->queue[i % nb_queues];
1402 		struct sfc_rxq *rxq = &sa->rxq_ctrl[rxq_sw_index];
1403 
1404 		sfc_rss_conf->rss_tbl[i] = rxq->hw_index - rxq_hw_index_min;
1405 	}
1406 
1407 	return 0;
1408 }
1409 
1410 static int
1411 sfc_flow_spec_flush(struct sfc_adapter *sa, struct sfc_flow_spec *spec,
1412 		    unsigned int filters_count)
1413 {
1414 	struct sfc_flow_spec_filter *spec_filter = &spec->filter;
1415 	unsigned int i;
1416 	int ret = 0;
1417 
1418 	for (i = 0; i < filters_count; i++) {
1419 		int rc;
1420 
1421 		rc = efx_filter_remove(sa->nic, &spec_filter->filters[i]);
1422 		if (ret == 0 && rc != 0) {
1423 			sfc_err(sa, "failed to remove filter specification "
1424 				"(rc = %d)", rc);
1425 			ret = rc;
1426 		}
1427 	}
1428 
1429 	return ret;
1430 }
1431 
1432 static int
1433 sfc_flow_spec_insert(struct sfc_adapter *sa, struct sfc_flow_spec *spec)
1434 {
1435 	struct sfc_flow_spec_filter *spec_filter = &spec->filter;
1436 	unsigned int i;
1437 	int rc = 0;
1438 
1439 	for (i = 0; i < spec_filter->count; i++) {
1440 		rc = efx_filter_insert(sa->nic, &spec_filter->filters[i]);
1441 		if (rc != 0) {
1442 			sfc_flow_spec_flush(sa, spec, i);
1443 			break;
1444 		}
1445 	}
1446 
1447 	return rc;
1448 }
1449 
1450 static int
1451 sfc_flow_spec_remove(struct sfc_adapter *sa, struct sfc_flow_spec *spec)
1452 {
1453 	struct sfc_flow_spec_filter *spec_filter = &spec->filter;
1454 
1455 	return sfc_flow_spec_flush(sa, spec, spec_filter->count);
1456 }
1457 
1458 static int
1459 sfc_flow_filter_insert(struct sfc_adapter *sa,
1460 		       struct rte_flow *flow)
1461 {
1462 	struct sfc_adapter_shared * const sas = sfc_sa2shared(sa);
1463 	struct sfc_rss *rss = &sas->rss;
1464 	struct sfc_flow_spec_filter *spec_filter = &flow->spec.filter;
1465 	struct sfc_flow_rss *flow_rss = &spec_filter->rss_conf;
1466 	uint32_t efs_rss_context = EFX_RSS_CONTEXT_DEFAULT;
1467 	unsigned int i;
1468 	int rc = 0;
1469 
1470 	if (spec_filter->rss) {
1471 		unsigned int rss_spread = MIN(flow_rss->rxq_hw_index_max -
1472 					      flow_rss->rxq_hw_index_min + 1,
1473 					      EFX_MAXRSS);
1474 
1475 		rc = efx_rx_scale_context_alloc(sa->nic,
1476 						EFX_RX_SCALE_EXCLUSIVE,
1477 						rss_spread,
1478 						&efs_rss_context);
1479 		if (rc != 0)
1480 			goto fail_scale_context_alloc;
1481 
1482 		rc = efx_rx_scale_mode_set(sa->nic, efs_rss_context,
1483 					   rss->hash_alg,
1484 					   flow_rss->rss_hash_types, B_TRUE);
1485 		if (rc != 0)
1486 			goto fail_scale_mode_set;
1487 
1488 		rc = efx_rx_scale_key_set(sa->nic, efs_rss_context,
1489 					  flow_rss->rss_key,
1490 					  sizeof(rss->key));
1491 		if (rc != 0)
1492 			goto fail_scale_key_set;
1493 
1494 		/*
1495 		 * At this point, fully elaborated filter specifications
1496 		 * have been produced from the template. To make sure that
1497 		 * RSS behaviour is consistent between them, set the same
1498 		 * RSS context value everywhere.
1499 		 */
1500 		for (i = 0; i < spec_filter->count; i++) {
1501 			efx_filter_spec_t *spec = &spec_filter->filters[i];
1502 
1503 			spec->efs_rss_context = efs_rss_context;
1504 			spec->efs_dmaq_id = flow_rss->rxq_hw_index_min;
1505 			spec->efs_flags |= EFX_FILTER_FLAG_RX_RSS;
1506 		}
1507 	}
1508 
1509 	rc = sfc_flow_spec_insert(sa, &flow->spec);
1510 	if (rc != 0)
1511 		goto fail_filter_insert;
1512 
1513 	if (spec_filter->rss) {
1514 		/*
1515 		 * Scale table is set after filter insertion because
1516 		 * the table entries are relative to the base RxQ ID
1517 		 * and the latter is submitted to the HW by means of
1518 		 * inserting a filter, so by the time of the request
1519 		 * the HW knows all the information needed to verify
1520 		 * the table entries, and the operation will succeed
1521 		 */
1522 		rc = efx_rx_scale_tbl_set(sa->nic, efs_rss_context,
1523 					  flow_rss->rss_tbl,
1524 					  RTE_DIM(flow_rss->rss_tbl));
1525 		if (rc != 0)
1526 			goto fail_scale_tbl_set;
1527 	}
1528 
1529 	return 0;
1530 
1531 fail_scale_tbl_set:
1532 	sfc_flow_spec_remove(sa, &flow->spec);
1533 
1534 fail_filter_insert:
1535 fail_scale_key_set:
1536 fail_scale_mode_set:
1537 	if (efs_rss_context != EFX_RSS_CONTEXT_DEFAULT)
1538 		efx_rx_scale_context_free(sa->nic, efs_rss_context);
1539 
1540 fail_scale_context_alloc:
1541 	return rc;
1542 }
1543 
1544 static int
1545 sfc_flow_filter_remove(struct sfc_adapter *sa,
1546 		       struct rte_flow *flow)
1547 {
1548 	struct sfc_flow_spec_filter *spec_filter = &flow->spec.filter;
1549 	int rc = 0;
1550 
1551 	rc = sfc_flow_spec_remove(sa, &flow->spec);
1552 	if (rc != 0)
1553 		return rc;
1554 
1555 	if (spec_filter->rss) {
1556 		/*
1557 		 * All specifications for a given flow rule have the same RSS
1558 		 * context, so that RSS context value is taken from the first
1559 		 * filter specification
1560 		 */
1561 		efx_filter_spec_t *spec = &spec_filter->filters[0];
1562 
1563 		rc = efx_rx_scale_context_free(sa->nic, spec->efs_rss_context);
1564 	}
1565 
1566 	return rc;
1567 }
1568 
1569 static int
1570 sfc_flow_parse_mark(struct sfc_adapter *sa,
1571 		    const struct rte_flow_action_mark *mark,
1572 		    struct rte_flow *flow)
1573 {
1574 	struct sfc_flow_spec *spec = &flow->spec;
1575 	struct sfc_flow_spec_filter *spec_filter = &spec->filter;
1576 	const efx_nic_cfg_t *encp = efx_nic_cfg_get(sa->nic);
1577 
1578 	if (mark == NULL || mark->id > encp->enc_filter_action_mark_max)
1579 		return EINVAL;
1580 
1581 	spec_filter->template.efs_flags |= EFX_FILTER_FLAG_ACTION_MARK;
1582 	spec_filter->template.efs_mark = mark->id;
1583 
1584 	return 0;
1585 }
1586 
1587 static int
1588 sfc_flow_parse_actions(struct sfc_adapter *sa,
1589 		       const struct rte_flow_action actions[],
1590 		       struct rte_flow *flow,
1591 		       struct rte_flow_error *error)
1592 {
1593 	int rc;
1594 	struct sfc_flow_spec *spec = &flow->spec;
1595 	struct sfc_flow_spec_filter *spec_filter = &spec->filter;
1596 	const unsigned int dp_rx_features = sa->priv.dp_rx->features;
1597 	uint32_t actions_set = 0;
1598 	const uint32_t fate_actions_mask = (1UL << RTE_FLOW_ACTION_TYPE_QUEUE) |
1599 					   (1UL << RTE_FLOW_ACTION_TYPE_RSS) |
1600 					   (1UL << RTE_FLOW_ACTION_TYPE_DROP);
1601 	const uint32_t mark_actions_mask = (1UL << RTE_FLOW_ACTION_TYPE_MARK) |
1602 					   (1UL << RTE_FLOW_ACTION_TYPE_FLAG);
1603 
1604 	if (actions == NULL) {
1605 		rte_flow_error_set(error, EINVAL,
1606 				   RTE_FLOW_ERROR_TYPE_ACTION_NUM, NULL,
1607 				   "NULL actions");
1608 		return -rte_errno;
1609 	}
1610 
1611 #define SFC_BUILD_SET_OVERFLOW(_action, _set) \
1612 	RTE_BUILD_BUG_ON(_action >= sizeof(_set) * CHAR_BIT)
1613 
1614 	for (; actions->type != RTE_FLOW_ACTION_TYPE_END; actions++) {
1615 		switch (actions->type) {
1616 		case RTE_FLOW_ACTION_TYPE_VOID:
1617 			SFC_BUILD_SET_OVERFLOW(RTE_FLOW_ACTION_TYPE_VOID,
1618 					       actions_set);
1619 			break;
1620 
1621 		case RTE_FLOW_ACTION_TYPE_QUEUE:
1622 			SFC_BUILD_SET_OVERFLOW(RTE_FLOW_ACTION_TYPE_QUEUE,
1623 					       actions_set);
1624 			if ((actions_set & fate_actions_mask) != 0)
1625 				goto fail_fate_actions;
1626 
1627 			rc = sfc_flow_parse_queue(sa, actions->conf, flow);
1628 			if (rc != 0) {
1629 				rte_flow_error_set(error, EINVAL,
1630 					RTE_FLOW_ERROR_TYPE_ACTION, actions,
1631 					"Bad QUEUE action");
1632 				return -rte_errno;
1633 			}
1634 			break;
1635 
1636 		case RTE_FLOW_ACTION_TYPE_RSS:
1637 			SFC_BUILD_SET_OVERFLOW(RTE_FLOW_ACTION_TYPE_RSS,
1638 					       actions_set);
1639 			if ((actions_set & fate_actions_mask) != 0)
1640 				goto fail_fate_actions;
1641 
1642 			rc = sfc_flow_parse_rss(sa, actions->conf, flow);
1643 			if (rc != 0) {
1644 				rte_flow_error_set(error, -rc,
1645 					RTE_FLOW_ERROR_TYPE_ACTION, actions,
1646 					"Bad RSS action");
1647 				return -rte_errno;
1648 			}
1649 			break;
1650 
1651 		case RTE_FLOW_ACTION_TYPE_DROP:
1652 			SFC_BUILD_SET_OVERFLOW(RTE_FLOW_ACTION_TYPE_DROP,
1653 					       actions_set);
1654 			if ((actions_set & fate_actions_mask) != 0)
1655 				goto fail_fate_actions;
1656 
1657 			spec_filter->template.efs_dmaq_id =
1658 				EFX_FILTER_SPEC_RX_DMAQ_ID_DROP;
1659 			break;
1660 
1661 		case RTE_FLOW_ACTION_TYPE_FLAG:
1662 			SFC_BUILD_SET_OVERFLOW(RTE_FLOW_ACTION_TYPE_FLAG,
1663 					       actions_set);
1664 			if ((actions_set & mark_actions_mask) != 0)
1665 				goto fail_actions_overlap;
1666 
1667 			if ((dp_rx_features & SFC_DP_RX_FEAT_FLOW_FLAG) == 0) {
1668 				rte_flow_error_set(error, ENOTSUP,
1669 					RTE_FLOW_ERROR_TYPE_ACTION, NULL,
1670 					"FLAG action is not supported on the current Rx datapath");
1671 				return -rte_errno;
1672 			}
1673 
1674 			spec_filter->template.efs_flags |=
1675 				EFX_FILTER_FLAG_ACTION_FLAG;
1676 			break;
1677 
1678 		case RTE_FLOW_ACTION_TYPE_MARK:
1679 			SFC_BUILD_SET_OVERFLOW(RTE_FLOW_ACTION_TYPE_MARK,
1680 					       actions_set);
1681 			if ((actions_set & mark_actions_mask) != 0)
1682 				goto fail_actions_overlap;
1683 
1684 			if ((dp_rx_features & SFC_DP_RX_FEAT_FLOW_MARK) == 0) {
1685 				rte_flow_error_set(error, ENOTSUP,
1686 					RTE_FLOW_ERROR_TYPE_ACTION, NULL,
1687 					"MARK action is not supported on the current Rx datapath");
1688 				return -rte_errno;
1689 			}
1690 
1691 			rc = sfc_flow_parse_mark(sa, actions->conf, flow);
1692 			if (rc != 0) {
1693 				rte_flow_error_set(error, rc,
1694 					RTE_FLOW_ERROR_TYPE_ACTION, actions,
1695 					"Bad MARK action");
1696 				return -rte_errno;
1697 			}
1698 			break;
1699 
1700 		default:
1701 			rte_flow_error_set(error, ENOTSUP,
1702 					   RTE_FLOW_ERROR_TYPE_ACTION, actions,
1703 					   "Action is not supported");
1704 			return -rte_errno;
1705 		}
1706 
1707 		actions_set |= (1UL << actions->type);
1708 	}
1709 #undef SFC_BUILD_SET_OVERFLOW
1710 
1711 	/* When fate is unknown, drop traffic. */
1712 	if ((actions_set & fate_actions_mask) == 0) {
1713 		spec_filter->template.efs_dmaq_id =
1714 			EFX_FILTER_SPEC_RX_DMAQ_ID_DROP;
1715 	}
1716 
1717 	return 0;
1718 
1719 fail_fate_actions:
1720 	rte_flow_error_set(error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ACTION, actions,
1721 			   "Cannot combine several fate-deciding actions, "
1722 			   "choose between QUEUE, RSS or DROP");
1723 	return -rte_errno;
1724 
1725 fail_actions_overlap:
1726 	rte_flow_error_set(error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ACTION, actions,
1727 			   "Overlapping actions are not supported");
1728 	return -rte_errno;
1729 }
1730 
1731 /**
1732  * Set the EFX_FILTER_MATCH_UNKNOWN_UCAST_DST
1733  * and EFX_FILTER_MATCH_UNKNOWN_MCAST_DST match flags in the same
1734  * specifications after copying.
1735  *
1736  * @param spec[in, out]
1737  *   SFC flow specification to update.
1738  * @param filters_count_for_one_val[in]
1739  *   How many specifications should have the same match flag, what is the
1740  *   number of specifications before copying.
1741  * @param error[out]
1742  *   Perform verbose error reporting if not NULL.
1743  */
1744 static int
1745 sfc_flow_set_unknown_dst_flags(struct sfc_flow_spec *spec,
1746 			       unsigned int filters_count_for_one_val,
1747 			       struct rte_flow_error *error)
1748 {
1749 	unsigned int i;
1750 	struct sfc_flow_spec_filter *spec_filter = &spec->filter;
1751 	static const efx_filter_match_flags_t vals[] = {
1752 		EFX_FILTER_MATCH_UNKNOWN_UCAST_DST,
1753 		EFX_FILTER_MATCH_UNKNOWN_MCAST_DST
1754 	};
1755 
1756 	if (filters_count_for_one_val * RTE_DIM(vals) != spec_filter->count) {
1757 		rte_flow_error_set(error, EINVAL,
1758 			RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
1759 			"Number of specifications is incorrect while copying "
1760 			"by unknown destination flags");
1761 		return -rte_errno;
1762 	}
1763 
1764 	for (i = 0; i < spec_filter->count; i++) {
1765 		/* The check above ensures that divisor can't be zero here */
1766 		spec_filter->filters[i].efs_match_flags |=
1767 			vals[i / filters_count_for_one_val];
1768 	}
1769 
1770 	return 0;
1771 }
1772 
1773 /**
1774  * Check that the following conditions are met:
1775  * - the list of supported filters has a filter
1776  *   with EFX_FILTER_MATCH_UNKNOWN_MCAST_DST flag instead of
1777  *   EFX_FILTER_MATCH_UNKNOWN_UCAST_DST, since this filter will also
1778  *   be inserted.
1779  *
1780  * @param match[in]
1781  *   The match flags of filter.
1782  * @param spec[in]
1783  *   Specification to be supplemented.
1784  * @param filter[in]
1785  *   SFC filter with list of supported filters.
1786  */
1787 static boolean_t
1788 sfc_flow_check_unknown_dst_flags(efx_filter_match_flags_t match,
1789 				 __rte_unused efx_filter_spec_t *spec,
1790 				 struct sfc_filter *filter)
1791 {
1792 	unsigned int i;
1793 	efx_filter_match_flags_t match_mcast_dst;
1794 
1795 	match_mcast_dst =
1796 		(match & ~EFX_FILTER_MATCH_UNKNOWN_UCAST_DST) |
1797 		EFX_FILTER_MATCH_UNKNOWN_MCAST_DST;
1798 	for (i = 0; i < filter->supported_match_num; i++) {
1799 		if (match_mcast_dst == filter->supported_match[i])
1800 			return B_TRUE;
1801 	}
1802 
1803 	return B_FALSE;
1804 }
1805 
1806 /**
1807  * Set the EFX_FILTER_MATCH_ETHER_TYPE match flag and EFX_ETHER_TYPE_IPV4 and
1808  * EFX_ETHER_TYPE_IPV6 values of the corresponding field in the same
1809  * specifications after copying.
1810  *
1811  * @param spec[in, out]
1812  *   SFC flow specification to update.
1813  * @param filters_count_for_one_val[in]
1814  *   How many specifications should have the same EtherType value, what is the
1815  *   number of specifications before copying.
1816  * @param error[out]
1817  *   Perform verbose error reporting if not NULL.
1818  */
1819 static int
1820 sfc_flow_set_ethertypes(struct sfc_flow_spec *spec,
1821 			unsigned int filters_count_for_one_val,
1822 			struct rte_flow_error *error)
1823 {
1824 	unsigned int i;
1825 	struct sfc_flow_spec_filter *spec_filter = &spec->filter;
1826 	static const uint16_t vals[] = {
1827 		EFX_ETHER_TYPE_IPV4, EFX_ETHER_TYPE_IPV6
1828 	};
1829 
1830 	if (filters_count_for_one_val * RTE_DIM(vals) != spec_filter->count) {
1831 		rte_flow_error_set(error, EINVAL,
1832 			RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
1833 			"Number of specifications is incorrect "
1834 			"while copying by Ethertype");
1835 		return -rte_errno;
1836 	}
1837 
1838 	for (i = 0; i < spec_filter->count; i++) {
1839 		spec_filter->filters[i].efs_match_flags |=
1840 			EFX_FILTER_MATCH_ETHER_TYPE;
1841 
1842 		/*
1843 		 * The check above ensures that
1844 		 * filters_count_for_one_val is not 0
1845 		 */
1846 		spec_filter->filters[i].efs_ether_type =
1847 			vals[i / filters_count_for_one_val];
1848 	}
1849 
1850 	return 0;
1851 }
1852 
1853 /**
1854  * Set the EFX_FILTER_MATCH_OUTER_VID match flag with value 0
1855  * in the same specifications after copying.
1856  *
1857  * @param spec[in, out]
1858  *   SFC flow specification to update.
1859  * @param filters_count_for_one_val[in]
1860  *   How many specifications should have the same match flag, what is the
1861  *   number of specifications before copying.
1862  * @param error[out]
1863  *   Perform verbose error reporting if not NULL.
1864  */
1865 static int
1866 sfc_flow_set_outer_vid_flag(struct sfc_flow_spec *spec,
1867 			    unsigned int filters_count_for_one_val,
1868 			    struct rte_flow_error *error)
1869 {
1870 	struct sfc_flow_spec_filter *spec_filter = &spec->filter;
1871 	unsigned int i;
1872 
1873 	if (filters_count_for_one_val != spec_filter->count) {
1874 		rte_flow_error_set(error, EINVAL,
1875 			RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
1876 			"Number of specifications is incorrect "
1877 			"while copying by outer VLAN ID");
1878 		return -rte_errno;
1879 	}
1880 
1881 	for (i = 0; i < spec_filter->count; i++) {
1882 		spec_filter->filters[i].efs_match_flags |=
1883 			EFX_FILTER_MATCH_OUTER_VID;
1884 
1885 		spec_filter->filters[i].efs_outer_vid = 0;
1886 	}
1887 
1888 	return 0;
1889 }
1890 
1891 /**
1892  * Set the EFX_FILTER_MATCH_IFRM_UNKNOWN_UCAST_DST and
1893  * EFX_FILTER_MATCH_IFRM_UNKNOWN_MCAST_DST match flags in the same
1894  * specifications after copying.
1895  *
1896  * @param spec[in, out]
1897  *   SFC flow specification to update.
1898  * @param filters_count_for_one_val[in]
1899  *   How many specifications should have the same match flag, what is the
1900  *   number of specifications before copying.
1901  * @param error[out]
1902  *   Perform verbose error reporting if not NULL.
1903  */
1904 static int
1905 sfc_flow_set_ifrm_unknown_dst_flags(struct sfc_flow_spec *spec,
1906 				    unsigned int filters_count_for_one_val,
1907 				    struct rte_flow_error *error)
1908 {
1909 	unsigned int i;
1910 	struct sfc_flow_spec_filter *spec_filter = &spec->filter;
1911 	static const efx_filter_match_flags_t vals[] = {
1912 		EFX_FILTER_MATCH_IFRM_UNKNOWN_UCAST_DST,
1913 		EFX_FILTER_MATCH_IFRM_UNKNOWN_MCAST_DST
1914 	};
1915 
1916 	if (filters_count_for_one_val * RTE_DIM(vals) != spec_filter->count) {
1917 		rte_flow_error_set(error, EINVAL,
1918 			RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
1919 			"Number of specifications is incorrect while copying "
1920 			"by inner frame unknown destination flags");
1921 		return -rte_errno;
1922 	}
1923 
1924 	for (i = 0; i < spec_filter->count; i++) {
1925 		/* The check above ensures that divisor can't be zero here */
1926 		spec_filter->filters[i].efs_match_flags |=
1927 			vals[i / filters_count_for_one_val];
1928 	}
1929 
1930 	return 0;
1931 }
1932 
1933 /**
1934  * Check that the following conditions are met:
1935  * - the specification corresponds to a filter for encapsulated traffic
1936  * - the list of supported filters has a filter
1937  *   with EFX_FILTER_MATCH_IFRM_UNKNOWN_MCAST_DST flag instead of
1938  *   EFX_FILTER_MATCH_IFRM_UNKNOWN_UCAST_DST, since this filter will also
1939  *   be inserted.
1940  *
1941  * @param match[in]
1942  *   The match flags of filter.
1943  * @param spec[in]
1944  *   Specification to be supplemented.
1945  * @param filter[in]
1946  *   SFC filter with list of supported filters.
1947  */
1948 static boolean_t
1949 sfc_flow_check_ifrm_unknown_dst_flags(efx_filter_match_flags_t match,
1950 				      efx_filter_spec_t *spec,
1951 				      struct sfc_filter *filter)
1952 {
1953 	unsigned int i;
1954 	efx_tunnel_protocol_t encap_type = spec->efs_encap_type;
1955 	efx_filter_match_flags_t match_mcast_dst;
1956 
1957 	if (encap_type == EFX_TUNNEL_PROTOCOL_NONE)
1958 		return B_FALSE;
1959 
1960 	match_mcast_dst =
1961 		(match & ~EFX_FILTER_MATCH_IFRM_UNKNOWN_UCAST_DST) |
1962 		EFX_FILTER_MATCH_IFRM_UNKNOWN_MCAST_DST;
1963 	for (i = 0; i < filter->supported_match_num; i++) {
1964 		if (match_mcast_dst == filter->supported_match[i])
1965 			return B_TRUE;
1966 	}
1967 
1968 	return B_FALSE;
1969 }
1970 
1971 /**
1972  * Check that the list of supported filters has a filter that differs
1973  * from @p match in that it has no flag EFX_FILTER_MATCH_OUTER_VID
1974  * in this case that filter will be used and the flag
1975  * EFX_FILTER_MATCH_OUTER_VID is not needed.
1976  *
1977  * @param match[in]
1978  *   The match flags of filter.
1979  * @param spec[in]
1980  *   Specification to be supplemented.
1981  * @param filter[in]
1982  *   SFC filter with list of supported filters.
1983  */
1984 static boolean_t
1985 sfc_flow_check_outer_vid_flag(efx_filter_match_flags_t match,
1986 			      __rte_unused efx_filter_spec_t *spec,
1987 			      struct sfc_filter *filter)
1988 {
1989 	unsigned int i;
1990 	efx_filter_match_flags_t match_without_vid =
1991 		match & ~EFX_FILTER_MATCH_OUTER_VID;
1992 
1993 	for (i = 0; i < filter->supported_match_num; i++) {
1994 		if (match_without_vid == filter->supported_match[i])
1995 			return B_FALSE;
1996 	}
1997 
1998 	return B_TRUE;
1999 }
2000 
2001 /*
2002  * Match flags that can be automatically added to filters.
2003  * Selecting the last minimum when searching for the copy flag ensures that the
2004  * EFX_FILTER_MATCH_UNKNOWN_UCAST_DST flag has a higher priority than
2005  * EFX_FILTER_MATCH_ETHER_TYPE. This is because the filter
2006  * EFX_FILTER_MATCH_UNKNOWN_UCAST_DST is at the end of the list of supported
2007  * filters.
2008  */
2009 static const struct sfc_flow_copy_flag sfc_flow_copy_flags[] = {
2010 	{
2011 		.flag = EFX_FILTER_MATCH_UNKNOWN_UCAST_DST,
2012 		.vals_count = 2,
2013 		.set_vals = sfc_flow_set_unknown_dst_flags,
2014 		.spec_check = sfc_flow_check_unknown_dst_flags,
2015 	},
2016 	{
2017 		.flag = EFX_FILTER_MATCH_ETHER_TYPE,
2018 		.vals_count = 2,
2019 		.set_vals = sfc_flow_set_ethertypes,
2020 		.spec_check = NULL,
2021 	},
2022 	{
2023 		.flag = EFX_FILTER_MATCH_IFRM_UNKNOWN_UCAST_DST,
2024 		.vals_count = 2,
2025 		.set_vals = sfc_flow_set_ifrm_unknown_dst_flags,
2026 		.spec_check = sfc_flow_check_ifrm_unknown_dst_flags,
2027 	},
2028 	{
2029 		.flag = EFX_FILTER_MATCH_OUTER_VID,
2030 		.vals_count = 1,
2031 		.set_vals = sfc_flow_set_outer_vid_flag,
2032 		.spec_check = sfc_flow_check_outer_vid_flag,
2033 	},
2034 };
2035 
2036 /* Get item from array sfc_flow_copy_flags */
2037 static const struct sfc_flow_copy_flag *
2038 sfc_flow_get_copy_flag(efx_filter_match_flags_t flag)
2039 {
2040 	unsigned int i;
2041 
2042 	for (i = 0; i < RTE_DIM(sfc_flow_copy_flags); i++) {
2043 		if (sfc_flow_copy_flags[i].flag == flag)
2044 			return &sfc_flow_copy_flags[i];
2045 	}
2046 
2047 	return NULL;
2048 }
2049 
2050 /**
2051  * Make copies of the specifications, set match flag and values
2052  * of the field that corresponds to it.
2053  *
2054  * @param spec[in, out]
2055  *   SFC flow specification to update.
2056  * @param flag[in]
2057  *   The match flag to add.
2058  * @param error[out]
2059  *   Perform verbose error reporting if not NULL.
2060  */
2061 static int
2062 sfc_flow_spec_add_match_flag(struct sfc_flow_spec *spec,
2063 			     efx_filter_match_flags_t flag,
2064 			     struct rte_flow_error *error)
2065 {
2066 	unsigned int i;
2067 	unsigned int new_filters_count;
2068 	unsigned int filters_count_for_one_val;
2069 	const struct sfc_flow_copy_flag *copy_flag;
2070 	struct sfc_flow_spec_filter *spec_filter = &spec->filter;
2071 	int rc;
2072 
2073 	copy_flag = sfc_flow_get_copy_flag(flag);
2074 	if (copy_flag == NULL) {
2075 		rte_flow_error_set(error, ENOTSUP,
2076 				   RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
2077 				   "Unsupported spec field for copying");
2078 		return -rte_errno;
2079 	}
2080 
2081 	new_filters_count = spec_filter->count * copy_flag->vals_count;
2082 	if (new_filters_count > SF_FLOW_SPEC_NB_FILTERS_MAX) {
2083 		rte_flow_error_set(error, EINVAL,
2084 			RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
2085 			"Too much EFX specifications in the flow rule");
2086 		return -rte_errno;
2087 	}
2088 
2089 	/* Copy filters specifications */
2090 	for (i = spec_filter->count; i < new_filters_count; i++) {
2091 		spec_filter->filters[i] =
2092 			spec_filter->filters[i - spec_filter->count];
2093 	}
2094 
2095 	filters_count_for_one_val = spec_filter->count;
2096 	spec_filter->count = new_filters_count;
2097 
2098 	rc = copy_flag->set_vals(spec, filters_count_for_one_val, error);
2099 	if (rc != 0)
2100 		return rc;
2101 
2102 	return 0;
2103 }
2104 
2105 /**
2106  * Check that the given set of match flags missing in the original filter spec
2107  * could be covered by adding spec copies which specify the corresponding
2108  * flags and packet field values to match.
2109  *
2110  * @param miss_flags[in]
2111  *   Flags that are missing until the supported filter.
2112  * @param spec[in]
2113  *   Specification to be supplemented.
2114  * @param filter[in]
2115  *   SFC filter.
2116  *
2117  * @return
2118  *   Number of specifications after copy or 0, if the flags can not be added.
2119  */
2120 static unsigned int
2121 sfc_flow_check_missing_flags(efx_filter_match_flags_t miss_flags,
2122 			     efx_filter_spec_t *spec,
2123 			     struct sfc_filter *filter)
2124 {
2125 	unsigned int i;
2126 	efx_filter_match_flags_t copy_flags = 0;
2127 	efx_filter_match_flags_t flag;
2128 	efx_filter_match_flags_t match = spec->efs_match_flags | miss_flags;
2129 	sfc_flow_spec_check *check;
2130 	unsigned int multiplier = 1;
2131 
2132 	for (i = 0; i < RTE_DIM(sfc_flow_copy_flags); i++) {
2133 		flag = sfc_flow_copy_flags[i].flag;
2134 		check = sfc_flow_copy_flags[i].spec_check;
2135 		if ((flag & miss_flags) == flag) {
2136 			if (check != NULL && (!check(match, spec, filter)))
2137 				continue;
2138 
2139 			copy_flags |= flag;
2140 			multiplier *= sfc_flow_copy_flags[i].vals_count;
2141 		}
2142 	}
2143 
2144 	if (copy_flags == miss_flags)
2145 		return multiplier;
2146 
2147 	return 0;
2148 }
2149 
2150 /**
2151  * Attempt to supplement the specification template to the minimally
2152  * supported set of match flags. To do this, it is necessary to copy
2153  * the specifications, filling them with the values of fields that
2154  * correspond to the missing flags.
2155  * The necessary and sufficient filter is built from the fewest number
2156  * of copies which could be made to cover the minimally required set
2157  * of flags.
2158  *
2159  * @param sa[in]
2160  *   SFC adapter.
2161  * @param spec[in, out]
2162  *   SFC flow specification to update.
2163  * @param error[out]
2164  *   Perform verbose error reporting if not NULL.
2165  */
2166 static int
2167 sfc_flow_spec_filters_complete(struct sfc_adapter *sa,
2168 			       struct sfc_flow_spec *spec,
2169 			       struct rte_flow_error *error)
2170 {
2171 	struct sfc_flow_spec_filter *spec_filter = &spec->filter;
2172 	struct sfc_filter *filter = &sa->filter;
2173 	efx_filter_match_flags_t miss_flags;
2174 	efx_filter_match_flags_t min_miss_flags = 0;
2175 	efx_filter_match_flags_t match;
2176 	unsigned int min_multiplier = UINT_MAX;
2177 	unsigned int multiplier;
2178 	unsigned int i;
2179 	int rc;
2180 
2181 	match = spec_filter->template.efs_match_flags;
2182 	for (i = 0; i < filter->supported_match_num; i++) {
2183 		if ((match & filter->supported_match[i]) == match) {
2184 			miss_flags = filter->supported_match[i] & (~match);
2185 			multiplier = sfc_flow_check_missing_flags(miss_flags,
2186 				&spec_filter->template, filter);
2187 			if (multiplier > 0) {
2188 				if (multiplier <= min_multiplier) {
2189 					min_multiplier = multiplier;
2190 					min_miss_flags = miss_flags;
2191 				}
2192 			}
2193 		}
2194 	}
2195 
2196 	if (min_multiplier == UINT_MAX) {
2197 		rte_flow_error_set(error, ENOTSUP,
2198 				   RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
2199 				   "The flow rule pattern is unsupported");
2200 		return -rte_errno;
2201 	}
2202 
2203 	for (i = 0; i < RTE_DIM(sfc_flow_copy_flags); i++) {
2204 		efx_filter_match_flags_t flag = sfc_flow_copy_flags[i].flag;
2205 
2206 		if ((flag & min_miss_flags) == flag) {
2207 			rc = sfc_flow_spec_add_match_flag(spec, flag, error);
2208 			if (rc != 0)
2209 				return rc;
2210 		}
2211 	}
2212 
2213 	return 0;
2214 }
2215 
2216 /**
2217  * Check that set of match flags is referred to by a filter. Filter is
2218  * described by match flags with the ability to add OUTER_VID and INNER_VID
2219  * flags.
2220  *
2221  * @param match_flags[in]
2222  *   Set of match flags.
2223  * @param flags_pattern[in]
2224  *   Pattern of filter match flags.
2225  */
2226 static boolean_t
2227 sfc_flow_is_match_with_vids(efx_filter_match_flags_t match_flags,
2228 			    efx_filter_match_flags_t flags_pattern)
2229 {
2230 	if ((match_flags & flags_pattern) != flags_pattern)
2231 		return B_FALSE;
2232 
2233 	switch (match_flags & ~flags_pattern) {
2234 	case 0:
2235 	case EFX_FILTER_MATCH_OUTER_VID:
2236 	case EFX_FILTER_MATCH_OUTER_VID | EFX_FILTER_MATCH_INNER_VID:
2237 		return B_TRUE;
2238 	default:
2239 		return B_FALSE;
2240 	}
2241 }
2242 
2243 /**
2244  * Check whether the spec maps to a hardware filter which is known to be
2245  * ineffective despite being valid.
2246  *
2247  * @param filter[in]
2248  *   SFC filter with list of supported filters.
2249  * @param spec[in]
2250  *   SFC flow specification.
2251  */
2252 static boolean_t
2253 sfc_flow_is_match_flags_exception(struct sfc_filter *filter,
2254 				  struct sfc_flow_spec *spec)
2255 {
2256 	unsigned int i;
2257 	uint16_t ether_type;
2258 	uint8_t ip_proto;
2259 	efx_filter_match_flags_t match_flags;
2260 	struct sfc_flow_spec_filter *spec_filter = &spec->filter;
2261 
2262 	for (i = 0; i < spec_filter->count; i++) {
2263 		match_flags = spec_filter->filters[i].efs_match_flags;
2264 
2265 		if (sfc_flow_is_match_with_vids(match_flags,
2266 						EFX_FILTER_MATCH_ETHER_TYPE) ||
2267 		    sfc_flow_is_match_with_vids(match_flags,
2268 						EFX_FILTER_MATCH_ETHER_TYPE |
2269 						EFX_FILTER_MATCH_LOC_MAC)) {
2270 			ether_type = spec_filter->filters[i].efs_ether_type;
2271 			if (filter->supports_ip_proto_or_addr_filter &&
2272 			    (ether_type == EFX_ETHER_TYPE_IPV4 ||
2273 			     ether_type == EFX_ETHER_TYPE_IPV6))
2274 				return B_TRUE;
2275 		} else if (sfc_flow_is_match_with_vids(match_flags,
2276 				EFX_FILTER_MATCH_ETHER_TYPE |
2277 				EFX_FILTER_MATCH_IP_PROTO) ||
2278 			   sfc_flow_is_match_with_vids(match_flags,
2279 				EFX_FILTER_MATCH_ETHER_TYPE |
2280 				EFX_FILTER_MATCH_IP_PROTO |
2281 				EFX_FILTER_MATCH_LOC_MAC)) {
2282 			ip_proto = spec_filter->filters[i].efs_ip_proto;
2283 			if (filter->supports_rem_or_local_port_filter &&
2284 			    (ip_proto == EFX_IPPROTO_TCP ||
2285 			     ip_proto == EFX_IPPROTO_UDP))
2286 				return B_TRUE;
2287 		}
2288 	}
2289 
2290 	return B_FALSE;
2291 }
2292 
2293 static int
2294 sfc_flow_validate_match_flags(struct sfc_adapter *sa,
2295 			      struct rte_flow *flow,
2296 			      struct rte_flow_error *error)
2297 {
2298 	struct sfc_flow_spec *spec = &flow->spec;
2299 	struct sfc_flow_spec_filter *spec_filter = &spec->filter;
2300 	efx_filter_spec_t *spec_tmpl = &spec_filter->template;
2301 	efx_filter_match_flags_t match_flags = spec_tmpl->efs_match_flags;
2302 	int rc;
2303 
2304 	/* Initialize the first filter spec with template */
2305 	spec_filter->filters[0] = *spec_tmpl;
2306 	spec_filter->count = 1;
2307 
2308 	if (!sfc_filter_is_match_supported(sa, match_flags)) {
2309 		rc = sfc_flow_spec_filters_complete(sa, &flow->spec, error);
2310 		if (rc != 0)
2311 			return rc;
2312 	}
2313 
2314 	if (sfc_flow_is_match_flags_exception(&sa->filter, &flow->spec)) {
2315 		rte_flow_error_set(error, ENOTSUP,
2316 			RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
2317 			"The flow rule pattern is unsupported");
2318 		return -rte_errno;
2319 	}
2320 
2321 	return 0;
2322 }
2323 
2324 static int
2325 sfc_flow_parse_rte_to_filter(struct rte_eth_dev *dev,
2326 			     const struct rte_flow_item pattern[],
2327 			     const struct rte_flow_action actions[],
2328 			     struct rte_flow *flow,
2329 			     struct rte_flow_error *error)
2330 {
2331 	struct sfc_adapter *sa = sfc_adapter_by_eth_dev(dev);
2332 	struct sfc_flow_spec *spec = &flow->spec;
2333 	struct sfc_flow_spec_filter *spec_filter = &spec->filter;
2334 	struct sfc_flow_parse_ctx ctx;
2335 	int rc;
2336 
2337 	ctx.type = SFC_FLOW_PARSE_CTX_FILTER;
2338 	ctx.filter = &spec_filter->template;
2339 
2340 	rc = sfc_flow_parse_pattern(sfc_flow_items, RTE_DIM(sfc_flow_items),
2341 				    pattern, &ctx, error);
2342 	if (rc != 0)
2343 		goto fail_bad_value;
2344 
2345 	rc = sfc_flow_parse_actions(sa, actions, flow, error);
2346 	if (rc != 0)
2347 		goto fail_bad_value;
2348 
2349 	rc = sfc_flow_validate_match_flags(sa, flow, error);
2350 	if (rc != 0)
2351 		goto fail_bad_value;
2352 
2353 	return 0;
2354 
2355 fail_bad_value:
2356 	return rc;
2357 }
2358 
2359 static int
2360 sfc_flow_parse(struct rte_eth_dev *dev,
2361 	       const struct rte_flow_attr *attr,
2362 	       const struct rte_flow_item pattern[],
2363 	       const struct rte_flow_action actions[],
2364 	       struct rte_flow *flow,
2365 	       struct rte_flow_error *error)
2366 {
2367 	const struct sfc_flow_ops_by_spec *ops;
2368 	int rc;
2369 
2370 	rc = sfc_flow_parse_attr(attr, flow, error);
2371 	if (rc != 0)
2372 		return rc;
2373 
2374 	ops = sfc_flow_get_ops_by_spec(flow);
2375 	if (ops == NULL || ops->parse == NULL) {
2376 		rte_flow_error_set(error, ENOTSUP,
2377 				   RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
2378 				   "No backend to handle this flow");
2379 		return -rte_errno;
2380 	}
2381 
2382 	return ops->parse(dev, pattern, actions, flow, error);
2383 }
2384 
2385 static struct rte_flow *
2386 sfc_flow_zmalloc(struct rte_flow_error *error)
2387 {
2388 	struct rte_flow *flow;
2389 
2390 	flow = rte_zmalloc("sfc_rte_flow", sizeof(*flow), 0);
2391 	if (flow == NULL) {
2392 		rte_flow_error_set(error, ENOMEM,
2393 				   RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
2394 				   "Failed to allocate memory");
2395 	}
2396 
2397 	return flow;
2398 }
2399 
2400 static void
2401 sfc_flow_free(__rte_unused struct sfc_adapter *sa, struct rte_flow *flow)
2402 {
2403 	rte_free(flow);
2404 }
2405 
2406 static int
2407 sfc_flow_insert(struct sfc_adapter *sa, struct rte_flow *flow,
2408 		struct rte_flow_error *error)
2409 {
2410 	const struct sfc_flow_ops_by_spec *ops;
2411 	int rc;
2412 
2413 	ops = sfc_flow_get_ops_by_spec(flow);
2414 	if (ops == NULL || ops->insert == NULL) {
2415 		rte_flow_error_set(error, ENOTSUP,
2416 				   RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
2417 				   "No backend to handle this flow");
2418 		return rte_errno;
2419 	}
2420 
2421 	rc = ops->insert(sa, flow);
2422 	if (rc != 0) {
2423 		rte_flow_error_set(error, rc, RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
2424 				   NULL, "Failed to insert the flow rule");
2425 	}
2426 
2427 	return rc;
2428 }
2429 
2430 static int
2431 sfc_flow_remove(struct sfc_adapter *sa, struct rte_flow *flow,
2432 		struct rte_flow_error *error)
2433 {
2434 	const struct sfc_flow_ops_by_spec *ops;
2435 	int rc;
2436 
2437 	ops = sfc_flow_get_ops_by_spec(flow);
2438 	if (ops == NULL || ops->remove == NULL) {
2439 		rte_flow_error_set(error, ENOTSUP,
2440 				   RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
2441 				   "No backend to handle this flow");
2442 		return rte_errno;
2443 	}
2444 
2445 	rc = ops->remove(sa, flow);
2446 	if (rc != 0) {
2447 		rte_flow_error_set(error, rc, RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
2448 				   NULL, "Failed to remove the flow rule");
2449 	}
2450 
2451 	return rc;
2452 }
2453 
2454 static int
2455 sfc_flow_validate(struct rte_eth_dev *dev,
2456 		  const struct rte_flow_attr *attr,
2457 		  const struct rte_flow_item pattern[],
2458 		  const struct rte_flow_action actions[],
2459 		  struct rte_flow_error *error)
2460 {
2461 	struct sfc_adapter *sa = sfc_adapter_by_eth_dev(dev);
2462 	struct rte_flow *flow;
2463 	int rc;
2464 
2465 	flow = sfc_flow_zmalloc(error);
2466 	if (flow == NULL)
2467 		return -rte_errno;
2468 
2469 	rc = sfc_flow_parse(dev, attr, pattern, actions, flow, error);
2470 
2471 	sfc_flow_free(sa, flow);
2472 
2473 	return rc;
2474 }
2475 
2476 static struct rte_flow *
2477 sfc_flow_create(struct rte_eth_dev *dev,
2478 		const struct rte_flow_attr *attr,
2479 		const struct rte_flow_item pattern[],
2480 		const struct rte_flow_action actions[],
2481 		struct rte_flow_error *error)
2482 {
2483 	struct sfc_adapter *sa = sfc_adapter_by_eth_dev(dev);
2484 	struct rte_flow *flow = NULL;
2485 	int rc;
2486 
2487 	flow = sfc_flow_zmalloc(error);
2488 	if (flow == NULL)
2489 		goto fail_no_mem;
2490 
2491 	rc = sfc_flow_parse(dev, attr, pattern, actions, flow, error);
2492 	if (rc != 0)
2493 		goto fail_bad_value;
2494 
2495 	sfc_adapter_lock(sa);
2496 
2497 	TAILQ_INSERT_TAIL(&sa->flow_list, flow, entries);
2498 
2499 	if (sa->state == SFC_ADAPTER_STARTED) {
2500 		rc = sfc_flow_insert(sa, flow, error);
2501 		if (rc != 0)
2502 			goto fail_flow_insert;
2503 	}
2504 
2505 	sfc_adapter_unlock(sa);
2506 
2507 	return flow;
2508 
2509 fail_flow_insert:
2510 	TAILQ_REMOVE(&sa->flow_list, flow, entries);
2511 
2512 fail_bad_value:
2513 	sfc_flow_free(sa, flow);
2514 	sfc_adapter_unlock(sa);
2515 
2516 fail_no_mem:
2517 	return NULL;
2518 }
2519 
2520 static int
2521 sfc_flow_destroy(struct rte_eth_dev *dev,
2522 		 struct rte_flow *flow,
2523 		 struct rte_flow_error *error)
2524 {
2525 	struct sfc_adapter *sa = sfc_adapter_by_eth_dev(dev);
2526 	struct rte_flow *flow_ptr;
2527 	int rc = EINVAL;
2528 
2529 	sfc_adapter_lock(sa);
2530 
2531 	TAILQ_FOREACH(flow_ptr, &sa->flow_list, entries) {
2532 		if (flow_ptr == flow)
2533 			rc = 0;
2534 	}
2535 	if (rc != 0) {
2536 		rte_flow_error_set(error, rc,
2537 				   RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
2538 				   "Failed to find flow rule to destroy");
2539 		goto fail_bad_value;
2540 	}
2541 
2542 	if (sa->state == SFC_ADAPTER_STARTED)
2543 		rc = sfc_flow_remove(sa, flow, error);
2544 
2545 	TAILQ_REMOVE(&sa->flow_list, flow, entries);
2546 	sfc_flow_free(sa, flow);
2547 
2548 fail_bad_value:
2549 	sfc_adapter_unlock(sa);
2550 
2551 	return -rc;
2552 }
2553 
2554 static int
2555 sfc_flow_flush(struct rte_eth_dev *dev,
2556 	       struct rte_flow_error *error)
2557 {
2558 	struct sfc_adapter *sa = sfc_adapter_by_eth_dev(dev);
2559 	struct rte_flow *flow;
2560 	int ret = 0;
2561 
2562 	sfc_adapter_lock(sa);
2563 
2564 	while ((flow = TAILQ_FIRST(&sa->flow_list)) != NULL) {
2565 		if (sa->state == SFC_ADAPTER_STARTED) {
2566 			int rc;
2567 
2568 			rc = sfc_flow_remove(sa, flow, error);
2569 			if (rc != 0)
2570 				ret = rc;
2571 		}
2572 
2573 		TAILQ_REMOVE(&sa->flow_list, flow, entries);
2574 		sfc_flow_free(sa, flow);
2575 	}
2576 
2577 	sfc_adapter_unlock(sa);
2578 
2579 	return -ret;
2580 }
2581 
2582 static int
2583 sfc_flow_isolate(struct rte_eth_dev *dev, int enable,
2584 		 struct rte_flow_error *error)
2585 {
2586 	struct sfc_adapter *sa = sfc_adapter_by_eth_dev(dev);
2587 	int ret = 0;
2588 
2589 	sfc_adapter_lock(sa);
2590 	if (sa->state != SFC_ADAPTER_INITIALIZED) {
2591 		rte_flow_error_set(error, EBUSY,
2592 				   RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
2593 				   NULL, "please close the port first");
2594 		ret = -rte_errno;
2595 	} else {
2596 		sfc_sa2shared(sa)->isolated = (enable) ? B_TRUE : B_FALSE;
2597 	}
2598 	sfc_adapter_unlock(sa);
2599 
2600 	return ret;
2601 }
2602 
2603 const struct rte_flow_ops sfc_flow_ops = {
2604 	.validate = sfc_flow_validate,
2605 	.create = sfc_flow_create,
2606 	.destroy = sfc_flow_destroy,
2607 	.flush = sfc_flow_flush,
2608 	.query = NULL,
2609 	.isolate = sfc_flow_isolate,
2610 };
2611 
2612 void
2613 sfc_flow_init(struct sfc_adapter *sa)
2614 {
2615 	SFC_ASSERT(sfc_adapter_is_locked(sa));
2616 
2617 	TAILQ_INIT(&sa->flow_list);
2618 }
2619 
2620 void
2621 sfc_flow_fini(struct sfc_adapter *sa)
2622 {
2623 	struct rte_flow *flow;
2624 
2625 	SFC_ASSERT(sfc_adapter_is_locked(sa));
2626 
2627 	while ((flow = TAILQ_FIRST(&sa->flow_list)) != NULL) {
2628 		TAILQ_REMOVE(&sa->flow_list, flow, entries);
2629 		sfc_flow_free(sa, flow);
2630 	}
2631 }
2632 
2633 void
2634 sfc_flow_stop(struct sfc_adapter *sa)
2635 {
2636 	struct rte_flow *flow;
2637 
2638 	SFC_ASSERT(sfc_adapter_is_locked(sa));
2639 
2640 	TAILQ_FOREACH(flow, &sa->flow_list, entries)
2641 		sfc_flow_remove(sa, flow, NULL);
2642 }
2643 
2644 int
2645 sfc_flow_start(struct sfc_adapter *sa)
2646 {
2647 	struct rte_flow *flow;
2648 	int rc = 0;
2649 
2650 	sfc_log_init(sa, "entry");
2651 
2652 	SFC_ASSERT(sfc_adapter_is_locked(sa));
2653 
2654 	TAILQ_FOREACH(flow, &sa->flow_list, entries) {
2655 		rc = sfc_flow_insert(sa, flow, NULL);
2656 		if (rc != 0)
2657 			goto fail_bad_flow;
2658 	}
2659 
2660 	sfc_log_init(sa, "done");
2661 
2662 fail_bad_flow:
2663 	return rc;
2664 }
2665