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