net/sfc: support VXLAN in flow API filters
[dpdk.git] / drivers / net / sfc / sfc_flow.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2  *
3  * Copyright (c) 2017-2018 Solarflare Communications Inc.
4  * All rights reserved.
5  *
6  * This software was jointly developed between OKTET Labs (under contract
7  * for Solarflare) and Solarflare Communications, Inc.
8  */
9
10 #include <rte_tailq.h>
11 #include <rte_common.h>
12 #include <rte_ethdev_driver.h>
13 #include <rte_eth_ctrl.h>
14 #include <rte_ether.h>
15 #include <rte_flow.h>
16 #include <rte_flow_driver.h>
17
18 #include "efx.h"
19
20 #include "sfc.h"
21 #include "sfc_rx.h"
22 #include "sfc_filter.h"
23 #include "sfc_flow.h"
24 #include "sfc_log.h"
25
26 /*
27  * At now flow API is implemented in such a manner that each
28  * flow rule is converted to a hardware filter.
29  * All elements of flow rule (attributes, pattern items, actions)
30  * correspond to one or more fields in the efx_filter_spec_s structure
31  * that is responsible for the hardware filter.
32  */
33
34 enum sfc_flow_item_layers {
35         SFC_FLOW_ITEM_ANY_LAYER,
36         SFC_FLOW_ITEM_START_LAYER,
37         SFC_FLOW_ITEM_L2,
38         SFC_FLOW_ITEM_L3,
39         SFC_FLOW_ITEM_L4,
40 };
41
42 typedef int (sfc_flow_item_parse)(const struct rte_flow_item *item,
43                                   efx_filter_spec_t *spec,
44                                   struct rte_flow_error *error);
45
46 struct sfc_flow_item {
47         enum rte_flow_item_type type;           /* Type of item */
48         enum sfc_flow_item_layers layer;        /* Layer of item */
49         enum sfc_flow_item_layers prev_layer;   /* Previous layer of item */
50         sfc_flow_item_parse *parse;             /* Parsing function */
51 };
52
53 static sfc_flow_item_parse sfc_flow_parse_void;
54 static sfc_flow_item_parse sfc_flow_parse_eth;
55 static sfc_flow_item_parse sfc_flow_parse_vlan;
56 static sfc_flow_item_parse sfc_flow_parse_ipv4;
57 static sfc_flow_item_parse sfc_flow_parse_ipv6;
58 static sfc_flow_item_parse sfc_flow_parse_tcp;
59 static sfc_flow_item_parse sfc_flow_parse_udp;
60 static sfc_flow_item_parse sfc_flow_parse_vxlan;
61
62 static boolean_t
63 sfc_flow_is_zero(const uint8_t *buf, unsigned int size)
64 {
65         uint8_t sum = 0;
66         unsigned int i;
67
68         for (i = 0; i < size; i++)
69                 sum |= buf[i];
70
71         return (sum == 0) ? B_TRUE : B_FALSE;
72 }
73
74 /*
75  * Validate item and prepare structures spec and mask for parsing
76  */
77 static int
78 sfc_flow_parse_init(const struct rte_flow_item *item,
79                     const void **spec_ptr,
80                     const void **mask_ptr,
81                     const void *supp_mask,
82                     const void *def_mask,
83                     unsigned int size,
84                     struct rte_flow_error *error)
85 {
86         const uint8_t *spec;
87         const uint8_t *mask;
88         const uint8_t *last;
89         uint8_t match;
90         uint8_t supp;
91         unsigned int i;
92
93         if (item == NULL) {
94                 rte_flow_error_set(error, EINVAL,
95                                    RTE_FLOW_ERROR_TYPE_ITEM, NULL,
96                                    "NULL item");
97                 return -rte_errno;
98         }
99
100         if ((item->last != NULL || item->mask != NULL) && item->spec == NULL) {
101                 rte_flow_error_set(error, EINVAL,
102                                    RTE_FLOW_ERROR_TYPE_ITEM, item,
103                                    "Mask or last is set without spec");
104                 return -rte_errno;
105         }
106
107         /*
108          * If "mask" is not set, default mask is used,
109          * but if default mask is NULL, "mask" should be set
110          */
111         if (item->mask == NULL) {
112                 if (def_mask == NULL) {
113                         rte_flow_error_set(error, EINVAL,
114                                 RTE_FLOW_ERROR_TYPE_ITEM, NULL,
115                                 "Mask should be specified");
116                         return -rte_errno;
117                 }
118
119                 mask = def_mask;
120         } else {
121                 mask = item->mask;
122         }
123
124         spec = item->spec;
125         last = item->last;
126
127         if (spec == NULL)
128                 goto exit;
129
130         /*
131          * If field values in "last" are either 0 or equal to the corresponding
132          * values in "spec" then they are ignored
133          */
134         if (last != NULL &&
135             !sfc_flow_is_zero(last, size) &&
136             memcmp(last, spec, size) != 0) {
137                 rte_flow_error_set(error, ENOTSUP,
138                                    RTE_FLOW_ERROR_TYPE_ITEM, item,
139                                    "Ranging is not supported");
140                 return -rte_errno;
141         }
142
143         if (supp_mask == NULL) {
144                 rte_flow_error_set(error, EINVAL,
145                         RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
146                         "Supported mask for item should be specified");
147                 return -rte_errno;
148         }
149
150         /* Check that mask and spec not asks for more match than supp_mask */
151         for (i = 0; i < size; i++) {
152                 match = spec[i] | mask[i];
153                 supp = ((const uint8_t *)supp_mask)[i];
154
155                 if ((match | supp) != supp) {
156                         rte_flow_error_set(error, ENOTSUP,
157                                            RTE_FLOW_ERROR_TYPE_ITEM, item,
158                                            "Item's field is not supported");
159                         return -rte_errno;
160                 }
161         }
162
163 exit:
164         *spec_ptr = spec;
165         *mask_ptr = mask;
166         return 0;
167 }
168
169 /*
170  * Protocol parsers.
171  * Masking is not supported, so masks in items should be either
172  * full or empty (zeroed) and set only for supported fields which
173  * are specified in the supp_mask.
174  */
175
176 static int
177 sfc_flow_parse_void(__rte_unused const struct rte_flow_item *item,
178                     __rte_unused efx_filter_spec_t *efx_spec,
179                     __rte_unused struct rte_flow_error *error)
180 {
181         return 0;
182 }
183
184 /**
185  * Convert Ethernet item to EFX filter specification.
186  *
187  * @param item[in]
188  *   Item specification. Only source and destination addresses and
189  *   Ethernet type fields are supported. In addition to full and
190  *   empty masks of destination address, individual/group mask is
191  *   also supported. If the mask is NULL, default mask will be used.
192  *   Ranging is not supported.
193  * @param efx_spec[in, out]
194  *   EFX filter specification to update.
195  * @param[out] error
196  *   Perform verbose error reporting if not NULL.
197  */
198 static int
199 sfc_flow_parse_eth(const struct rte_flow_item *item,
200                    efx_filter_spec_t *efx_spec,
201                    struct rte_flow_error *error)
202 {
203         int rc;
204         const struct rte_flow_item_eth *spec = NULL;
205         const struct rte_flow_item_eth *mask = NULL;
206         const struct rte_flow_item_eth supp_mask = {
207                 .dst.addr_bytes = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff },
208                 .src.addr_bytes = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff },
209                 .type = 0xffff,
210         };
211         const uint8_t ig_mask[EFX_MAC_ADDR_LEN] = {
212                 0x01, 0x00, 0x00, 0x00, 0x00, 0x00
213         };
214
215         rc = sfc_flow_parse_init(item,
216                                  (const void **)&spec,
217                                  (const void **)&mask,
218                                  &supp_mask,
219                                  &rte_flow_item_eth_mask,
220                                  sizeof(struct rte_flow_item_eth),
221                                  error);
222         if (rc != 0)
223                 return rc;
224
225         /* If "spec" is not set, could be any Ethernet */
226         if (spec == NULL)
227                 return 0;
228
229         if (is_same_ether_addr(&mask->dst, &supp_mask.dst)) {
230                 efx_spec->efs_match_flags |= EFX_FILTER_MATCH_LOC_MAC;
231                 rte_memcpy(efx_spec->efs_loc_mac, spec->dst.addr_bytes,
232                            EFX_MAC_ADDR_LEN);
233         } else if (memcmp(mask->dst.addr_bytes, ig_mask,
234                           EFX_MAC_ADDR_LEN) == 0) {
235                 if (is_unicast_ether_addr(&spec->dst))
236                         efx_spec->efs_match_flags |=
237                                 EFX_FILTER_MATCH_UNKNOWN_UCAST_DST;
238                 else
239                         efx_spec->efs_match_flags |=
240                                 EFX_FILTER_MATCH_UNKNOWN_MCAST_DST;
241         } else if (!is_zero_ether_addr(&mask->dst)) {
242                 goto fail_bad_mask;
243         }
244
245         if (is_same_ether_addr(&mask->src, &supp_mask.src)) {
246                 efx_spec->efs_match_flags |= EFX_FILTER_MATCH_REM_MAC;
247                 rte_memcpy(efx_spec->efs_rem_mac, spec->src.addr_bytes,
248                            EFX_MAC_ADDR_LEN);
249         } else if (!is_zero_ether_addr(&mask->src)) {
250                 goto fail_bad_mask;
251         }
252
253         /*
254          * Ether type is in big-endian byte order in item and
255          * in little-endian in efx_spec, so byte swap is used
256          */
257         if (mask->type == supp_mask.type) {
258                 efx_spec->efs_match_flags |= EFX_FILTER_MATCH_ETHER_TYPE;
259                 efx_spec->efs_ether_type = rte_bswap16(spec->type);
260         } else if (mask->type != 0) {
261                 goto fail_bad_mask;
262         }
263
264         return 0;
265
266 fail_bad_mask:
267         rte_flow_error_set(error, EINVAL,
268                            RTE_FLOW_ERROR_TYPE_ITEM, item,
269                            "Bad mask in the ETH pattern item");
270         return -rte_errno;
271 }
272
273 /**
274  * Convert VLAN item to EFX filter specification.
275  *
276  * @param item[in]
277  *   Item specification. Only VID field is supported.
278  *   The mask can not be NULL. Ranging is not supported.
279  * @param efx_spec[in, out]
280  *   EFX filter specification to update.
281  * @param[out] error
282  *   Perform verbose error reporting if not NULL.
283  */
284 static int
285 sfc_flow_parse_vlan(const struct rte_flow_item *item,
286                     efx_filter_spec_t *efx_spec,
287                     struct rte_flow_error *error)
288 {
289         int rc;
290         uint16_t vid;
291         const struct rte_flow_item_vlan *spec = NULL;
292         const struct rte_flow_item_vlan *mask = NULL;
293         const struct rte_flow_item_vlan supp_mask = {
294                 .tci = rte_cpu_to_be_16(ETH_VLAN_ID_MAX),
295         };
296
297         rc = sfc_flow_parse_init(item,
298                                  (const void **)&spec,
299                                  (const void **)&mask,
300                                  &supp_mask,
301                                  NULL,
302                                  sizeof(struct rte_flow_item_vlan),
303                                  error);
304         if (rc != 0)
305                 return rc;
306
307         /*
308          * VID is in big-endian byte order in item and
309          * in little-endian in efx_spec, so byte swap is used.
310          * If two VLAN items are included, the first matches
311          * the outer tag and the next matches the inner tag.
312          */
313         if (mask->tci == supp_mask.tci) {
314                 vid = rte_bswap16(spec->tci);
315
316                 if (!(efx_spec->efs_match_flags &
317                       EFX_FILTER_MATCH_OUTER_VID)) {
318                         efx_spec->efs_match_flags |= EFX_FILTER_MATCH_OUTER_VID;
319                         efx_spec->efs_outer_vid = vid;
320                 } else if (!(efx_spec->efs_match_flags &
321                              EFX_FILTER_MATCH_INNER_VID)) {
322                         efx_spec->efs_match_flags |= EFX_FILTER_MATCH_INNER_VID;
323                         efx_spec->efs_inner_vid = vid;
324                 } else {
325                         rte_flow_error_set(error, EINVAL,
326                                            RTE_FLOW_ERROR_TYPE_ITEM, item,
327                                            "More than two VLAN items");
328                         return -rte_errno;
329                 }
330         } else {
331                 rte_flow_error_set(error, EINVAL,
332                                    RTE_FLOW_ERROR_TYPE_ITEM, item,
333                                    "VLAN ID in TCI match is required");
334                 return -rte_errno;
335         }
336
337         return 0;
338 }
339
340 /**
341  * Convert IPv4 item to EFX filter specification.
342  *
343  * @param item[in]
344  *   Item specification. Only source and destination addresses and
345  *   protocol fields are supported. If the mask is NULL, default
346  *   mask will be used. Ranging is not supported.
347  * @param efx_spec[in, out]
348  *   EFX filter specification to update.
349  * @param[out] error
350  *   Perform verbose error reporting if not NULL.
351  */
352 static int
353 sfc_flow_parse_ipv4(const struct rte_flow_item *item,
354                     efx_filter_spec_t *efx_spec,
355                     struct rte_flow_error *error)
356 {
357         int rc;
358         const struct rte_flow_item_ipv4 *spec = NULL;
359         const struct rte_flow_item_ipv4 *mask = NULL;
360         const uint16_t ether_type_ipv4 = rte_cpu_to_le_16(EFX_ETHER_TYPE_IPV4);
361         const struct rte_flow_item_ipv4 supp_mask = {
362                 .hdr = {
363                         .src_addr = 0xffffffff,
364                         .dst_addr = 0xffffffff,
365                         .next_proto_id = 0xff,
366                 }
367         };
368
369         rc = sfc_flow_parse_init(item,
370                                  (const void **)&spec,
371                                  (const void **)&mask,
372                                  &supp_mask,
373                                  &rte_flow_item_ipv4_mask,
374                                  sizeof(struct rte_flow_item_ipv4),
375                                  error);
376         if (rc != 0)
377                 return rc;
378
379         /*
380          * Filtering by IPv4 source and destination addresses requires
381          * the appropriate ETHER_TYPE in hardware filters
382          */
383         if (!(efx_spec->efs_match_flags & EFX_FILTER_MATCH_ETHER_TYPE)) {
384                 efx_spec->efs_match_flags |= EFX_FILTER_MATCH_ETHER_TYPE;
385                 efx_spec->efs_ether_type = ether_type_ipv4;
386         } else if (efx_spec->efs_ether_type != ether_type_ipv4) {
387                 rte_flow_error_set(error, EINVAL,
388                         RTE_FLOW_ERROR_TYPE_ITEM, item,
389                         "Ethertype in pattern with IPV4 item should be appropriate");
390                 return -rte_errno;
391         }
392
393         if (spec == NULL)
394                 return 0;
395
396         /*
397          * IPv4 addresses are in big-endian byte order in item and in
398          * efx_spec
399          */
400         if (mask->hdr.src_addr == supp_mask.hdr.src_addr) {
401                 efx_spec->efs_match_flags |= EFX_FILTER_MATCH_REM_HOST;
402                 efx_spec->efs_rem_host.eo_u32[0] = spec->hdr.src_addr;
403         } else if (mask->hdr.src_addr != 0) {
404                 goto fail_bad_mask;
405         }
406
407         if (mask->hdr.dst_addr == supp_mask.hdr.dst_addr) {
408                 efx_spec->efs_match_flags |= EFX_FILTER_MATCH_LOC_HOST;
409                 efx_spec->efs_loc_host.eo_u32[0] = spec->hdr.dst_addr;
410         } else if (mask->hdr.dst_addr != 0) {
411                 goto fail_bad_mask;
412         }
413
414         if (mask->hdr.next_proto_id == supp_mask.hdr.next_proto_id) {
415                 efx_spec->efs_match_flags |= EFX_FILTER_MATCH_IP_PROTO;
416                 efx_spec->efs_ip_proto = spec->hdr.next_proto_id;
417         } else if (mask->hdr.next_proto_id != 0) {
418                 goto fail_bad_mask;
419         }
420
421         return 0;
422
423 fail_bad_mask:
424         rte_flow_error_set(error, EINVAL,
425                            RTE_FLOW_ERROR_TYPE_ITEM, item,
426                            "Bad mask in the IPV4 pattern item");
427         return -rte_errno;
428 }
429
430 /**
431  * Convert IPv6 item to EFX filter specification.
432  *
433  * @param item[in]
434  *   Item specification. Only source and destination addresses and
435  *   next header fields are supported. If the mask is NULL, default
436  *   mask will be used. Ranging is not supported.
437  * @param efx_spec[in, out]
438  *   EFX filter specification to update.
439  * @param[out] error
440  *   Perform verbose error reporting if not NULL.
441  */
442 static int
443 sfc_flow_parse_ipv6(const struct rte_flow_item *item,
444                     efx_filter_spec_t *efx_spec,
445                     struct rte_flow_error *error)
446 {
447         int rc;
448         const struct rte_flow_item_ipv6 *spec = NULL;
449         const struct rte_flow_item_ipv6 *mask = NULL;
450         const uint16_t ether_type_ipv6 = rte_cpu_to_le_16(EFX_ETHER_TYPE_IPV6);
451         const struct rte_flow_item_ipv6 supp_mask = {
452                 .hdr = {
453                         .src_addr = { 0xff, 0xff, 0xff, 0xff,
454                                       0xff, 0xff, 0xff, 0xff,
455                                       0xff, 0xff, 0xff, 0xff,
456                                       0xff, 0xff, 0xff, 0xff },
457                         .dst_addr = { 0xff, 0xff, 0xff, 0xff,
458                                       0xff, 0xff, 0xff, 0xff,
459                                       0xff, 0xff, 0xff, 0xff,
460                                       0xff, 0xff, 0xff, 0xff },
461                         .proto = 0xff,
462                 }
463         };
464
465         rc = sfc_flow_parse_init(item,
466                                  (const void **)&spec,
467                                  (const void **)&mask,
468                                  &supp_mask,
469                                  &rte_flow_item_ipv6_mask,
470                                  sizeof(struct rte_flow_item_ipv6),
471                                  error);
472         if (rc != 0)
473                 return rc;
474
475         /*
476          * Filtering by IPv6 source and destination addresses requires
477          * the appropriate ETHER_TYPE in hardware filters
478          */
479         if (!(efx_spec->efs_match_flags & EFX_FILTER_MATCH_ETHER_TYPE)) {
480                 efx_spec->efs_match_flags |= EFX_FILTER_MATCH_ETHER_TYPE;
481                 efx_spec->efs_ether_type = ether_type_ipv6;
482         } else if (efx_spec->efs_ether_type != ether_type_ipv6) {
483                 rte_flow_error_set(error, EINVAL,
484                         RTE_FLOW_ERROR_TYPE_ITEM, item,
485                         "Ethertype in pattern with IPV6 item should be appropriate");
486                 return -rte_errno;
487         }
488
489         if (spec == NULL)
490                 return 0;
491
492         /*
493          * IPv6 addresses are in big-endian byte order in item and in
494          * efx_spec
495          */
496         if (memcmp(mask->hdr.src_addr, supp_mask.hdr.src_addr,
497                    sizeof(mask->hdr.src_addr)) == 0) {
498                 efx_spec->efs_match_flags |= EFX_FILTER_MATCH_REM_HOST;
499
500                 RTE_BUILD_BUG_ON(sizeof(efx_spec->efs_rem_host) !=
501                                  sizeof(spec->hdr.src_addr));
502                 rte_memcpy(&efx_spec->efs_rem_host, spec->hdr.src_addr,
503                            sizeof(efx_spec->efs_rem_host));
504         } else if (!sfc_flow_is_zero(mask->hdr.src_addr,
505                                      sizeof(mask->hdr.src_addr))) {
506                 goto fail_bad_mask;
507         }
508
509         if (memcmp(mask->hdr.dst_addr, supp_mask.hdr.dst_addr,
510                    sizeof(mask->hdr.dst_addr)) == 0) {
511                 efx_spec->efs_match_flags |= EFX_FILTER_MATCH_LOC_HOST;
512
513                 RTE_BUILD_BUG_ON(sizeof(efx_spec->efs_loc_host) !=
514                                  sizeof(spec->hdr.dst_addr));
515                 rte_memcpy(&efx_spec->efs_loc_host, spec->hdr.dst_addr,
516                            sizeof(efx_spec->efs_loc_host));
517         } else if (!sfc_flow_is_zero(mask->hdr.dst_addr,
518                                      sizeof(mask->hdr.dst_addr))) {
519                 goto fail_bad_mask;
520         }
521
522         if (mask->hdr.proto == supp_mask.hdr.proto) {
523                 efx_spec->efs_match_flags |= EFX_FILTER_MATCH_IP_PROTO;
524                 efx_spec->efs_ip_proto = spec->hdr.proto;
525         } else if (mask->hdr.proto != 0) {
526                 goto fail_bad_mask;
527         }
528
529         return 0;
530
531 fail_bad_mask:
532         rte_flow_error_set(error, EINVAL,
533                            RTE_FLOW_ERROR_TYPE_ITEM, item,
534                            "Bad mask in the IPV6 pattern item");
535         return -rte_errno;
536 }
537
538 /**
539  * Convert TCP item to EFX filter specification.
540  *
541  * @param item[in]
542  *   Item specification. Only source and destination ports fields
543  *   are supported. If the mask is NULL, default mask will be used.
544  *   Ranging is not supported.
545  * @param efx_spec[in, out]
546  *   EFX filter specification to update.
547  * @param[out] error
548  *   Perform verbose error reporting if not NULL.
549  */
550 static int
551 sfc_flow_parse_tcp(const struct rte_flow_item *item,
552                    efx_filter_spec_t *efx_spec,
553                    struct rte_flow_error *error)
554 {
555         int rc;
556         const struct rte_flow_item_tcp *spec = NULL;
557         const struct rte_flow_item_tcp *mask = NULL;
558         const struct rte_flow_item_tcp supp_mask = {
559                 .hdr = {
560                         .src_port = 0xffff,
561                         .dst_port = 0xffff,
562                 }
563         };
564
565         rc = sfc_flow_parse_init(item,
566                                  (const void **)&spec,
567                                  (const void **)&mask,
568                                  &supp_mask,
569                                  &rte_flow_item_tcp_mask,
570                                  sizeof(struct rte_flow_item_tcp),
571                                  error);
572         if (rc != 0)
573                 return rc;
574
575         /*
576          * Filtering by TCP source and destination ports requires
577          * the appropriate IP_PROTO in hardware filters
578          */
579         if (!(efx_spec->efs_match_flags & EFX_FILTER_MATCH_IP_PROTO)) {
580                 efx_spec->efs_match_flags |= EFX_FILTER_MATCH_IP_PROTO;
581                 efx_spec->efs_ip_proto = EFX_IPPROTO_TCP;
582         } else if (efx_spec->efs_ip_proto != EFX_IPPROTO_TCP) {
583                 rte_flow_error_set(error, EINVAL,
584                         RTE_FLOW_ERROR_TYPE_ITEM, item,
585                         "IP proto in pattern with TCP item should be appropriate");
586                 return -rte_errno;
587         }
588
589         if (spec == NULL)
590                 return 0;
591
592         /*
593          * Source and destination ports are in big-endian byte order in item and
594          * in little-endian in efx_spec, so byte swap is used
595          */
596         if (mask->hdr.src_port == supp_mask.hdr.src_port) {
597                 efx_spec->efs_match_flags |= EFX_FILTER_MATCH_REM_PORT;
598                 efx_spec->efs_rem_port = rte_bswap16(spec->hdr.src_port);
599         } else if (mask->hdr.src_port != 0) {
600                 goto fail_bad_mask;
601         }
602
603         if (mask->hdr.dst_port == supp_mask.hdr.dst_port) {
604                 efx_spec->efs_match_flags |= EFX_FILTER_MATCH_LOC_PORT;
605                 efx_spec->efs_loc_port = rte_bswap16(spec->hdr.dst_port);
606         } else if (mask->hdr.dst_port != 0) {
607                 goto fail_bad_mask;
608         }
609
610         return 0;
611
612 fail_bad_mask:
613         rte_flow_error_set(error, EINVAL,
614                            RTE_FLOW_ERROR_TYPE_ITEM, item,
615                            "Bad mask in the TCP pattern item");
616         return -rte_errno;
617 }
618
619 /**
620  * Convert UDP item to EFX filter specification.
621  *
622  * @param item[in]
623  *   Item specification. Only source and destination ports fields
624  *   are supported. If the mask is NULL, default mask will be used.
625  *   Ranging is not supported.
626  * @param efx_spec[in, out]
627  *   EFX filter specification to update.
628  * @param[out] error
629  *   Perform verbose error reporting if not NULL.
630  */
631 static int
632 sfc_flow_parse_udp(const struct rte_flow_item *item,
633                    efx_filter_spec_t *efx_spec,
634                    struct rte_flow_error *error)
635 {
636         int rc;
637         const struct rte_flow_item_udp *spec = NULL;
638         const struct rte_flow_item_udp *mask = NULL;
639         const struct rte_flow_item_udp supp_mask = {
640                 .hdr = {
641                         .src_port = 0xffff,
642                         .dst_port = 0xffff,
643                 }
644         };
645
646         rc = sfc_flow_parse_init(item,
647                                  (const void **)&spec,
648                                  (const void **)&mask,
649                                  &supp_mask,
650                                  &rte_flow_item_udp_mask,
651                                  sizeof(struct rte_flow_item_udp),
652                                  error);
653         if (rc != 0)
654                 return rc;
655
656         /*
657          * Filtering by UDP source and destination ports requires
658          * the appropriate IP_PROTO in hardware filters
659          */
660         if (!(efx_spec->efs_match_flags & EFX_FILTER_MATCH_IP_PROTO)) {
661                 efx_spec->efs_match_flags |= EFX_FILTER_MATCH_IP_PROTO;
662                 efx_spec->efs_ip_proto = EFX_IPPROTO_UDP;
663         } else if (efx_spec->efs_ip_proto != EFX_IPPROTO_UDP) {
664                 rte_flow_error_set(error, EINVAL,
665                         RTE_FLOW_ERROR_TYPE_ITEM, item,
666                         "IP proto in pattern with UDP item should be appropriate");
667                 return -rte_errno;
668         }
669
670         if (spec == NULL)
671                 return 0;
672
673         /*
674          * Source and destination ports are in big-endian byte order in item and
675          * in little-endian in efx_spec, so byte swap is used
676          */
677         if (mask->hdr.src_port == supp_mask.hdr.src_port) {
678                 efx_spec->efs_match_flags |= EFX_FILTER_MATCH_REM_PORT;
679                 efx_spec->efs_rem_port = rte_bswap16(spec->hdr.src_port);
680         } else if (mask->hdr.src_port != 0) {
681                 goto fail_bad_mask;
682         }
683
684         if (mask->hdr.dst_port == supp_mask.hdr.dst_port) {
685                 efx_spec->efs_match_flags |= EFX_FILTER_MATCH_LOC_PORT;
686                 efx_spec->efs_loc_port = rte_bswap16(spec->hdr.dst_port);
687         } else if (mask->hdr.dst_port != 0) {
688                 goto fail_bad_mask;
689         }
690
691         return 0;
692
693 fail_bad_mask:
694         rte_flow_error_set(error, EINVAL,
695                            RTE_FLOW_ERROR_TYPE_ITEM, item,
696                            "Bad mask in the UDP pattern item");
697         return -rte_errno;
698 }
699
700 /*
701  * Filters for encapsulated packets match based on the EtherType and IP
702  * protocol in the outer frame.
703  */
704 static int
705 sfc_flow_set_match_flags_for_encap_pkts(const struct rte_flow_item *item,
706                                         efx_filter_spec_t *efx_spec,
707                                         uint8_t ip_proto,
708                                         struct rte_flow_error *error)
709 {
710         if (!(efx_spec->efs_match_flags & EFX_FILTER_MATCH_IP_PROTO)) {
711                 efx_spec->efs_match_flags |= EFX_FILTER_MATCH_IP_PROTO;
712                 efx_spec->efs_ip_proto = ip_proto;
713         } else if (efx_spec->efs_ip_proto != ip_proto) {
714                 switch (ip_proto) {
715                 case EFX_IPPROTO_UDP:
716                         rte_flow_error_set(error, EINVAL,
717                                 RTE_FLOW_ERROR_TYPE_ITEM, item,
718                                 "Outer IP header protocol must be UDP "
719                                 "in VxLAN pattern");
720                         return -rte_errno;
721
722                 default:
723                         rte_flow_error_set(error, EINVAL,
724                                 RTE_FLOW_ERROR_TYPE_ITEM, item,
725                                 "Only VxLAN tunneling patterns "
726                                 "are supported");
727                         return -rte_errno;
728                 }
729         }
730
731         if (!(efx_spec->efs_match_flags & EFX_FILTER_MATCH_ETHER_TYPE)) {
732                 rte_flow_error_set(error, EINVAL,
733                         RTE_FLOW_ERROR_TYPE_ITEM, item,
734                         "Outer frame EtherType in pattern with tunneling "
735                         "must be set");
736                 return -rte_errno;
737         } else if (efx_spec->efs_ether_type != EFX_ETHER_TYPE_IPV4 &&
738                    efx_spec->efs_ether_type != EFX_ETHER_TYPE_IPV6) {
739                 rte_flow_error_set(error, EINVAL,
740                         RTE_FLOW_ERROR_TYPE_ITEM, item,
741                         "Outer frame EtherType in pattern with tunneling "
742                         "must be IPv4 or IPv6");
743                 return -rte_errno;
744         }
745
746         return 0;
747 }
748
749 static int
750 sfc_flow_set_efx_spec_vni_or_vsid(efx_filter_spec_t *efx_spec,
751                                   const uint8_t *vni_or_vsid_val,
752                                   const uint8_t *vni_or_vsid_mask,
753                                   const struct rte_flow_item *item,
754                                   struct rte_flow_error *error)
755 {
756         const uint8_t vni_or_vsid_full_mask[EFX_VNI_OR_VSID_LEN] = {
757                 0xff, 0xff, 0xff
758         };
759
760         if (memcmp(vni_or_vsid_mask, vni_or_vsid_full_mask,
761                    EFX_VNI_OR_VSID_LEN) == 0) {
762                 efx_spec->efs_match_flags |= EFX_FILTER_MATCH_VNI_OR_VSID;
763                 rte_memcpy(efx_spec->efs_vni_or_vsid, vni_or_vsid_val,
764                            EFX_VNI_OR_VSID_LEN);
765         } else if (!sfc_flow_is_zero(vni_or_vsid_mask, EFX_VNI_OR_VSID_LEN)) {
766                 rte_flow_error_set(error, EINVAL,
767                                    RTE_FLOW_ERROR_TYPE_ITEM, item,
768                                    "Unsupported VNI/VSID mask");
769                 return -rte_errno;
770         }
771
772         return 0;
773 }
774
775 /**
776  * Convert VXLAN item to EFX filter specification.
777  *
778  * @param item[in]
779  *   Item specification. Only VXLAN network identifier field is supported.
780  *   If the mask is NULL, default mask will be used.
781  *   Ranging is not supported.
782  * @param efx_spec[in, out]
783  *   EFX filter specification to update.
784  * @param[out] error
785  *   Perform verbose error reporting if not NULL.
786  */
787 static int
788 sfc_flow_parse_vxlan(const struct rte_flow_item *item,
789                      efx_filter_spec_t *efx_spec,
790                      struct rte_flow_error *error)
791 {
792         int rc;
793         const struct rte_flow_item_vxlan *spec = NULL;
794         const struct rte_flow_item_vxlan *mask = NULL;
795         const struct rte_flow_item_vxlan supp_mask = {
796                 .vni = { 0xff, 0xff, 0xff }
797         };
798
799         rc = sfc_flow_parse_init(item,
800                                  (const void **)&spec,
801                                  (const void **)&mask,
802                                  &supp_mask,
803                                  &rte_flow_item_vxlan_mask,
804                                  sizeof(struct rte_flow_item_vxlan),
805                                  error);
806         if (rc != 0)
807                 return rc;
808
809         rc = sfc_flow_set_match_flags_for_encap_pkts(item, efx_spec,
810                                                      EFX_IPPROTO_UDP, error);
811         if (rc != 0)
812                 return rc;
813
814         efx_spec->efs_encap_type = EFX_TUNNEL_PROTOCOL_VXLAN;
815         efx_spec->efs_match_flags |= EFX_FILTER_MATCH_ENCAP_TYPE;
816
817         if (spec == NULL)
818                 return 0;
819
820         rc = sfc_flow_set_efx_spec_vni_or_vsid(efx_spec, spec->vni,
821                                                mask->vni, item, error);
822
823         return rc;
824 }
825
826 static const struct sfc_flow_item sfc_flow_items[] = {
827         {
828                 .type = RTE_FLOW_ITEM_TYPE_VOID,
829                 .prev_layer = SFC_FLOW_ITEM_ANY_LAYER,
830                 .layer = SFC_FLOW_ITEM_ANY_LAYER,
831                 .parse = sfc_flow_parse_void,
832         },
833         {
834                 .type = RTE_FLOW_ITEM_TYPE_ETH,
835                 .prev_layer = SFC_FLOW_ITEM_START_LAYER,
836                 .layer = SFC_FLOW_ITEM_L2,
837                 .parse = sfc_flow_parse_eth,
838         },
839         {
840                 .type = RTE_FLOW_ITEM_TYPE_VLAN,
841                 .prev_layer = SFC_FLOW_ITEM_L2,
842                 .layer = SFC_FLOW_ITEM_L2,
843                 .parse = sfc_flow_parse_vlan,
844         },
845         {
846                 .type = RTE_FLOW_ITEM_TYPE_IPV4,
847                 .prev_layer = SFC_FLOW_ITEM_L2,
848                 .layer = SFC_FLOW_ITEM_L3,
849                 .parse = sfc_flow_parse_ipv4,
850         },
851         {
852                 .type = RTE_FLOW_ITEM_TYPE_IPV6,
853                 .prev_layer = SFC_FLOW_ITEM_L2,
854                 .layer = SFC_FLOW_ITEM_L3,
855                 .parse = sfc_flow_parse_ipv6,
856         },
857         {
858                 .type = RTE_FLOW_ITEM_TYPE_TCP,
859                 .prev_layer = SFC_FLOW_ITEM_L3,
860                 .layer = SFC_FLOW_ITEM_L4,
861                 .parse = sfc_flow_parse_tcp,
862         },
863         {
864                 .type = RTE_FLOW_ITEM_TYPE_UDP,
865                 .prev_layer = SFC_FLOW_ITEM_L3,
866                 .layer = SFC_FLOW_ITEM_L4,
867                 .parse = sfc_flow_parse_udp,
868         },
869         {
870                 .type = RTE_FLOW_ITEM_TYPE_VXLAN,
871                 .prev_layer = SFC_FLOW_ITEM_L4,
872                 .layer = SFC_FLOW_ITEM_START_LAYER,
873                 .parse = sfc_flow_parse_vxlan,
874         },
875 };
876
877 /*
878  * Protocol-independent flow API support
879  */
880 static int
881 sfc_flow_parse_attr(const struct rte_flow_attr *attr,
882                     struct rte_flow *flow,
883                     struct rte_flow_error *error)
884 {
885         if (attr == NULL) {
886                 rte_flow_error_set(error, EINVAL,
887                                    RTE_FLOW_ERROR_TYPE_ATTR, NULL,
888                                    "NULL attribute");
889                 return -rte_errno;
890         }
891         if (attr->group != 0) {
892                 rte_flow_error_set(error, ENOTSUP,
893                                    RTE_FLOW_ERROR_TYPE_ATTR_GROUP, attr,
894                                    "Groups are not supported");
895                 return -rte_errno;
896         }
897         if (attr->priority != 0) {
898                 rte_flow_error_set(error, ENOTSUP,
899                                    RTE_FLOW_ERROR_TYPE_ATTR_PRIORITY, attr,
900                                    "Priorities are not supported");
901                 return -rte_errno;
902         }
903         if (attr->egress != 0) {
904                 rte_flow_error_set(error, ENOTSUP,
905                                    RTE_FLOW_ERROR_TYPE_ATTR_EGRESS, attr,
906                                    "Egress is not supported");
907                 return -rte_errno;
908         }
909         if (attr->ingress == 0) {
910                 rte_flow_error_set(error, ENOTSUP,
911                                    RTE_FLOW_ERROR_TYPE_ATTR_INGRESS, attr,
912                                    "Only ingress is supported");
913                 return -rte_errno;
914         }
915
916         flow->spec.efs_flags |= EFX_FILTER_FLAG_RX;
917         flow->spec.efs_rss_context = EFX_RSS_CONTEXT_DEFAULT;
918
919         return 0;
920 }
921
922 /* Get item from array sfc_flow_items */
923 static const struct sfc_flow_item *
924 sfc_flow_get_item(enum rte_flow_item_type type)
925 {
926         unsigned int i;
927
928         for (i = 0; i < RTE_DIM(sfc_flow_items); i++)
929                 if (sfc_flow_items[i].type == type)
930                         return &sfc_flow_items[i];
931
932         return NULL;
933 }
934
935 static int
936 sfc_flow_parse_pattern(const struct rte_flow_item pattern[],
937                        struct rte_flow *flow,
938                        struct rte_flow_error *error)
939 {
940         int rc;
941         unsigned int prev_layer = SFC_FLOW_ITEM_ANY_LAYER;
942         boolean_t is_ifrm = B_FALSE;
943         const struct sfc_flow_item *item;
944
945         if (pattern == NULL) {
946                 rte_flow_error_set(error, EINVAL,
947                                    RTE_FLOW_ERROR_TYPE_ITEM_NUM, NULL,
948                                    "NULL pattern");
949                 return -rte_errno;
950         }
951
952         for (; pattern->type != RTE_FLOW_ITEM_TYPE_END; pattern++) {
953                 item = sfc_flow_get_item(pattern->type);
954                 if (item == NULL) {
955                         rte_flow_error_set(error, ENOTSUP,
956                                            RTE_FLOW_ERROR_TYPE_ITEM, pattern,
957                                            "Unsupported pattern item");
958                         return -rte_errno;
959                 }
960
961                 /*
962                  * Omitting one or several protocol layers at the beginning
963                  * of pattern is supported
964                  */
965                 if (item->prev_layer != SFC_FLOW_ITEM_ANY_LAYER &&
966                     prev_layer != SFC_FLOW_ITEM_ANY_LAYER &&
967                     item->prev_layer != prev_layer) {
968                         rte_flow_error_set(error, ENOTSUP,
969                                            RTE_FLOW_ERROR_TYPE_ITEM, pattern,
970                                            "Unexpected sequence of pattern items");
971                         return -rte_errno;
972                 }
973
974                 /*
975                  * Allow only VOID pattern item in the inner frame.
976                  * Also check that there is only one tunneling protocol.
977                  */
978                 switch (item->type) {
979                 case RTE_FLOW_ITEM_TYPE_VOID:
980                         break;
981
982                 case RTE_FLOW_ITEM_TYPE_VXLAN:
983                         if (is_ifrm) {
984                                 rte_flow_error_set(error, EINVAL,
985                                         RTE_FLOW_ERROR_TYPE_ITEM,
986                                         pattern,
987                                         "More than one tunneling protocol");
988                                 return -rte_errno;
989                         }
990                         is_ifrm = B_TRUE;
991                         break;
992
993                 default:
994                         if (is_ifrm) {
995                                 rte_flow_error_set(error, EINVAL,
996                                         RTE_FLOW_ERROR_TYPE_ITEM,
997                                         pattern,
998                                         "There is an unsupported pattern item "
999                                         "in the inner frame");
1000                                 return -rte_errno;
1001                         }
1002                         break;
1003                 }
1004
1005                 rc = item->parse(pattern, &flow->spec, error);
1006                 if (rc != 0)
1007                         return rc;
1008
1009                 if (item->layer != SFC_FLOW_ITEM_ANY_LAYER)
1010                         prev_layer = item->layer;
1011         }
1012
1013         return 0;
1014 }
1015
1016 static int
1017 sfc_flow_parse_queue(struct sfc_adapter *sa,
1018                      const struct rte_flow_action_queue *queue,
1019                      struct rte_flow *flow)
1020 {
1021         struct sfc_rxq *rxq;
1022
1023         if (queue->index >= sa->rxq_count)
1024                 return -EINVAL;
1025
1026         rxq = sa->rxq_info[queue->index].rxq;
1027         flow->spec.efs_dmaq_id = (uint16_t)rxq->hw_index;
1028
1029         return 0;
1030 }
1031
1032 #if EFSYS_OPT_RX_SCALE
1033 static int
1034 sfc_flow_parse_rss(struct sfc_adapter *sa,
1035                    const struct rte_flow_action_rss *rss,
1036                    struct rte_flow *flow)
1037 {
1038         unsigned int rxq_sw_index;
1039         struct sfc_rxq *rxq;
1040         unsigned int rxq_hw_index_min;
1041         unsigned int rxq_hw_index_max;
1042         const struct rte_eth_rss_conf *rss_conf = rss->rss_conf;
1043         uint64_t rss_hf;
1044         uint8_t *rss_key = NULL;
1045         struct sfc_flow_rss *sfc_rss_conf = &flow->rss_conf;
1046         unsigned int i;
1047
1048         if (rss->num == 0)
1049                 return -EINVAL;
1050
1051         rxq_sw_index = sa->rxq_count - 1;
1052         rxq = sa->rxq_info[rxq_sw_index].rxq;
1053         rxq_hw_index_min = rxq->hw_index;
1054         rxq_hw_index_max = 0;
1055
1056         for (i = 0; i < rss->num; ++i) {
1057                 rxq_sw_index = rss->queue[i];
1058
1059                 if (rxq_sw_index >= sa->rxq_count)
1060                         return -EINVAL;
1061
1062                 rxq = sa->rxq_info[rxq_sw_index].rxq;
1063
1064                 if (rxq->hw_index < rxq_hw_index_min)
1065                         rxq_hw_index_min = rxq->hw_index;
1066
1067                 if (rxq->hw_index > rxq_hw_index_max)
1068                         rxq_hw_index_max = rxq->hw_index;
1069         }
1070
1071         rss_hf = (rss_conf != NULL) ? rss_conf->rss_hf : SFC_RSS_OFFLOADS;
1072         if ((rss_hf & ~SFC_RSS_OFFLOADS) != 0)
1073                 return -EINVAL;
1074
1075         if (rss_conf != NULL) {
1076                 if (rss_conf->rss_key_len != sizeof(sa->rss_key))
1077                         return -EINVAL;
1078
1079                 rss_key = rss_conf->rss_key;
1080         } else {
1081                 rss_key = sa->rss_key;
1082         }
1083
1084         flow->rss = B_TRUE;
1085
1086         sfc_rss_conf->rxq_hw_index_min = rxq_hw_index_min;
1087         sfc_rss_conf->rxq_hw_index_max = rxq_hw_index_max;
1088         sfc_rss_conf->rss_hash_types = sfc_rte_to_efx_hash_type(rss_hf);
1089         rte_memcpy(sfc_rss_conf->rss_key, rss_key, sizeof(sa->rss_key));
1090
1091         for (i = 0; i < RTE_DIM(sfc_rss_conf->rss_tbl); ++i) {
1092                 unsigned int rxq_sw_index = rss->queue[i % rss->num];
1093                 struct sfc_rxq *rxq = sa->rxq_info[rxq_sw_index].rxq;
1094
1095                 sfc_rss_conf->rss_tbl[i] = rxq->hw_index - rxq_hw_index_min;
1096         }
1097
1098         return 0;
1099 }
1100 #endif /* EFSYS_OPT_RX_SCALE */
1101
1102 static int
1103 sfc_flow_filter_insert(struct sfc_adapter *sa,
1104                        struct rte_flow *flow)
1105 {
1106         efx_filter_spec_t *spec = &flow->spec;
1107
1108 #if EFSYS_OPT_RX_SCALE
1109         struct sfc_flow_rss *rss = &flow->rss_conf;
1110         int rc = 0;
1111
1112         if (flow->rss) {
1113                 unsigned int rss_spread = MIN(rss->rxq_hw_index_max -
1114                                               rss->rxq_hw_index_min + 1,
1115                                               EFX_MAXRSS);
1116
1117                 rc = efx_rx_scale_context_alloc(sa->nic,
1118                                                 EFX_RX_SCALE_EXCLUSIVE,
1119                                                 rss_spread,
1120                                                 &spec->efs_rss_context);
1121                 if (rc != 0)
1122                         goto fail_scale_context_alloc;
1123
1124                 rc = efx_rx_scale_mode_set(sa->nic, spec->efs_rss_context,
1125                                            EFX_RX_HASHALG_TOEPLITZ,
1126                                            rss->rss_hash_types, B_TRUE);
1127                 if (rc != 0)
1128                         goto fail_scale_mode_set;
1129
1130                 rc = efx_rx_scale_key_set(sa->nic, spec->efs_rss_context,
1131                                           rss->rss_key,
1132                                           sizeof(sa->rss_key));
1133                 if (rc != 0)
1134                         goto fail_scale_key_set;
1135
1136                 spec->efs_dmaq_id = rss->rxq_hw_index_min;
1137                 spec->efs_flags |= EFX_FILTER_FLAG_RX_RSS;
1138         }
1139
1140         rc = efx_filter_insert(sa->nic, spec);
1141         if (rc != 0)
1142                 goto fail_filter_insert;
1143
1144         if (flow->rss) {
1145                 /*
1146                  * Scale table is set after filter insertion because
1147                  * the table entries are relative to the base RxQ ID
1148                  * and the latter is submitted to the HW by means of
1149                  * inserting a filter, so by the time of the request
1150                  * the HW knows all the information needed to verify
1151                  * the table entries, and the operation will succeed
1152                  */
1153                 rc = efx_rx_scale_tbl_set(sa->nic, spec->efs_rss_context,
1154                                           rss->rss_tbl, RTE_DIM(rss->rss_tbl));
1155                 if (rc != 0)
1156                         goto fail_scale_tbl_set;
1157         }
1158
1159         return 0;
1160
1161 fail_scale_tbl_set:
1162         efx_filter_remove(sa->nic, spec);
1163
1164 fail_filter_insert:
1165 fail_scale_key_set:
1166 fail_scale_mode_set:
1167         if (flow->rss)
1168                 efx_rx_scale_context_free(sa->nic, spec->efs_rss_context);
1169
1170 fail_scale_context_alloc:
1171         return rc;
1172 #else /* !EFSYS_OPT_RX_SCALE */
1173         return efx_filter_insert(sa->nic, spec);
1174 #endif /* EFSYS_OPT_RX_SCALE */
1175 }
1176
1177 static int
1178 sfc_flow_filter_remove(struct sfc_adapter *sa,
1179                        struct rte_flow *flow)
1180 {
1181         efx_filter_spec_t *spec = &flow->spec;
1182         int rc = 0;
1183
1184         rc = efx_filter_remove(sa->nic, spec);
1185         if (rc != 0)
1186                 return rc;
1187
1188 #if EFSYS_OPT_RX_SCALE
1189         if (flow->rss)
1190                 rc = efx_rx_scale_context_free(sa->nic, spec->efs_rss_context);
1191 #endif /* EFSYS_OPT_RX_SCALE */
1192
1193         return rc;
1194 }
1195
1196 static int
1197 sfc_flow_parse_actions(struct sfc_adapter *sa,
1198                        const struct rte_flow_action actions[],
1199                        struct rte_flow *flow,
1200                        struct rte_flow_error *error)
1201 {
1202         int rc;
1203         boolean_t is_specified = B_FALSE;
1204
1205         if (actions == NULL) {
1206                 rte_flow_error_set(error, EINVAL,
1207                                    RTE_FLOW_ERROR_TYPE_ACTION_NUM, NULL,
1208                                    "NULL actions");
1209                 return -rte_errno;
1210         }
1211
1212         for (; actions->type != RTE_FLOW_ACTION_TYPE_END; actions++) {
1213                 switch (actions->type) {
1214                 case RTE_FLOW_ACTION_TYPE_VOID:
1215                         break;
1216
1217                 case RTE_FLOW_ACTION_TYPE_QUEUE:
1218                         rc = sfc_flow_parse_queue(sa, actions->conf, flow);
1219                         if (rc != 0) {
1220                                 rte_flow_error_set(error, EINVAL,
1221                                         RTE_FLOW_ERROR_TYPE_ACTION, actions,
1222                                         "Bad QUEUE action");
1223                                 return -rte_errno;
1224                         }
1225
1226                         is_specified = B_TRUE;
1227                         break;
1228
1229 #if EFSYS_OPT_RX_SCALE
1230                 case RTE_FLOW_ACTION_TYPE_RSS:
1231                         rc = sfc_flow_parse_rss(sa, actions->conf, flow);
1232                         if (rc != 0) {
1233                                 rte_flow_error_set(error, rc,
1234                                         RTE_FLOW_ERROR_TYPE_ACTION, actions,
1235                                         "Bad RSS action");
1236                                 return -rte_errno;
1237                         }
1238
1239                         is_specified = B_TRUE;
1240                         break;
1241 #endif /* EFSYS_OPT_RX_SCALE */
1242
1243                 default:
1244                         rte_flow_error_set(error, ENOTSUP,
1245                                            RTE_FLOW_ERROR_TYPE_ACTION, actions,
1246                                            "Action is not supported");
1247                         return -rte_errno;
1248                 }
1249         }
1250
1251         if (!is_specified) {
1252                 rte_flow_error_set(error, EINVAL,
1253                                    RTE_FLOW_ERROR_TYPE_ACTION_NUM, actions,
1254                                    "Action is unspecified");
1255                 return -rte_errno;
1256         }
1257
1258         return 0;
1259 }
1260
1261 static int
1262 sfc_flow_parse(struct rte_eth_dev *dev,
1263                const struct rte_flow_attr *attr,
1264                const struct rte_flow_item pattern[],
1265                const struct rte_flow_action actions[],
1266                struct rte_flow *flow,
1267                struct rte_flow_error *error)
1268 {
1269         struct sfc_adapter *sa = dev->data->dev_private;
1270         int rc;
1271
1272         rc = sfc_flow_parse_attr(attr, flow, error);
1273         if (rc != 0)
1274                 goto fail_bad_value;
1275
1276         rc = sfc_flow_parse_pattern(pattern, flow, error);
1277         if (rc != 0)
1278                 goto fail_bad_value;
1279
1280         rc = sfc_flow_parse_actions(sa, actions, flow, error);
1281         if (rc != 0)
1282                 goto fail_bad_value;
1283
1284         if (!sfc_filter_is_match_supported(sa, flow->spec.efs_match_flags)) {
1285                 rte_flow_error_set(error, ENOTSUP,
1286                                    RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
1287                                    "Flow rule pattern is not supported");
1288                 return -rte_errno;
1289         }
1290
1291 fail_bad_value:
1292         return rc;
1293 }
1294
1295 static int
1296 sfc_flow_validate(struct rte_eth_dev *dev,
1297                   const struct rte_flow_attr *attr,
1298                   const struct rte_flow_item pattern[],
1299                   const struct rte_flow_action actions[],
1300                   struct rte_flow_error *error)
1301 {
1302         struct rte_flow flow;
1303
1304         memset(&flow, 0, sizeof(flow));
1305
1306         return sfc_flow_parse(dev, attr, pattern, actions, &flow, error);
1307 }
1308
1309 static struct rte_flow *
1310 sfc_flow_create(struct rte_eth_dev *dev,
1311                 const struct rte_flow_attr *attr,
1312                 const struct rte_flow_item pattern[],
1313                 const struct rte_flow_action actions[],
1314                 struct rte_flow_error *error)
1315 {
1316         struct sfc_adapter *sa = dev->data->dev_private;
1317         struct rte_flow *flow = NULL;
1318         int rc;
1319
1320         flow = rte_zmalloc("sfc_rte_flow", sizeof(*flow), 0);
1321         if (flow == NULL) {
1322                 rte_flow_error_set(error, ENOMEM,
1323                                    RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
1324                                    "Failed to allocate memory");
1325                 goto fail_no_mem;
1326         }
1327
1328         rc = sfc_flow_parse(dev, attr, pattern, actions, flow, error);
1329         if (rc != 0)
1330                 goto fail_bad_value;
1331
1332         TAILQ_INSERT_TAIL(&sa->filter.flow_list, flow, entries);
1333
1334         sfc_adapter_lock(sa);
1335
1336         if (sa->state == SFC_ADAPTER_STARTED) {
1337                 rc = sfc_flow_filter_insert(sa, flow);
1338                 if (rc != 0) {
1339                         rte_flow_error_set(error, rc,
1340                                 RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
1341                                 "Failed to insert filter");
1342                         goto fail_filter_insert;
1343                 }
1344         }
1345
1346         sfc_adapter_unlock(sa);
1347
1348         return flow;
1349
1350 fail_filter_insert:
1351         TAILQ_REMOVE(&sa->filter.flow_list, flow, entries);
1352
1353 fail_bad_value:
1354         rte_free(flow);
1355         sfc_adapter_unlock(sa);
1356
1357 fail_no_mem:
1358         return NULL;
1359 }
1360
1361 static int
1362 sfc_flow_remove(struct sfc_adapter *sa,
1363                 struct rte_flow *flow,
1364                 struct rte_flow_error *error)
1365 {
1366         int rc = 0;
1367
1368         SFC_ASSERT(sfc_adapter_is_locked(sa));
1369
1370         if (sa->state == SFC_ADAPTER_STARTED) {
1371                 rc = sfc_flow_filter_remove(sa, flow);
1372                 if (rc != 0)
1373                         rte_flow_error_set(error, rc,
1374                                 RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
1375                                 "Failed to destroy flow rule");
1376         }
1377
1378         TAILQ_REMOVE(&sa->filter.flow_list, flow, entries);
1379         rte_free(flow);
1380
1381         return rc;
1382 }
1383
1384 static int
1385 sfc_flow_destroy(struct rte_eth_dev *dev,
1386                  struct rte_flow *flow,
1387                  struct rte_flow_error *error)
1388 {
1389         struct sfc_adapter *sa = dev->data->dev_private;
1390         struct rte_flow *flow_ptr;
1391         int rc = EINVAL;
1392
1393         sfc_adapter_lock(sa);
1394
1395         TAILQ_FOREACH(flow_ptr, &sa->filter.flow_list, entries) {
1396                 if (flow_ptr == flow)
1397                         rc = 0;
1398         }
1399         if (rc != 0) {
1400                 rte_flow_error_set(error, rc,
1401                                    RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
1402                                    "Failed to find flow rule to destroy");
1403                 goto fail_bad_value;
1404         }
1405
1406         rc = sfc_flow_remove(sa, flow, error);
1407
1408 fail_bad_value:
1409         sfc_adapter_unlock(sa);
1410
1411         return -rc;
1412 }
1413
1414 static int
1415 sfc_flow_flush(struct rte_eth_dev *dev,
1416                struct rte_flow_error *error)
1417 {
1418         struct sfc_adapter *sa = dev->data->dev_private;
1419         struct rte_flow *flow;
1420         int rc = 0;
1421         int ret = 0;
1422
1423         sfc_adapter_lock(sa);
1424
1425         while ((flow = TAILQ_FIRST(&sa->filter.flow_list)) != NULL) {
1426                 rc = sfc_flow_remove(sa, flow, error);
1427                 if (rc != 0)
1428                         ret = rc;
1429         }
1430
1431         sfc_adapter_unlock(sa);
1432
1433         return -ret;
1434 }
1435
1436 static int
1437 sfc_flow_isolate(struct rte_eth_dev *dev, int enable,
1438                  struct rte_flow_error *error)
1439 {
1440         struct sfc_adapter *sa = dev->data->dev_private;
1441         struct sfc_port *port = &sa->port;
1442         int ret = 0;
1443
1444         sfc_adapter_lock(sa);
1445         if (sa->state != SFC_ADAPTER_INITIALIZED) {
1446                 rte_flow_error_set(error, EBUSY,
1447                                    RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
1448                                    NULL, "please close the port first");
1449                 ret = -rte_errno;
1450         } else {
1451                 port->isolated = (enable) ? B_TRUE : B_FALSE;
1452         }
1453         sfc_adapter_unlock(sa);
1454
1455         return ret;
1456 }
1457
1458 const struct rte_flow_ops sfc_flow_ops = {
1459         .validate = sfc_flow_validate,
1460         .create = sfc_flow_create,
1461         .destroy = sfc_flow_destroy,
1462         .flush = sfc_flow_flush,
1463         .query = NULL,
1464         .isolate = sfc_flow_isolate,
1465 };
1466
1467 void
1468 sfc_flow_init(struct sfc_adapter *sa)
1469 {
1470         SFC_ASSERT(sfc_adapter_is_locked(sa));
1471
1472         TAILQ_INIT(&sa->filter.flow_list);
1473 }
1474
1475 void
1476 sfc_flow_fini(struct sfc_adapter *sa)
1477 {
1478         struct rte_flow *flow;
1479
1480         SFC_ASSERT(sfc_adapter_is_locked(sa));
1481
1482         while ((flow = TAILQ_FIRST(&sa->filter.flow_list)) != NULL) {
1483                 TAILQ_REMOVE(&sa->filter.flow_list, flow, entries);
1484                 rte_free(flow);
1485         }
1486 }
1487
1488 void
1489 sfc_flow_stop(struct sfc_adapter *sa)
1490 {
1491         struct rte_flow *flow;
1492
1493         SFC_ASSERT(sfc_adapter_is_locked(sa));
1494
1495         TAILQ_FOREACH(flow, &sa->filter.flow_list, entries)
1496                 sfc_flow_filter_remove(sa, flow);
1497 }
1498
1499 int
1500 sfc_flow_start(struct sfc_adapter *sa)
1501 {
1502         struct rte_flow *flow;
1503         int rc = 0;
1504
1505         sfc_log_init(sa, "entry");
1506
1507         SFC_ASSERT(sfc_adapter_is_locked(sa));
1508
1509         TAILQ_FOREACH(flow, &sa->filter.flow_list, entries) {
1510                 rc = sfc_flow_filter_insert(sa, flow);
1511                 if (rc != 0)
1512                         goto fail_bad_flow;
1513         }
1514
1515         sfc_log_init(sa, "done");
1516
1517 fail_bad_flow:
1518         return rc;
1519 }