net/vmxnet3: support RETA query and update
[dpdk.git] / lib / ethdev / rte_flow.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright 2016 6WIND S.A.
3  * Copyright 2016 Mellanox Technologies, Ltd
4  */
5
6 #include <errno.h>
7 #include <stddef.h>
8 #include <stdint.h>
9 #include <string.h>
10
11 #include <rte_common.h>
12 #include <rte_errno.h>
13 #include <rte_branch_prediction.h>
14 #include <rte_string_fns.h>
15 #include <rte_mbuf.h>
16 #include <rte_mbuf_dyn.h>
17 #include "rte_ethdev.h"
18 #include "rte_flow_driver.h"
19 #include "rte_flow.h"
20
21 /* Mbuf dynamic field name for metadata. */
22 int32_t rte_flow_dynf_metadata_offs = -1;
23
24 /* Mbuf dynamic field flag bit number for metadata. */
25 uint64_t rte_flow_dynf_metadata_mask;
26
27 /**
28  * Flow elements description tables.
29  */
30 struct rte_flow_desc_data {
31         const char *name;
32         size_t size;
33         size_t (*desc_fn)(void *dst, const void *src);
34 };
35
36 /**
37  *
38  * @param buf
39  * Destination memory.
40  * @param data
41  * Source memory
42  * @param size
43  * Requested copy size
44  * @param desc
45  * rte_flow_desc_item - for flow item conversion.
46  * rte_flow_desc_action - for flow action conversion.
47  * @param type
48  * Offset into the desc param or negative value for private flow elements.
49  */
50 static inline size_t
51 rte_flow_conv_copy(void *buf, const void *data, const size_t size,
52                    const struct rte_flow_desc_data *desc, int type)
53 {
54         /**
55          * Allow PMD private flow item
56          */
57         bool rte_type = type >= 0;
58
59         size_t sz = rte_type ? desc[type].size : sizeof(void *);
60         if (buf == NULL || data == NULL)
61                 return 0;
62         rte_memcpy(buf, data, (size > sz ? sz : size));
63         if (rte_type && desc[type].desc_fn)
64                 sz += desc[type].desc_fn(size > 0 ? buf : NULL, data);
65         return sz;
66 }
67
68 static size_t
69 rte_flow_item_flex_conv(void *buf, const void *data)
70 {
71         struct rte_flow_item_flex *dst = buf;
72         const struct rte_flow_item_flex *src = data;
73         if (buf) {
74                 dst->pattern = rte_memcpy
75                         ((void *)((uintptr_t)(dst + 1)), src->pattern,
76                          src->length);
77         }
78         return src->length;
79 }
80
81 /** Generate flow_item[] entry. */
82 #define MK_FLOW_ITEM(t, s) \
83         [RTE_FLOW_ITEM_TYPE_ ## t] = { \
84                 .name = # t, \
85                 .size = s,               \
86                 .desc_fn = NULL,\
87         }
88
89 #define MK_FLOW_ITEM_FN(t, s, fn) \
90         [RTE_FLOW_ITEM_TYPE_ ## t] = {\
91                 .name = # t,                 \
92                 .size = s,                   \
93                 .desc_fn = fn,               \
94         }
95
96 /** Information about known flow pattern items. */
97 static const struct rte_flow_desc_data rte_flow_desc_item[] = {
98         MK_FLOW_ITEM(END, 0),
99         MK_FLOW_ITEM(VOID, 0),
100         MK_FLOW_ITEM(INVERT, 0),
101         MK_FLOW_ITEM(ANY, sizeof(struct rte_flow_item_any)),
102         MK_FLOW_ITEM(PF, 0),
103         MK_FLOW_ITEM(VF, sizeof(struct rte_flow_item_vf)),
104         MK_FLOW_ITEM(PHY_PORT, sizeof(struct rte_flow_item_phy_port)),
105         MK_FLOW_ITEM(PORT_ID, sizeof(struct rte_flow_item_port_id)),
106         MK_FLOW_ITEM(RAW, sizeof(struct rte_flow_item_raw)),
107         MK_FLOW_ITEM(ETH, sizeof(struct rte_flow_item_eth)),
108         MK_FLOW_ITEM(VLAN, sizeof(struct rte_flow_item_vlan)),
109         MK_FLOW_ITEM(IPV4, sizeof(struct rte_flow_item_ipv4)),
110         MK_FLOW_ITEM(IPV6, sizeof(struct rte_flow_item_ipv6)),
111         MK_FLOW_ITEM(ICMP, sizeof(struct rte_flow_item_icmp)),
112         MK_FLOW_ITEM(UDP, sizeof(struct rte_flow_item_udp)),
113         MK_FLOW_ITEM(TCP, sizeof(struct rte_flow_item_tcp)),
114         MK_FLOW_ITEM(SCTP, sizeof(struct rte_flow_item_sctp)),
115         MK_FLOW_ITEM(VXLAN, sizeof(struct rte_flow_item_vxlan)),
116         MK_FLOW_ITEM(E_TAG, sizeof(struct rte_flow_item_e_tag)),
117         MK_FLOW_ITEM(NVGRE, sizeof(struct rte_flow_item_nvgre)),
118         MK_FLOW_ITEM(MPLS, sizeof(struct rte_flow_item_mpls)),
119         MK_FLOW_ITEM(GRE, sizeof(struct rte_flow_item_gre)),
120         MK_FLOW_ITEM(FUZZY, sizeof(struct rte_flow_item_fuzzy)),
121         MK_FLOW_ITEM(GTP, sizeof(struct rte_flow_item_gtp)),
122         MK_FLOW_ITEM(GTPC, sizeof(struct rte_flow_item_gtp)),
123         MK_FLOW_ITEM(GTPU, sizeof(struct rte_flow_item_gtp)),
124         MK_FLOW_ITEM(ESP, sizeof(struct rte_flow_item_esp)),
125         MK_FLOW_ITEM(GENEVE, sizeof(struct rte_flow_item_geneve)),
126         MK_FLOW_ITEM(VXLAN_GPE, sizeof(struct rte_flow_item_vxlan_gpe)),
127         MK_FLOW_ITEM(ARP_ETH_IPV4, sizeof(struct rte_flow_item_arp_eth_ipv4)),
128         MK_FLOW_ITEM(IPV6_EXT, sizeof(struct rte_flow_item_ipv6_ext)),
129         MK_FLOW_ITEM(IPV6_FRAG_EXT, sizeof(struct rte_flow_item_ipv6_frag_ext)),
130         MK_FLOW_ITEM(ICMP6, sizeof(struct rte_flow_item_icmp6)),
131         MK_FLOW_ITEM(ICMP6_ND_NS, sizeof(struct rte_flow_item_icmp6_nd_ns)),
132         MK_FLOW_ITEM(ICMP6_ND_NA, sizeof(struct rte_flow_item_icmp6_nd_na)),
133         MK_FLOW_ITEM(ICMP6_ND_OPT, sizeof(struct rte_flow_item_icmp6_nd_opt)),
134         MK_FLOW_ITEM(ICMP6_ND_OPT_SLA_ETH,
135                      sizeof(struct rte_flow_item_icmp6_nd_opt_sla_eth)),
136         MK_FLOW_ITEM(ICMP6_ND_OPT_TLA_ETH,
137                      sizeof(struct rte_flow_item_icmp6_nd_opt_tla_eth)),
138         MK_FLOW_ITEM(MARK, sizeof(struct rte_flow_item_mark)),
139         MK_FLOW_ITEM(META, sizeof(struct rte_flow_item_meta)),
140         MK_FLOW_ITEM(TAG, sizeof(struct rte_flow_item_tag)),
141         MK_FLOW_ITEM(GRE_KEY, sizeof(rte_be32_t)),
142         MK_FLOW_ITEM(GRE_OPTION, sizeof(struct rte_flow_item_gre_opt)),
143         MK_FLOW_ITEM(GTP_PSC, sizeof(struct rte_flow_item_gtp_psc)),
144         MK_FLOW_ITEM(PPPOES, sizeof(struct rte_flow_item_pppoe)),
145         MK_FLOW_ITEM(PPPOED, sizeof(struct rte_flow_item_pppoe)),
146         MK_FLOW_ITEM(PPPOE_PROTO_ID,
147                         sizeof(struct rte_flow_item_pppoe_proto_id)),
148         MK_FLOW_ITEM(NSH, sizeof(struct rte_flow_item_nsh)),
149         MK_FLOW_ITEM(IGMP, sizeof(struct rte_flow_item_igmp)),
150         MK_FLOW_ITEM(AH, sizeof(struct rte_flow_item_ah)),
151         MK_FLOW_ITEM(HIGIG2, sizeof(struct rte_flow_item_higig2_hdr)),
152         MK_FLOW_ITEM(L2TPV3OIP, sizeof(struct rte_flow_item_l2tpv3oip)),
153         MK_FLOW_ITEM(PFCP, sizeof(struct rte_flow_item_pfcp)),
154         MK_FLOW_ITEM(ECPRI, sizeof(struct rte_flow_item_ecpri)),
155         MK_FLOW_ITEM(GENEVE_OPT, sizeof(struct rte_flow_item_geneve_opt)),
156         MK_FLOW_ITEM(INTEGRITY, sizeof(struct rte_flow_item_integrity)),
157         MK_FLOW_ITEM(CONNTRACK, sizeof(uint32_t)),
158         MK_FLOW_ITEM(PORT_REPRESENTOR, sizeof(struct rte_flow_item_ethdev)),
159         MK_FLOW_ITEM(REPRESENTED_PORT, sizeof(struct rte_flow_item_ethdev)),
160         MK_FLOW_ITEM_FN(FLEX, sizeof(struct rte_flow_item_flex),
161                         rte_flow_item_flex_conv),
162         MK_FLOW_ITEM(L2TPV2, sizeof(struct rte_flow_item_l2tpv2)),
163         MK_FLOW_ITEM(PPP, sizeof(struct rte_flow_item_ppp)),
164 };
165
166 /** Generate flow_action[] entry. */
167 #define MK_FLOW_ACTION(t, s) \
168         [RTE_FLOW_ACTION_TYPE_ ## t] = { \
169                 .name = # t, \
170                 .size = s, \
171                 .desc_fn = NULL,\
172         }
173
174 #define MK_FLOW_ACTION_FN(t, fn) \
175         [RTE_FLOW_ACTION_TYPE_ ## t] = { \
176                 .name = # t, \
177                 .size = 0, \
178                 .desc_fn = fn,\
179         }
180
181
182 /** Information about known flow actions. */
183 static const struct rte_flow_desc_data rte_flow_desc_action[] = {
184         MK_FLOW_ACTION(END, 0),
185         MK_FLOW_ACTION(VOID, 0),
186         MK_FLOW_ACTION(PASSTHRU, 0),
187         MK_FLOW_ACTION(JUMP, sizeof(struct rte_flow_action_jump)),
188         MK_FLOW_ACTION(MARK, sizeof(struct rte_flow_action_mark)),
189         MK_FLOW_ACTION(FLAG, 0),
190         MK_FLOW_ACTION(QUEUE, sizeof(struct rte_flow_action_queue)),
191         MK_FLOW_ACTION(DROP, 0),
192         MK_FLOW_ACTION(COUNT, sizeof(struct rte_flow_action_count)),
193         MK_FLOW_ACTION(RSS, sizeof(struct rte_flow_action_rss)),
194         MK_FLOW_ACTION(PF, 0),
195         MK_FLOW_ACTION(VF, sizeof(struct rte_flow_action_vf)),
196         MK_FLOW_ACTION(PHY_PORT, sizeof(struct rte_flow_action_phy_port)),
197         MK_FLOW_ACTION(PORT_ID, sizeof(struct rte_flow_action_port_id)),
198         MK_FLOW_ACTION(METER, sizeof(struct rte_flow_action_meter)),
199         MK_FLOW_ACTION(SECURITY, sizeof(struct rte_flow_action_security)),
200         MK_FLOW_ACTION(OF_SET_MPLS_TTL,
201                        sizeof(struct rte_flow_action_of_set_mpls_ttl)),
202         MK_FLOW_ACTION(OF_DEC_MPLS_TTL, 0),
203         MK_FLOW_ACTION(OF_SET_NW_TTL,
204                        sizeof(struct rte_flow_action_of_set_nw_ttl)),
205         MK_FLOW_ACTION(OF_DEC_NW_TTL, 0),
206         MK_FLOW_ACTION(OF_COPY_TTL_OUT, 0),
207         MK_FLOW_ACTION(OF_COPY_TTL_IN, 0),
208         MK_FLOW_ACTION(OF_POP_VLAN, 0),
209         MK_FLOW_ACTION(OF_PUSH_VLAN,
210                        sizeof(struct rte_flow_action_of_push_vlan)),
211         MK_FLOW_ACTION(OF_SET_VLAN_VID,
212                        sizeof(struct rte_flow_action_of_set_vlan_vid)),
213         MK_FLOW_ACTION(OF_SET_VLAN_PCP,
214                        sizeof(struct rte_flow_action_of_set_vlan_pcp)),
215         MK_FLOW_ACTION(OF_POP_MPLS,
216                        sizeof(struct rte_flow_action_of_pop_mpls)),
217         MK_FLOW_ACTION(OF_PUSH_MPLS,
218                        sizeof(struct rte_flow_action_of_push_mpls)),
219         MK_FLOW_ACTION(VXLAN_ENCAP, sizeof(struct rte_flow_action_vxlan_encap)),
220         MK_FLOW_ACTION(VXLAN_DECAP, 0),
221         MK_FLOW_ACTION(NVGRE_ENCAP, sizeof(struct rte_flow_action_vxlan_encap)),
222         MK_FLOW_ACTION(NVGRE_DECAP, 0),
223         MK_FLOW_ACTION(RAW_ENCAP, sizeof(struct rte_flow_action_raw_encap)),
224         MK_FLOW_ACTION(RAW_DECAP, sizeof(struct rte_flow_action_raw_decap)),
225         MK_FLOW_ACTION(SET_IPV4_SRC,
226                        sizeof(struct rte_flow_action_set_ipv4)),
227         MK_FLOW_ACTION(SET_IPV4_DST,
228                        sizeof(struct rte_flow_action_set_ipv4)),
229         MK_FLOW_ACTION(SET_IPV6_SRC,
230                        sizeof(struct rte_flow_action_set_ipv6)),
231         MK_FLOW_ACTION(SET_IPV6_DST,
232                        sizeof(struct rte_flow_action_set_ipv6)),
233         MK_FLOW_ACTION(SET_TP_SRC,
234                        sizeof(struct rte_flow_action_set_tp)),
235         MK_FLOW_ACTION(SET_TP_DST,
236                        sizeof(struct rte_flow_action_set_tp)),
237         MK_FLOW_ACTION(MAC_SWAP, 0),
238         MK_FLOW_ACTION(DEC_TTL, 0),
239         MK_FLOW_ACTION(SET_TTL, sizeof(struct rte_flow_action_set_ttl)),
240         MK_FLOW_ACTION(SET_MAC_SRC, sizeof(struct rte_flow_action_set_mac)),
241         MK_FLOW_ACTION(SET_MAC_DST, sizeof(struct rte_flow_action_set_mac)),
242         MK_FLOW_ACTION(INC_TCP_SEQ, sizeof(rte_be32_t)),
243         MK_FLOW_ACTION(DEC_TCP_SEQ, sizeof(rte_be32_t)),
244         MK_FLOW_ACTION(INC_TCP_ACK, sizeof(rte_be32_t)),
245         MK_FLOW_ACTION(DEC_TCP_ACK, sizeof(rte_be32_t)),
246         MK_FLOW_ACTION(SET_TAG, sizeof(struct rte_flow_action_set_tag)),
247         MK_FLOW_ACTION(SET_META, sizeof(struct rte_flow_action_set_meta)),
248         MK_FLOW_ACTION(SET_IPV4_DSCP, sizeof(struct rte_flow_action_set_dscp)),
249         MK_FLOW_ACTION(SET_IPV6_DSCP, sizeof(struct rte_flow_action_set_dscp)),
250         MK_FLOW_ACTION(AGE, sizeof(struct rte_flow_action_age)),
251         MK_FLOW_ACTION(SAMPLE, sizeof(struct rte_flow_action_sample)),
252         MK_FLOW_ACTION(MODIFY_FIELD,
253                        sizeof(struct rte_flow_action_modify_field)),
254         /**
255          * Indirect action represented as handle of type
256          * (struct rte_flow_action_handle *) stored in conf field (see
257          * struct rte_flow_action); no need for additional structure to * store
258          * indirect action handle.
259          */
260         MK_FLOW_ACTION(INDIRECT, 0),
261         MK_FLOW_ACTION(CONNTRACK, sizeof(struct rte_flow_action_conntrack)),
262         MK_FLOW_ACTION(PORT_REPRESENTOR, sizeof(struct rte_flow_action_ethdev)),
263         MK_FLOW_ACTION(REPRESENTED_PORT, sizeof(struct rte_flow_action_ethdev)),
264 };
265
266 int
267 rte_flow_dynf_metadata_register(void)
268 {
269         int offset;
270         int flag;
271
272         static const struct rte_mbuf_dynfield desc_offs = {
273                 .name = RTE_MBUF_DYNFIELD_METADATA_NAME,
274                 .size = sizeof(uint32_t),
275                 .align = __alignof__(uint32_t),
276         };
277         static const struct rte_mbuf_dynflag desc_flag = {
278                 .name = RTE_MBUF_DYNFLAG_METADATA_NAME,
279         };
280
281         offset = rte_mbuf_dynfield_register(&desc_offs);
282         if (offset < 0)
283                 goto error;
284         flag = rte_mbuf_dynflag_register(&desc_flag);
285         if (flag < 0)
286                 goto error;
287         rte_flow_dynf_metadata_offs = offset;
288         rte_flow_dynf_metadata_mask = RTE_BIT64(flag);
289         return 0;
290
291 error:
292         rte_flow_dynf_metadata_offs = -1;
293         rte_flow_dynf_metadata_mask = UINT64_C(0);
294         return -rte_errno;
295 }
296
297 static inline void
298 fts_enter(struct rte_eth_dev *dev)
299 {
300         if (!(dev->data->dev_flags & RTE_ETH_DEV_FLOW_OPS_THREAD_SAFE))
301                 pthread_mutex_lock(&dev->data->flow_ops_mutex);
302 }
303
304 static inline void
305 fts_exit(struct rte_eth_dev *dev)
306 {
307         if (!(dev->data->dev_flags & RTE_ETH_DEV_FLOW_OPS_THREAD_SAFE))
308                 pthread_mutex_unlock(&dev->data->flow_ops_mutex);
309 }
310
311 static int
312 flow_err(uint16_t port_id, int ret, struct rte_flow_error *error)
313 {
314         if (ret == 0)
315                 return 0;
316         if (rte_eth_dev_is_removed(port_id))
317                 return rte_flow_error_set(error, EIO,
318                                           RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
319                                           NULL, rte_strerror(EIO));
320         return ret;
321 }
322
323 /* Get generic flow operations structure from a port. */
324 const struct rte_flow_ops *
325 rte_flow_ops_get(uint16_t port_id, struct rte_flow_error *error)
326 {
327         struct rte_eth_dev *dev = &rte_eth_devices[port_id];
328         const struct rte_flow_ops *ops;
329         int code;
330
331         if (unlikely(!rte_eth_dev_is_valid_port(port_id)))
332                 code = ENODEV;
333         else if (unlikely(dev->dev_ops->flow_ops_get == NULL))
334                 /* flow API not supported with this driver dev_ops */
335                 code = ENOSYS;
336         else
337                 code = dev->dev_ops->flow_ops_get(dev, &ops);
338         if (code == 0 && ops == NULL)
339                 /* flow API not supported with this device */
340                 code = ENOSYS;
341
342         if (code != 0) {
343                 rte_flow_error_set(error, code, RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
344                                    NULL, rte_strerror(code));
345                 return NULL;
346         }
347         return ops;
348 }
349
350 /* Check whether a flow rule can be created on a given port. */
351 int
352 rte_flow_validate(uint16_t port_id,
353                   const struct rte_flow_attr *attr,
354                   const struct rte_flow_item pattern[],
355                   const struct rte_flow_action actions[],
356                   struct rte_flow_error *error)
357 {
358         const struct rte_flow_ops *ops = rte_flow_ops_get(port_id, error);
359         struct rte_eth_dev *dev = &rte_eth_devices[port_id];
360         int ret;
361
362         if (unlikely(!ops))
363                 return -rte_errno;
364         if (likely(!!ops->validate)) {
365                 fts_enter(dev);
366                 ret = ops->validate(dev, attr, pattern, actions, error);
367                 fts_exit(dev);
368                 return flow_err(port_id, ret, error);
369         }
370         return rte_flow_error_set(error, ENOSYS,
371                                   RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
372                                   NULL, rte_strerror(ENOSYS));
373 }
374
375 /* Create a flow rule on a given port. */
376 struct rte_flow *
377 rte_flow_create(uint16_t port_id,
378                 const struct rte_flow_attr *attr,
379                 const struct rte_flow_item pattern[],
380                 const struct rte_flow_action actions[],
381                 struct rte_flow_error *error)
382 {
383         struct rte_eth_dev *dev = &rte_eth_devices[port_id];
384         struct rte_flow *flow;
385         const struct rte_flow_ops *ops = rte_flow_ops_get(port_id, error);
386
387         if (unlikely(!ops))
388                 return NULL;
389         if (likely(!!ops->create)) {
390                 fts_enter(dev);
391                 flow = ops->create(dev, attr, pattern, actions, error);
392                 fts_exit(dev);
393                 if (flow == NULL)
394                         flow_err(port_id, -rte_errno, error);
395                 return flow;
396         }
397         rte_flow_error_set(error, ENOSYS, RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
398                            NULL, rte_strerror(ENOSYS));
399         return NULL;
400 }
401
402 /* Destroy a flow rule on a given port. */
403 int
404 rte_flow_destroy(uint16_t port_id,
405                  struct rte_flow *flow,
406                  struct rte_flow_error *error)
407 {
408         struct rte_eth_dev *dev = &rte_eth_devices[port_id];
409         const struct rte_flow_ops *ops = rte_flow_ops_get(port_id, error);
410         int ret;
411
412         if (unlikely(!ops))
413                 return -rte_errno;
414         if (likely(!!ops->destroy)) {
415                 fts_enter(dev);
416                 ret = ops->destroy(dev, flow, error);
417                 fts_exit(dev);
418                 return flow_err(port_id, ret, error);
419         }
420         return rte_flow_error_set(error, ENOSYS,
421                                   RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
422                                   NULL, rte_strerror(ENOSYS));
423 }
424
425 /* Destroy all flow rules associated with a port. */
426 int
427 rte_flow_flush(uint16_t port_id,
428                struct rte_flow_error *error)
429 {
430         struct rte_eth_dev *dev = &rte_eth_devices[port_id];
431         const struct rte_flow_ops *ops = rte_flow_ops_get(port_id, error);
432         int ret;
433
434         if (unlikely(!ops))
435                 return -rte_errno;
436         if (likely(!!ops->flush)) {
437                 fts_enter(dev);
438                 ret = ops->flush(dev, error);
439                 fts_exit(dev);
440                 return flow_err(port_id, ret, error);
441         }
442         return rte_flow_error_set(error, ENOSYS,
443                                   RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
444                                   NULL, rte_strerror(ENOSYS));
445 }
446
447 /* Query an existing flow rule. */
448 int
449 rte_flow_query(uint16_t port_id,
450                struct rte_flow *flow,
451                const struct rte_flow_action *action,
452                void *data,
453                struct rte_flow_error *error)
454 {
455         struct rte_eth_dev *dev = &rte_eth_devices[port_id];
456         const struct rte_flow_ops *ops = rte_flow_ops_get(port_id, error);
457         int ret;
458
459         if (!ops)
460                 return -rte_errno;
461         if (likely(!!ops->query)) {
462                 fts_enter(dev);
463                 ret = ops->query(dev, flow, action, data, error);
464                 fts_exit(dev);
465                 return flow_err(port_id, ret, error);
466         }
467         return rte_flow_error_set(error, ENOSYS,
468                                   RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
469                                   NULL, rte_strerror(ENOSYS));
470 }
471
472 /* Restrict ingress traffic to the defined flow rules. */
473 int
474 rte_flow_isolate(uint16_t port_id,
475                  int set,
476                  struct rte_flow_error *error)
477 {
478         struct rte_eth_dev *dev = &rte_eth_devices[port_id];
479         const struct rte_flow_ops *ops = rte_flow_ops_get(port_id, error);
480         int ret;
481
482         if (!ops)
483                 return -rte_errno;
484         if (likely(!!ops->isolate)) {
485                 fts_enter(dev);
486                 ret = ops->isolate(dev, set, error);
487                 fts_exit(dev);
488                 return flow_err(port_id, ret, error);
489         }
490         return rte_flow_error_set(error, ENOSYS,
491                                   RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
492                                   NULL, rte_strerror(ENOSYS));
493 }
494
495 /* Initialize flow error structure. */
496 int
497 rte_flow_error_set(struct rte_flow_error *error,
498                    int code,
499                    enum rte_flow_error_type type,
500                    const void *cause,
501                    const char *message)
502 {
503         if (error) {
504                 *error = (struct rte_flow_error){
505                         .type = type,
506                         .cause = cause,
507                         .message = message,
508                 };
509         }
510         rte_errno = code;
511         return -code;
512 }
513
514 /** Pattern item specification types. */
515 enum rte_flow_conv_item_spec_type {
516         RTE_FLOW_CONV_ITEM_SPEC,
517         RTE_FLOW_CONV_ITEM_LAST,
518         RTE_FLOW_CONV_ITEM_MASK,
519 };
520
521 /**
522  * Copy pattern item specification.
523  *
524  * @param[out] buf
525  *   Output buffer. Can be NULL if @p size is zero.
526  * @param size
527  *   Size of @p buf in bytes.
528  * @param[in] item
529  *   Pattern item to copy specification from.
530  * @param type
531  *   Specification selector for either @p spec, @p last or @p mask.
532  *
533  * @return
534  *   Number of bytes needed to store pattern item specification regardless
535  *   of @p size. @p buf contents are truncated to @p size if not large
536  *   enough.
537  */
538 static size_t
539 rte_flow_conv_item_spec(void *buf, const size_t size,
540                         const struct rte_flow_item *item,
541                         enum rte_flow_conv_item_spec_type type)
542 {
543         size_t off;
544         const void *data =
545                 type == RTE_FLOW_CONV_ITEM_SPEC ? item->spec :
546                 type == RTE_FLOW_CONV_ITEM_LAST ? item->last :
547                 type == RTE_FLOW_CONV_ITEM_MASK ? item->mask :
548                 NULL;
549
550         switch (item->type) {
551                 union {
552                         const struct rte_flow_item_raw *raw;
553                 } spec;
554                 union {
555                         const struct rte_flow_item_raw *raw;
556                 } last;
557                 union {
558                         const struct rte_flow_item_raw *raw;
559                 } mask;
560                 union {
561                         const struct rte_flow_item_raw *raw;
562                 } src;
563                 union {
564                         struct rte_flow_item_raw *raw;
565                 } dst;
566                 size_t tmp;
567
568         case RTE_FLOW_ITEM_TYPE_RAW:
569                 spec.raw = item->spec;
570                 last.raw = item->last ? item->last : item->spec;
571                 mask.raw = item->mask ? item->mask : &rte_flow_item_raw_mask;
572                 src.raw = data;
573                 dst.raw = buf;
574                 rte_memcpy(dst.raw,
575                            (&(struct rte_flow_item_raw){
576                                 .relative = src.raw->relative,
577                                 .search = src.raw->search,
578                                 .reserved = src.raw->reserved,
579                                 .offset = src.raw->offset,
580                                 .limit = src.raw->limit,
581                                 .length = src.raw->length,
582                            }),
583                            size > sizeof(*dst.raw) ? sizeof(*dst.raw) : size);
584                 off = sizeof(*dst.raw);
585                 if (type == RTE_FLOW_CONV_ITEM_SPEC ||
586                     (type == RTE_FLOW_CONV_ITEM_MASK &&
587                      ((spec.raw->length & mask.raw->length) >=
588                       (last.raw->length & mask.raw->length))))
589                         tmp = spec.raw->length & mask.raw->length;
590                 else
591                         tmp = last.raw->length & mask.raw->length;
592                 if (tmp) {
593                         off = RTE_ALIGN_CEIL(off, sizeof(*dst.raw->pattern));
594                         if (size >= off + tmp)
595                                 dst.raw->pattern = rte_memcpy
596                                         ((void *)((uintptr_t)dst.raw + off),
597                                          src.raw->pattern, tmp);
598                         off += tmp;
599                 }
600                 break;
601         default:
602                 off = rte_flow_conv_copy(buf, data, size,
603                                          rte_flow_desc_item, item->type);
604                 break;
605         }
606         return off;
607 }
608
609 /**
610  * Copy action configuration.
611  *
612  * @param[out] buf
613  *   Output buffer. Can be NULL if @p size is zero.
614  * @param size
615  *   Size of @p buf in bytes.
616  * @param[in] action
617  *   Action to copy configuration from.
618  *
619  * @return
620  *   Number of bytes needed to store pattern item specification regardless
621  *   of @p size. @p buf contents are truncated to @p size if not large
622  *   enough.
623  */
624 static size_t
625 rte_flow_conv_action_conf(void *buf, const size_t size,
626                           const struct rte_flow_action *action)
627 {
628         size_t off;
629
630         switch (action->type) {
631                 union {
632                         const struct rte_flow_action_rss *rss;
633                         const struct rte_flow_action_vxlan_encap *vxlan_encap;
634                         const struct rte_flow_action_nvgre_encap *nvgre_encap;
635                 } src;
636                 union {
637                         struct rte_flow_action_rss *rss;
638                         struct rte_flow_action_vxlan_encap *vxlan_encap;
639                         struct rte_flow_action_nvgre_encap *nvgre_encap;
640                 } dst;
641                 size_t tmp;
642                 int ret;
643
644         case RTE_FLOW_ACTION_TYPE_RSS:
645                 src.rss = action->conf;
646                 dst.rss = buf;
647                 rte_memcpy(dst.rss,
648                            (&(struct rte_flow_action_rss){
649                                 .func = src.rss->func,
650                                 .level = src.rss->level,
651                                 .types = src.rss->types,
652                                 .key_len = src.rss->key_len,
653                                 .queue_num = src.rss->queue_num,
654                            }),
655                            size > sizeof(*dst.rss) ? sizeof(*dst.rss) : size);
656                 off = sizeof(*dst.rss);
657                 if (src.rss->key_len && src.rss->key) {
658                         off = RTE_ALIGN_CEIL(off, sizeof(*dst.rss->key));
659                         tmp = sizeof(*src.rss->key) * src.rss->key_len;
660                         if (size >= off + tmp)
661                                 dst.rss->key = rte_memcpy
662                                         ((void *)((uintptr_t)dst.rss + off),
663                                          src.rss->key, tmp);
664                         off += tmp;
665                 }
666                 if (src.rss->queue_num) {
667                         off = RTE_ALIGN_CEIL(off, sizeof(*dst.rss->queue));
668                         tmp = sizeof(*src.rss->queue) * src.rss->queue_num;
669                         if (size >= off + tmp)
670                                 dst.rss->queue = rte_memcpy
671                                         ((void *)((uintptr_t)dst.rss + off),
672                                          src.rss->queue, tmp);
673                         off += tmp;
674                 }
675                 break;
676         case RTE_FLOW_ACTION_TYPE_VXLAN_ENCAP:
677         case RTE_FLOW_ACTION_TYPE_NVGRE_ENCAP:
678                 src.vxlan_encap = action->conf;
679                 dst.vxlan_encap = buf;
680                 RTE_BUILD_BUG_ON(sizeof(*src.vxlan_encap) !=
681                                  sizeof(*src.nvgre_encap) ||
682                                  offsetof(struct rte_flow_action_vxlan_encap,
683                                           definition) !=
684                                  offsetof(struct rte_flow_action_nvgre_encap,
685                                           definition));
686                 off = sizeof(*dst.vxlan_encap);
687                 if (src.vxlan_encap->definition) {
688                         off = RTE_ALIGN_CEIL
689                                 (off, sizeof(*dst.vxlan_encap->definition));
690                         ret = rte_flow_conv
691                                 (RTE_FLOW_CONV_OP_PATTERN,
692                                  (void *)((uintptr_t)dst.vxlan_encap + off),
693                                  size > off ? size - off : 0,
694                                  src.vxlan_encap->definition, NULL);
695                         if (ret < 0)
696                                 return 0;
697                         if (size >= off + ret)
698                                 dst.vxlan_encap->definition =
699                                         (void *)((uintptr_t)dst.vxlan_encap +
700                                                  off);
701                         off += ret;
702                 }
703                 break;
704         default:
705                 off = rte_flow_conv_copy(buf, action->conf, size,
706                                          rte_flow_desc_action, action->type);
707                 break;
708         }
709         return off;
710 }
711
712 /**
713  * Copy a list of pattern items.
714  *
715  * @param[out] dst
716  *   Destination buffer. Can be NULL if @p size is zero.
717  * @param size
718  *   Size of @p dst in bytes.
719  * @param[in] src
720  *   Source pattern items.
721  * @param num
722  *   Maximum number of pattern items to process from @p src or 0 to process
723  *   the entire list. In both cases, processing stops after
724  *   RTE_FLOW_ITEM_TYPE_END is encountered.
725  * @param[out] error
726  *   Perform verbose error reporting if not NULL.
727  *
728  * @return
729  *   A positive value representing the number of bytes needed to store
730  *   pattern items regardless of @p size on success (@p buf contents are
731  *   truncated to @p size if not large enough), a negative errno value
732  *   otherwise and rte_errno is set.
733  */
734 static int
735 rte_flow_conv_pattern(struct rte_flow_item *dst,
736                       const size_t size,
737                       const struct rte_flow_item *src,
738                       unsigned int num,
739                       struct rte_flow_error *error)
740 {
741         uintptr_t data = (uintptr_t)dst;
742         size_t off;
743         size_t ret;
744         unsigned int i;
745
746         for (i = 0, off = 0; !num || i != num; ++i, ++src, ++dst) {
747                 /**
748                  * allow PMD private flow item
749                  */
750                 if (((int)src->type >= 0) &&
751                         ((size_t)src->type >= RTE_DIM(rte_flow_desc_item) ||
752                     !rte_flow_desc_item[src->type].name))
753                         return rte_flow_error_set
754                                 (error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ITEM, src,
755                                  "cannot convert unknown item type");
756                 if (size >= off + sizeof(*dst))
757                         *dst = (struct rte_flow_item){
758                                 .type = src->type,
759                         };
760                 off += sizeof(*dst);
761                 if (!src->type)
762                         num = i + 1;
763         }
764         num = i;
765         src -= num;
766         dst -= num;
767         do {
768                 if (src->spec) {
769                         off = RTE_ALIGN_CEIL(off, sizeof(double));
770                         ret = rte_flow_conv_item_spec
771                                 ((void *)(data + off),
772                                  size > off ? size - off : 0, src,
773                                  RTE_FLOW_CONV_ITEM_SPEC);
774                         if (size && size >= off + ret)
775                                 dst->spec = (void *)(data + off);
776                         off += ret;
777
778                 }
779                 if (src->last) {
780                         off = RTE_ALIGN_CEIL(off, sizeof(double));
781                         ret = rte_flow_conv_item_spec
782                                 ((void *)(data + off),
783                                  size > off ? size - off : 0, src,
784                                  RTE_FLOW_CONV_ITEM_LAST);
785                         if (size && size >= off + ret)
786                                 dst->last = (void *)(data + off);
787                         off += ret;
788                 }
789                 if (src->mask) {
790                         off = RTE_ALIGN_CEIL(off, sizeof(double));
791                         ret = rte_flow_conv_item_spec
792                                 ((void *)(data + off),
793                                  size > off ? size - off : 0, src,
794                                  RTE_FLOW_CONV_ITEM_MASK);
795                         if (size && size >= off + ret)
796                                 dst->mask = (void *)(data + off);
797                         off += ret;
798                 }
799                 ++src;
800                 ++dst;
801         } while (--num);
802         return off;
803 }
804
805 /**
806  * Copy a list of actions.
807  *
808  * @param[out] dst
809  *   Destination buffer. Can be NULL if @p size is zero.
810  * @param size
811  *   Size of @p dst in bytes.
812  * @param[in] src
813  *   Source actions.
814  * @param num
815  *   Maximum number of actions to process from @p src or 0 to process the
816  *   entire list. In both cases, processing stops after
817  *   RTE_FLOW_ACTION_TYPE_END is encountered.
818  * @param[out] error
819  *   Perform verbose error reporting if not NULL.
820  *
821  * @return
822  *   A positive value representing the number of bytes needed to store
823  *   actions regardless of @p size on success (@p buf contents are truncated
824  *   to @p size if not large enough), a negative errno value otherwise and
825  *   rte_errno is set.
826  */
827 static int
828 rte_flow_conv_actions(struct rte_flow_action *dst,
829                       const size_t size,
830                       const struct rte_flow_action *src,
831                       unsigned int num,
832                       struct rte_flow_error *error)
833 {
834         uintptr_t data = (uintptr_t)dst;
835         size_t off;
836         size_t ret;
837         unsigned int i;
838
839         for (i = 0, off = 0; !num || i != num; ++i, ++src, ++dst) {
840                 /**
841                  * allow PMD private flow action
842                  */
843                 if (((int)src->type >= 0) &&
844                     ((size_t)src->type >= RTE_DIM(rte_flow_desc_action) ||
845                     !rte_flow_desc_action[src->type].name))
846                         return rte_flow_error_set
847                                 (error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ACTION,
848                                  src, "cannot convert unknown action type");
849                 if (size >= off + sizeof(*dst))
850                         *dst = (struct rte_flow_action){
851                                 .type = src->type,
852                         };
853                 off += sizeof(*dst);
854                 if (!src->type)
855                         num = i + 1;
856         }
857         num = i;
858         src -= num;
859         dst -= num;
860         do {
861                 if (src->conf) {
862                         off = RTE_ALIGN_CEIL(off, sizeof(double));
863                         ret = rte_flow_conv_action_conf
864                                 ((void *)(data + off),
865                                  size > off ? size - off : 0, src);
866                         if (size && size >= off + ret)
867                                 dst->conf = (void *)(data + off);
868                         off += ret;
869                 }
870                 ++src;
871                 ++dst;
872         } while (--num);
873         return off;
874 }
875
876 /**
877  * Copy flow rule components.
878  *
879  * This comprises the flow rule descriptor itself, attributes, pattern and
880  * actions list. NULL components in @p src are skipped.
881  *
882  * @param[out] dst
883  *   Destination buffer. Can be NULL if @p size is zero.
884  * @param size
885  *   Size of @p dst in bytes.
886  * @param[in] src
887  *   Source flow rule descriptor.
888  * @param[out] error
889  *   Perform verbose error reporting if not NULL.
890  *
891  * @return
892  *   A positive value representing the number of bytes needed to store all
893  *   components including the descriptor regardless of @p size on success
894  *   (@p buf contents are truncated to @p size if not large enough), a
895  *   negative errno value otherwise and rte_errno is set.
896  */
897 static int
898 rte_flow_conv_rule(struct rte_flow_conv_rule *dst,
899                    const size_t size,
900                    const struct rte_flow_conv_rule *src,
901                    struct rte_flow_error *error)
902 {
903         size_t off;
904         int ret;
905
906         rte_memcpy(dst,
907                    (&(struct rte_flow_conv_rule){
908                         .attr = NULL,
909                         .pattern = NULL,
910                         .actions = NULL,
911                    }),
912                    size > sizeof(*dst) ? sizeof(*dst) : size);
913         off = sizeof(*dst);
914         if (src->attr_ro) {
915                 off = RTE_ALIGN_CEIL(off, sizeof(double));
916                 if (size && size >= off + sizeof(*dst->attr))
917                         dst->attr = rte_memcpy
918                                 ((void *)((uintptr_t)dst + off),
919                                  src->attr_ro, sizeof(*dst->attr));
920                 off += sizeof(*dst->attr);
921         }
922         if (src->pattern_ro) {
923                 off = RTE_ALIGN_CEIL(off, sizeof(double));
924                 ret = rte_flow_conv_pattern((void *)((uintptr_t)dst + off),
925                                             size > off ? size - off : 0,
926                                             src->pattern_ro, 0, error);
927                 if (ret < 0)
928                         return ret;
929                 if (size && size >= off + (size_t)ret)
930                         dst->pattern = (void *)((uintptr_t)dst + off);
931                 off += ret;
932         }
933         if (src->actions_ro) {
934                 off = RTE_ALIGN_CEIL(off, sizeof(double));
935                 ret = rte_flow_conv_actions((void *)((uintptr_t)dst + off),
936                                             size > off ? size - off : 0,
937                                             src->actions_ro, 0, error);
938                 if (ret < 0)
939                         return ret;
940                 if (size >= off + (size_t)ret)
941                         dst->actions = (void *)((uintptr_t)dst + off);
942                 off += ret;
943         }
944         return off;
945 }
946
947 /**
948  * Retrieve the name of a pattern item/action type.
949  *
950  * @param is_action
951  *   Nonzero when @p src represents an action type instead of a pattern item
952  *   type.
953  * @param is_ptr
954  *   Nonzero to write string address instead of contents into @p dst.
955  * @param[out] dst
956  *   Destination buffer. Can be NULL if @p size is zero.
957  * @param size
958  *   Size of @p dst in bytes.
959  * @param[in] src
960  *   Depending on @p is_action, source pattern item or action type cast as a
961  *   pointer.
962  * @param[out] error
963  *   Perform verbose error reporting if not NULL.
964  *
965  * @return
966  *   A positive value representing the number of bytes needed to store the
967  *   name or its address regardless of @p size on success (@p buf contents
968  *   are truncated to @p size if not large enough), a negative errno value
969  *   otherwise and rte_errno is set.
970  */
971 static int
972 rte_flow_conv_name(int is_action,
973                    int is_ptr,
974                    char *dst,
975                    const size_t size,
976                    const void *src,
977                    struct rte_flow_error *error)
978 {
979         struct desc_info {
980                 const struct rte_flow_desc_data *data;
981                 size_t num;
982         };
983         static const struct desc_info info_rep[2] = {
984                 { rte_flow_desc_item, RTE_DIM(rte_flow_desc_item), },
985                 { rte_flow_desc_action, RTE_DIM(rte_flow_desc_action), },
986         };
987         const struct desc_info *const info = &info_rep[!!is_action];
988         unsigned int type = (uintptr_t)src;
989
990         if (type >= info->num)
991                 return rte_flow_error_set
992                         (error, EINVAL, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
993                          "unknown object type to retrieve the name of");
994         if (!is_ptr)
995                 return strlcpy(dst, info->data[type].name, size);
996         if (size >= sizeof(const char **))
997                 *((const char **)dst) = info->data[type].name;
998         return sizeof(const char **);
999 }
1000
1001 /** Helper function to convert flow API objects. */
1002 int
1003 rte_flow_conv(enum rte_flow_conv_op op,
1004               void *dst,
1005               size_t size,
1006               const void *src,
1007               struct rte_flow_error *error)
1008 {
1009         switch (op) {
1010                 const struct rte_flow_attr *attr;
1011
1012         case RTE_FLOW_CONV_OP_NONE:
1013                 return 0;
1014         case RTE_FLOW_CONV_OP_ATTR:
1015                 attr = src;
1016                 if (size > sizeof(*attr))
1017                         size = sizeof(*attr);
1018                 rte_memcpy(dst, attr, size);
1019                 return sizeof(*attr);
1020         case RTE_FLOW_CONV_OP_ITEM:
1021                 return rte_flow_conv_pattern(dst, size, src, 1, error);
1022         case RTE_FLOW_CONV_OP_ACTION:
1023                 return rte_flow_conv_actions(dst, size, src, 1, error);
1024         case RTE_FLOW_CONV_OP_PATTERN:
1025                 return rte_flow_conv_pattern(dst, size, src, 0, error);
1026         case RTE_FLOW_CONV_OP_ACTIONS:
1027                 return rte_flow_conv_actions(dst, size, src, 0, error);
1028         case RTE_FLOW_CONV_OP_RULE:
1029                 return rte_flow_conv_rule(dst, size, src, error);
1030         case RTE_FLOW_CONV_OP_ITEM_NAME:
1031                 return rte_flow_conv_name(0, 0, dst, size, src, error);
1032         case RTE_FLOW_CONV_OP_ACTION_NAME:
1033                 return rte_flow_conv_name(1, 0, dst, size, src, error);
1034         case RTE_FLOW_CONV_OP_ITEM_NAME_PTR:
1035                 return rte_flow_conv_name(0, 1, dst, size, src, error);
1036         case RTE_FLOW_CONV_OP_ACTION_NAME_PTR:
1037                 return rte_flow_conv_name(1, 1, dst, size, src, error);
1038         }
1039         return rte_flow_error_set
1040                 (error, ENOTSUP, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
1041                  "unknown object conversion operation");
1042 }
1043
1044 /** Store a full rte_flow description. */
1045 size_t
1046 rte_flow_copy(struct rte_flow_desc *desc, size_t len,
1047               const struct rte_flow_attr *attr,
1048               const struct rte_flow_item *items,
1049               const struct rte_flow_action *actions)
1050 {
1051         /*
1052          * Overlap struct rte_flow_conv with struct rte_flow_desc in order
1053          * to convert the former to the latter without wasting space.
1054          */
1055         struct rte_flow_conv_rule *dst =
1056                 len ?
1057                 (void *)((uintptr_t)desc +
1058                          (offsetof(struct rte_flow_desc, actions) -
1059                           offsetof(struct rte_flow_conv_rule, actions))) :
1060                 NULL;
1061         size_t dst_size =
1062                 len > sizeof(*desc) - sizeof(*dst) ?
1063                 len - (sizeof(*desc) - sizeof(*dst)) :
1064                 0;
1065         struct rte_flow_conv_rule src = {
1066                 .attr_ro = NULL,
1067                 .pattern_ro = items,
1068                 .actions_ro = actions,
1069         };
1070         int ret;
1071
1072         RTE_BUILD_BUG_ON(sizeof(struct rte_flow_desc) <
1073                          sizeof(struct rte_flow_conv_rule));
1074         if (dst_size &&
1075             (&dst->pattern != &desc->items ||
1076              &dst->actions != &desc->actions ||
1077              (uintptr_t)(dst + 1) != (uintptr_t)(desc + 1))) {
1078                 rte_errno = EINVAL;
1079                 return 0;
1080         }
1081         ret = rte_flow_conv(RTE_FLOW_CONV_OP_RULE, dst, dst_size, &src, NULL);
1082         if (ret < 0)
1083                 return 0;
1084         ret += sizeof(*desc) - sizeof(*dst);
1085         rte_memcpy(desc,
1086                    (&(struct rte_flow_desc){
1087                         .size = ret,
1088                         .attr = *attr,
1089                         .items = dst_size ? dst->pattern : NULL,
1090                         .actions = dst_size ? dst->actions : NULL,
1091                    }),
1092                    len > sizeof(*desc) ? sizeof(*desc) : len);
1093         return ret;
1094 }
1095
1096 int
1097 rte_flow_dev_dump(uint16_t port_id, struct rte_flow *flow,
1098                         FILE *file, struct rte_flow_error *error)
1099 {
1100         struct rte_eth_dev *dev = &rte_eth_devices[port_id];
1101         const struct rte_flow_ops *ops = rte_flow_ops_get(port_id, error);
1102         int ret;
1103
1104         if (unlikely(!ops))
1105                 return -rte_errno;
1106         if (likely(!!ops->dev_dump)) {
1107                 fts_enter(dev);
1108                 ret = ops->dev_dump(dev, flow, file, error);
1109                 fts_exit(dev);
1110                 return flow_err(port_id, ret, error);
1111         }
1112         return rte_flow_error_set(error, ENOSYS,
1113                                   RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
1114                                   NULL, rte_strerror(ENOSYS));
1115 }
1116
1117 int
1118 rte_flow_get_aged_flows(uint16_t port_id, void **contexts,
1119                     uint32_t nb_contexts, struct rte_flow_error *error)
1120 {
1121         struct rte_eth_dev *dev = &rte_eth_devices[port_id];
1122         const struct rte_flow_ops *ops = rte_flow_ops_get(port_id, error);
1123         int ret;
1124
1125         if (unlikely(!ops))
1126                 return -rte_errno;
1127         if (likely(!!ops->get_aged_flows)) {
1128                 fts_enter(dev);
1129                 ret = ops->get_aged_flows(dev, contexts, nb_contexts, error);
1130                 fts_exit(dev);
1131                 return flow_err(port_id, ret, error);
1132         }
1133         return rte_flow_error_set(error, ENOTSUP,
1134                                   RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
1135                                   NULL, rte_strerror(ENOTSUP));
1136 }
1137
1138 struct rte_flow_action_handle *
1139 rte_flow_action_handle_create(uint16_t port_id,
1140                               const struct rte_flow_indir_action_conf *conf,
1141                               const struct rte_flow_action *action,
1142                               struct rte_flow_error *error)
1143 {
1144         struct rte_flow_action_handle *handle;
1145         const struct rte_flow_ops *ops = rte_flow_ops_get(port_id, error);
1146
1147         if (unlikely(!ops))
1148                 return NULL;
1149         if (unlikely(!ops->action_handle_create)) {
1150                 rte_flow_error_set(error, ENOSYS,
1151                                    RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
1152                                    rte_strerror(ENOSYS));
1153                 return NULL;
1154         }
1155         handle = ops->action_handle_create(&rte_eth_devices[port_id],
1156                                            conf, action, error);
1157         if (handle == NULL)
1158                 flow_err(port_id, -rte_errno, error);
1159         return handle;
1160 }
1161
1162 int
1163 rte_flow_action_handle_destroy(uint16_t port_id,
1164                                struct rte_flow_action_handle *handle,
1165                                struct rte_flow_error *error)
1166 {
1167         int ret;
1168         const struct rte_flow_ops *ops = rte_flow_ops_get(port_id, error);
1169
1170         if (unlikely(!ops))
1171                 return -rte_errno;
1172         if (unlikely(!ops->action_handle_destroy))
1173                 return rte_flow_error_set(error, ENOSYS,
1174                                           RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
1175                                           NULL, rte_strerror(ENOSYS));
1176         ret = ops->action_handle_destroy(&rte_eth_devices[port_id],
1177                                          handle, error);
1178         return flow_err(port_id, ret, error);
1179 }
1180
1181 int
1182 rte_flow_action_handle_update(uint16_t port_id,
1183                               struct rte_flow_action_handle *handle,
1184                               const void *update,
1185                               struct rte_flow_error *error)
1186 {
1187         int ret;
1188         const struct rte_flow_ops *ops = rte_flow_ops_get(port_id, error);
1189
1190         if (unlikely(!ops))
1191                 return -rte_errno;
1192         if (unlikely(!ops->action_handle_update))
1193                 return rte_flow_error_set(error, ENOSYS,
1194                                           RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
1195                                           NULL, rte_strerror(ENOSYS));
1196         ret = ops->action_handle_update(&rte_eth_devices[port_id], handle,
1197                                         update, error);
1198         return flow_err(port_id, ret, error);
1199 }
1200
1201 int
1202 rte_flow_action_handle_query(uint16_t port_id,
1203                              const struct rte_flow_action_handle *handle,
1204                              void *data,
1205                              struct rte_flow_error *error)
1206 {
1207         int ret;
1208         const struct rte_flow_ops *ops = rte_flow_ops_get(port_id, error);
1209
1210         if (unlikely(!ops))
1211                 return -rte_errno;
1212         if (unlikely(!ops->action_handle_query))
1213                 return rte_flow_error_set(error, ENOSYS,
1214                                           RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
1215                                           NULL, rte_strerror(ENOSYS));
1216         ret = ops->action_handle_query(&rte_eth_devices[port_id], handle,
1217                                        data, error);
1218         return flow_err(port_id, ret, error);
1219 }
1220
1221 int
1222 rte_flow_tunnel_decap_set(uint16_t port_id,
1223                           struct rte_flow_tunnel *tunnel,
1224                           struct rte_flow_action **actions,
1225                           uint32_t *num_of_actions,
1226                           struct rte_flow_error *error)
1227 {
1228         struct rte_eth_dev *dev = &rte_eth_devices[port_id];
1229         const struct rte_flow_ops *ops = rte_flow_ops_get(port_id, error);
1230
1231         if (unlikely(!ops))
1232                 return -rte_errno;
1233         if (likely(!!ops->tunnel_decap_set)) {
1234                 return flow_err(port_id,
1235                                 ops->tunnel_decap_set(dev, tunnel, actions,
1236                                                       num_of_actions, error),
1237                                 error);
1238         }
1239         return rte_flow_error_set(error, ENOTSUP,
1240                                   RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
1241                                   NULL, rte_strerror(ENOTSUP));
1242 }
1243
1244 int
1245 rte_flow_tunnel_match(uint16_t port_id,
1246                       struct rte_flow_tunnel *tunnel,
1247                       struct rte_flow_item **items,
1248                       uint32_t *num_of_items,
1249                       struct rte_flow_error *error)
1250 {
1251         struct rte_eth_dev *dev = &rte_eth_devices[port_id];
1252         const struct rte_flow_ops *ops = rte_flow_ops_get(port_id, error);
1253
1254         if (unlikely(!ops))
1255                 return -rte_errno;
1256         if (likely(!!ops->tunnel_match)) {
1257                 return flow_err(port_id,
1258                                 ops->tunnel_match(dev, tunnel, items,
1259                                                   num_of_items, error),
1260                                 error);
1261         }
1262         return rte_flow_error_set(error, ENOTSUP,
1263                                   RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
1264                                   NULL, rte_strerror(ENOTSUP));
1265 }
1266
1267 int
1268 rte_flow_get_restore_info(uint16_t port_id,
1269                           struct rte_mbuf *m,
1270                           struct rte_flow_restore_info *restore_info,
1271                           struct rte_flow_error *error)
1272 {
1273         struct rte_eth_dev *dev = &rte_eth_devices[port_id];
1274         const struct rte_flow_ops *ops = rte_flow_ops_get(port_id, error);
1275
1276         if (unlikely(!ops))
1277                 return -rte_errno;
1278         if (likely(!!ops->get_restore_info)) {
1279                 return flow_err(port_id,
1280                                 ops->get_restore_info(dev, m, restore_info,
1281                                                       error),
1282                                 error);
1283         }
1284         return rte_flow_error_set(error, ENOTSUP,
1285                                   RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
1286                                   NULL, rte_strerror(ENOTSUP));
1287 }
1288
1289 int
1290 rte_flow_tunnel_action_decap_release(uint16_t port_id,
1291                                      struct rte_flow_action *actions,
1292                                      uint32_t num_of_actions,
1293                                      struct rte_flow_error *error)
1294 {
1295         struct rte_eth_dev *dev = &rte_eth_devices[port_id];
1296         const struct rte_flow_ops *ops = rte_flow_ops_get(port_id, error);
1297
1298         if (unlikely(!ops))
1299                 return -rte_errno;
1300         if (likely(!!ops->tunnel_action_decap_release)) {
1301                 return flow_err(port_id,
1302                                 ops->tunnel_action_decap_release(dev, actions,
1303                                                                  num_of_actions,
1304                                                                  error),
1305                                 error);
1306         }
1307         return rte_flow_error_set(error, ENOTSUP,
1308                                   RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
1309                                   NULL, rte_strerror(ENOTSUP));
1310 }
1311
1312 int
1313 rte_flow_tunnel_item_release(uint16_t port_id,
1314                              struct rte_flow_item *items,
1315                              uint32_t num_of_items,
1316                              struct rte_flow_error *error)
1317 {
1318         struct rte_eth_dev *dev = &rte_eth_devices[port_id];
1319         const struct rte_flow_ops *ops = rte_flow_ops_get(port_id, error);
1320
1321         if (unlikely(!ops))
1322                 return -rte_errno;
1323         if (likely(!!ops->tunnel_item_release)) {
1324                 return flow_err(port_id,
1325                                 ops->tunnel_item_release(dev, items,
1326                                                          num_of_items, error),
1327                                 error);
1328         }
1329         return rte_flow_error_set(error, ENOTSUP,
1330                                   RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
1331                                   NULL, rte_strerror(ENOTSUP));
1332 }
1333
1334 int
1335 rte_flow_pick_transfer_proxy(uint16_t port_id, uint16_t *proxy_port_id,
1336                              struct rte_flow_error *error)
1337 {
1338         const struct rte_flow_ops *ops = rte_flow_ops_get(port_id, error);
1339         struct rte_eth_dev *dev;
1340
1341         if (unlikely(ops == NULL))
1342                 return -rte_errno;
1343
1344         if (ops->pick_transfer_proxy == NULL) {
1345                 *proxy_port_id = port_id;
1346                 return 0;
1347         }
1348
1349         dev = &rte_eth_devices[port_id];
1350
1351         return flow_err(port_id,
1352                         ops->pick_transfer_proxy(dev, proxy_port_id, error),
1353                         error);
1354 }
1355
1356 struct rte_flow_item_flex_handle *
1357 rte_flow_flex_item_create(uint16_t port_id,
1358                           const struct rte_flow_item_flex_conf *conf,
1359                           struct rte_flow_error *error)
1360 {
1361         struct rte_eth_dev *dev = &rte_eth_devices[port_id];
1362         const struct rte_flow_ops *ops = rte_flow_ops_get(port_id, error);
1363         struct rte_flow_item_flex_handle *handle;
1364
1365         if (unlikely(!ops))
1366                 return NULL;
1367         if (unlikely(!ops->flex_item_create)) {
1368                 rte_flow_error_set(error, ENOTSUP,
1369                                    RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
1370                                    NULL, rte_strerror(ENOTSUP));
1371                 return NULL;
1372         }
1373         handle = ops->flex_item_create(dev, conf, error);
1374         if (handle == NULL)
1375                 flow_err(port_id, -rte_errno, error);
1376         return handle;
1377 }
1378
1379 int
1380 rte_flow_flex_item_release(uint16_t port_id,
1381                            const struct rte_flow_item_flex_handle *handle,
1382                            struct rte_flow_error *error)
1383 {
1384         int ret;
1385         struct rte_eth_dev *dev = &rte_eth_devices[port_id];
1386         const struct rte_flow_ops *ops = rte_flow_ops_get(port_id, error);
1387
1388         if (unlikely(!ops || !ops->flex_item_release))
1389                 return rte_flow_error_set(error, ENOTSUP,
1390                                           RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
1391                                           NULL, rte_strerror(ENOTSUP));
1392         ret = ops->flex_item_release(dev, handle, error);
1393         return flow_err(port_id, ret, error);
1394 }
1395
1396 int
1397 rte_flow_info_get(uint16_t port_id,
1398                   struct rte_flow_port_info *port_info,
1399                   struct rte_flow_queue_info *queue_info,
1400                   struct rte_flow_error *error)
1401 {
1402         struct rte_eth_dev *dev = &rte_eth_devices[port_id];
1403         const struct rte_flow_ops *ops = rte_flow_ops_get(port_id, error);
1404
1405         if (unlikely(!ops))
1406                 return -rte_errno;
1407         if (dev->data->dev_configured == 0) {
1408                 RTE_FLOW_LOG(INFO,
1409                         "Device with port_id=%"PRIu16" is not configured.\n",
1410                         port_id);
1411                 return -EINVAL;
1412         }
1413         if (port_info == NULL) {
1414                 RTE_FLOW_LOG(ERR, "Port %"PRIu16" info is NULL.\n", port_id);
1415                 return -EINVAL;
1416         }
1417         if (likely(!!ops->info_get)) {
1418                 return flow_err(port_id,
1419                                 ops->info_get(dev, port_info, queue_info, error),
1420                                 error);
1421         }
1422         return rte_flow_error_set(error, ENOTSUP,
1423                                   RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
1424                                   NULL, rte_strerror(ENOTSUP));
1425 }
1426
1427 int
1428 rte_flow_configure(uint16_t port_id,
1429                    const struct rte_flow_port_attr *port_attr,
1430                    uint16_t nb_queue,
1431                    const struct rte_flow_queue_attr *queue_attr[],
1432                    struct rte_flow_error *error)
1433 {
1434         struct rte_eth_dev *dev = &rte_eth_devices[port_id];
1435         const struct rte_flow_ops *ops = rte_flow_ops_get(port_id, error);
1436         int ret;
1437
1438         if (unlikely(!ops))
1439                 return -rte_errno;
1440         if (dev->data->dev_configured == 0) {
1441                 RTE_FLOW_LOG(INFO,
1442                         "Device with port_id=%"PRIu16" is not configured.\n",
1443                         port_id);
1444                 return -EINVAL;
1445         }
1446         if (dev->data->dev_started != 0) {
1447                 RTE_FLOW_LOG(INFO,
1448                         "Device with port_id=%"PRIu16" already started.\n",
1449                         port_id);
1450                 return -EINVAL;
1451         }
1452         if (port_attr == NULL) {
1453                 RTE_FLOW_LOG(ERR, "Port %"PRIu16" info is NULL.\n", port_id);
1454                 return -EINVAL;
1455         }
1456         if (queue_attr == NULL) {
1457                 RTE_FLOW_LOG(ERR, "Port %"PRIu16" queue info is NULL.\n", port_id);
1458                 return -EINVAL;
1459         }
1460         if (likely(!!ops->configure)) {
1461                 ret = ops->configure(dev, port_attr, nb_queue, queue_attr, error);
1462                 if (ret == 0)
1463                         dev->data->flow_configured = 1;
1464                 return flow_err(port_id, ret, error);
1465         }
1466         return rte_flow_error_set(error, ENOTSUP,
1467                                   RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
1468                                   NULL, rte_strerror(ENOTSUP));
1469 }
1470
1471 struct rte_flow_pattern_template *
1472 rte_flow_pattern_template_create(uint16_t port_id,
1473                 const struct rte_flow_pattern_template_attr *template_attr,
1474                 const struct rte_flow_item pattern[],
1475                 struct rte_flow_error *error)
1476 {
1477         struct rte_eth_dev *dev = &rte_eth_devices[port_id];
1478         const struct rte_flow_ops *ops = rte_flow_ops_get(port_id, error);
1479         struct rte_flow_pattern_template *template;
1480
1481         if (unlikely(!ops))
1482                 return NULL;
1483         if (dev->data->flow_configured == 0) {
1484                 RTE_FLOW_LOG(INFO,
1485                         "Flow engine on port_id=%"PRIu16" is not configured.\n",
1486                         port_id);
1487                 rte_flow_error_set(error, EINVAL,
1488                                 RTE_FLOW_ERROR_TYPE_STATE,
1489                                 NULL, rte_strerror(EINVAL));
1490                 return NULL;
1491         }
1492         if (template_attr == NULL) {
1493                 RTE_FLOW_LOG(ERR,
1494                              "Port %"PRIu16" template attr is NULL.\n",
1495                              port_id);
1496                 rte_flow_error_set(error, EINVAL,
1497                                    RTE_FLOW_ERROR_TYPE_ATTR,
1498                                    NULL, rte_strerror(EINVAL));
1499                 return NULL;
1500         }
1501         if (pattern == NULL) {
1502                 RTE_FLOW_LOG(ERR,
1503                              "Port %"PRIu16" pattern is NULL.\n",
1504                              port_id);
1505                 rte_flow_error_set(error, EINVAL,
1506                                    RTE_FLOW_ERROR_TYPE_ATTR,
1507                                    NULL, rte_strerror(EINVAL));
1508                 return NULL;
1509         }
1510         if (likely(!!ops->pattern_template_create)) {
1511                 template = ops->pattern_template_create(dev, template_attr,
1512                                                         pattern, error);
1513                 if (template == NULL)
1514                         flow_err(port_id, -rte_errno, error);
1515                 return template;
1516         }
1517         rte_flow_error_set(error, ENOTSUP,
1518                            RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
1519                            NULL, rte_strerror(ENOTSUP));
1520         return NULL;
1521 }
1522
1523 int
1524 rte_flow_pattern_template_destroy(uint16_t port_id,
1525                 struct rte_flow_pattern_template *pattern_template,
1526                 struct rte_flow_error *error)
1527 {
1528         struct rte_eth_dev *dev = &rte_eth_devices[port_id];
1529         const struct rte_flow_ops *ops = rte_flow_ops_get(port_id, error);
1530
1531         if (unlikely(!ops))
1532                 return -rte_errno;
1533         if (unlikely(pattern_template == NULL))
1534                 return 0;
1535         if (likely(!!ops->pattern_template_destroy)) {
1536                 return flow_err(port_id,
1537                                 ops->pattern_template_destroy(dev,
1538                                                               pattern_template,
1539                                                               error),
1540                                 error);
1541         }
1542         return rte_flow_error_set(error, ENOTSUP,
1543                                   RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
1544                                   NULL, rte_strerror(ENOTSUP));
1545 }
1546
1547 struct rte_flow_actions_template *
1548 rte_flow_actions_template_create(uint16_t port_id,
1549                         const struct rte_flow_actions_template_attr *template_attr,
1550                         const struct rte_flow_action actions[],
1551                         const struct rte_flow_action masks[],
1552                         struct rte_flow_error *error)
1553 {
1554         struct rte_eth_dev *dev = &rte_eth_devices[port_id];
1555         const struct rte_flow_ops *ops = rte_flow_ops_get(port_id, error);
1556         struct rte_flow_actions_template *template;
1557
1558         if (unlikely(!ops))
1559                 return NULL;
1560         if (dev->data->flow_configured == 0) {
1561                 RTE_FLOW_LOG(INFO,
1562                         "Flow engine on port_id=%"PRIu16" is not configured.\n",
1563                         port_id);
1564                 rte_flow_error_set(error, EINVAL,
1565                                    RTE_FLOW_ERROR_TYPE_STATE,
1566                                    NULL, rte_strerror(EINVAL));
1567                 return NULL;
1568         }
1569         if (template_attr == NULL) {
1570                 RTE_FLOW_LOG(ERR,
1571                              "Port %"PRIu16" template attr is NULL.\n",
1572                              port_id);
1573                 rte_flow_error_set(error, EINVAL,
1574                                    RTE_FLOW_ERROR_TYPE_ATTR,
1575                                    NULL, rte_strerror(EINVAL));
1576                 return NULL;
1577         }
1578         if (actions == NULL) {
1579                 RTE_FLOW_LOG(ERR,
1580                              "Port %"PRIu16" actions is NULL.\n",
1581                              port_id);
1582                 rte_flow_error_set(error, EINVAL,
1583                                    RTE_FLOW_ERROR_TYPE_ATTR,
1584                                    NULL, rte_strerror(EINVAL));
1585                 return NULL;
1586         }
1587         if (masks == NULL) {
1588                 RTE_FLOW_LOG(ERR,
1589                              "Port %"PRIu16" masks is NULL.\n",
1590                              port_id);
1591                 rte_flow_error_set(error, EINVAL,
1592                                    RTE_FLOW_ERROR_TYPE_ATTR,
1593                                    NULL, rte_strerror(EINVAL));
1594
1595         }
1596         if (likely(!!ops->actions_template_create)) {
1597                 template = ops->actions_template_create(dev, template_attr,
1598                                                         actions, masks, error);
1599                 if (template == NULL)
1600                         flow_err(port_id, -rte_errno, error);
1601                 return template;
1602         }
1603         rte_flow_error_set(error, ENOTSUP,
1604                            RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
1605                            NULL, rte_strerror(ENOTSUP));
1606         return NULL;
1607 }
1608
1609 int
1610 rte_flow_actions_template_destroy(uint16_t port_id,
1611                         struct rte_flow_actions_template *actions_template,
1612                         struct rte_flow_error *error)
1613 {
1614         struct rte_eth_dev *dev = &rte_eth_devices[port_id];
1615         const struct rte_flow_ops *ops = rte_flow_ops_get(port_id, error);
1616
1617         if (unlikely(!ops))
1618                 return -rte_errno;
1619         if (unlikely(actions_template == NULL))
1620                 return 0;
1621         if (likely(!!ops->actions_template_destroy)) {
1622                 return flow_err(port_id,
1623                                 ops->actions_template_destroy(dev,
1624                                                               actions_template,
1625                                                               error),
1626                                 error);
1627         }
1628         return rte_flow_error_set(error, ENOTSUP,
1629                                   RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
1630                                   NULL, rte_strerror(ENOTSUP));
1631 }
1632
1633 struct rte_flow_template_table *
1634 rte_flow_template_table_create(uint16_t port_id,
1635                         const struct rte_flow_template_table_attr *table_attr,
1636                         struct rte_flow_pattern_template *pattern_templates[],
1637                         uint8_t nb_pattern_templates,
1638                         struct rte_flow_actions_template *actions_templates[],
1639                         uint8_t nb_actions_templates,
1640                         struct rte_flow_error *error)
1641 {
1642         struct rte_eth_dev *dev = &rte_eth_devices[port_id];
1643         const struct rte_flow_ops *ops = rte_flow_ops_get(port_id, error);
1644         struct rte_flow_template_table *table;
1645
1646         if (unlikely(!ops))
1647                 return NULL;
1648         if (dev->data->flow_configured == 0) {
1649                 RTE_FLOW_LOG(INFO,
1650                         "Flow engine on port_id=%"PRIu16" is not configured.\n",
1651                         port_id);
1652                 rte_flow_error_set(error, EINVAL,
1653                                    RTE_FLOW_ERROR_TYPE_STATE,
1654                                    NULL, rte_strerror(EINVAL));
1655                 return NULL;
1656         }
1657         if (table_attr == NULL) {
1658                 RTE_FLOW_LOG(ERR,
1659                              "Port %"PRIu16" table attr is NULL.\n",
1660                              port_id);
1661                 rte_flow_error_set(error, EINVAL,
1662                                    RTE_FLOW_ERROR_TYPE_ATTR,
1663                                    NULL, rte_strerror(EINVAL));
1664                 return NULL;
1665         }
1666         if (pattern_templates == NULL) {
1667                 RTE_FLOW_LOG(ERR,
1668                              "Port %"PRIu16" pattern templates is NULL.\n",
1669                              port_id);
1670                 rte_flow_error_set(error, EINVAL,
1671                                    RTE_FLOW_ERROR_TYPE_ATTR,
1672                                    NULL, rte_strerror(EINVAL));
1673                 return NULL;
1674         }
1675         if (actions_templates == NULL) {
1676                 RTE_FLOW_LOG(ERR,
1677                              "Port %"PRIu16" actions templates is NULL.\n",
1678                              port_id);
1679                 rte_flow_error_set(error, EINVAL,
1680                                    RTE_FLOW_ERROR_TYPE_ATTR,
1681                                    NULL, rte_strerror(EINVAL));
1682                 return NULL;
1683         }
1684         if (likely(!!ops->template_table_create)) {
1685                 table = ops->template_table_create(dev, table_attr,
1686                                         pattern_templates, nb_pattern_templates,
1687                                         actions_templates, nb_actions_templates,
1688                                         error);
1689                 if (table == NULL)
1690                         flow_err(port_id, -rte_errno, error);
1691                 return table;
1692         }
1693         rte_flow_error_set(error, ENOTSUP,
1694                            RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
1695                            NULL, rte_strerror(ENOTSUP));
1696         return NULL;
1697 }
1698
1699 int
1700 rte_flow_template_table_destroy(uint16_t port_id,
1701                                 struct rte_flow_template_table *template_table,
1702                                 struct rte_flow_error *error)
1703 {
1704         struct rte_eth_dev *dev = &rte_eth_devices[port_id];
1705         const struct rte_flow_ops *ops = rte_flow_ops_get(port_id, error);
1706
1707         if (unlikely(!ops))
1708                 return -rte_errno;
1709         if (unlikely(template_table == NULL))
1710                 return 0;
1711         if (likely(!!ops->template_table_destroy)) {
1712                 return flow_err(port_id,
1713                                 ops->template_table_destroy(dev,
1714                                                             template_table,
1715                                                             error),
1716                                 error);
1717         }
1718         return rte_flow_error_set(error, ENOTSUP,
1719                                   RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
1720                                   NULL, rte_strerror(ENOTSUP));
1721 }
1722
1723 struct rte_flow *
1724 rte_flow_async_create(uint16_t port_id,
1725                       uint32_t queue_id,
1726                       const struct rte_flow_op_attr *op_attr,
1727                       struct rte_flow_template_table *template_table,
1728                       const struct rte_flow_item pattern[],
1729                       uint8_t pattern_template_index,
1730                       const struct rte_flow_action actions[],
1731                       uint8_t actions_template_index,
1732                       void *user_data,
1733                       struct rte_flow_error *error)
1734 {
1735         struct rte_eth_dev *dev = &rte_eth_devices[port_id];
1736         const struct rte_flow_ops *ops = rte_flow_ops_get(port_id, error);
1737         struct rte_flow *flow;
1738
1739         flow = ops->async_create(dev, queue_id,
1740                                  op_attr, template_table,
1741                                  pattern, pattern_template_index,
1742                                  actions, actions_template_index,
1743                                  user_data, error);
1744         if (flow == NULL)
1745                 flow_err(port_id, -rte_errno, error);
1746         return flow;
1747 }
1748
1749 int
1750 rte_flow_async_destroy(uint16_t port_id,
1751                        uint32_t queue_id,
1752                        const struct rte_flow_op_attr *op_attr,
1753                        struct rte_flow *flow,
1754                        void *user_data,
1755                        struct rte_flow_error *error)
1756 {
1757         struct rte_eth_dev *dev = &rte_eth_devices[port_id];
1758         const struct rte_flow_ops *ops = rte_flow_ops_get(port_id, error);
1759
1760         return flow_err(port_id,
1761                         ops->async_destroy(dev, queue_id,
1762                                            op_attr, flow,
1763                                            user_data, error),
1764                         error);
1765 }
1766
1767 int
1768 rte_flow_push(uint16_t port_id,
1769               uint32_t queue_id,
1770               struct rte_flow_error *error)
1771 {
1772         struct rte_eth_dev *dev = &rte_eth_devices[port_id];
1773         const struct rte_flow_ops *ops = rte_flow_ops_get(port_id, error);
1774
1775         return flow_err(port_id,
1776                         ops->push(dev, queue_id, error),
1777                         error);
1778 }
1779
1780 int
1781 rte_flow_pull(uint16_t port_id,
1782               uint32_t queue_id,
1783               struct rte_flow_op_result res[],
1784               uint16_t n_res,
1785               struct rte_flow_error *error)
1786 {
1787         struct rte_eth_dev *dev = &rte_eth_devices[port_id];
1788         const struct rte_flow_ops *ops = rte_flow_ops_get(port_id, error);
1789         int ret;
1790
1791         ret = ops->pull(dev, queue_id, res, n_res, error);
1792         return ret ? ret : flow_err(port_id, ret, error);
1793 }
1794
1795 struct rte_flow_action_handle *
1796 rte_flow_async_action_handle_create(uint16_t port_id,
1797                 uint32_t queue_id,
1798                 const struct rte_flow_op_attr *op_attr,
1799                 const struct rte_flow_indir_action_conf *indir_action_conf,
1800                 const struct rte_flow_action *action,
1801                 void *user_data,
1802                 struct rte_flow_error *error)
1803 {
1804         struct rte_eth_dev *dev = &rte_eth_devices[port_id];
1805         const struct rte_flow_ops *ops = rte_flow_ops_get(port_id, error);
1806         struct rte_flow_action_handle *handle;
1807
1808         handle = ops->async_action_handle_create(dev, queue_id, op_attr,
1809                                              indir_action_conf, action, user_data, error);
1810         if (handle == NULL)
1811                 flow_err(port_id, -rte_errno, error);
1812         return handle;
1813 }
1814
1815 int
1816 rte_flow_async_action_handle_destroy(uint16_t port_id,
1817                 uint32_t queue_id,
1818                 const struct rte_flow_op_attr *op_attr,
1819                 struct rte_flow_action_handle *action_handle,
1820                 void *user_data,
1821                 struct rte_flow_error *error)
1822 {
1823         struct rte_eth_dev *dev = &rte_eth_devices[port_id];
1824         const struct rte_flow_ops *ops = rte_flow_ops_get(port_id, error);
1825         int ret;
1826
1827         ret = ops->async_action_handle_destroy(dev, queue_id, op_attr,
1828                                            action_handle, user_data, error);
1829         return flow_err(port_id, ret, error);
1830 }
1831
1832 int
1833 rte_flow_async_action_handle_update(uint16_t port_id,
1834                 uint32_t queue_id,
1835                 const struct rte_flow_op_attr *op_attr,
1836                 struct rte_flow_action_handle *action_handle,
1837                 const void *update,
1838                 void *user_data,
1839                 struct rte_flow_error *error)
1840 {
1841         struct rte_eth_dev *dev = &rte_eth_devices[port_id];
1842         const struct rte_flow_ops *ops = rte_flow_ops_get(port_id, error);
1843         int ret;
1844
1845         ret = ops->async_action_handle_update(dev, queue_id, op_attr,
1846                                           action_handle, update, user_data, error);
1847         return flow_err(port_id, ret, error);
1848 }