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