7241f00353b53952e984486fbd89266a0f9e539a
[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 };
34
35 /** Generate flow_item[] entry. */
36 #define MK_FLOW_ITEM(t, s) \
37         [RTE_FLOW_ITEM_TYPE_ ## t] = { \
38                 .name = # t, \
39                 .size = s, \
40         }
41
42 /** Information about known flow pattern items. */
43 static const struct rte_flow_desc_data rte_flow_desc_item[] = {
44         MK_FLOW_ITEM(END, 0),
45         MK_FLOW_ITEM(VOID, 0),
46         MK_FLOW_ITEM(INVERT, 0),
47         MK_FLOW_ITEM(ANY, sizeof(struct rte_flow_item_any)),
48         MK_FLOW_ITEM(PF, 0),
49         MK_FLOW_ITEM(VF, sizeof(struct rte_flow_item_vf)),
50         MK_FLOW_ITEM(PHY_PORT, sizeof(struct rte_flow_item_phy_port)),
51         MK_FLOW_ITEM(PORT_ID, sizeof(struct rte_flow_item_port_id)),
52         MK_FLOW_ITEM(RAW, sizeof(struct rte_flow_item_raw)),
53         MK_FLOW_ITEM(ETH, sizeof(struct rte_flow_item_eth)),
54         MK_FLOW_ITEM(VLAN, sizeof(struct rte_flow_item_vlan)),
55         MK_FLOW_ITEM(IPV4, sizeof(struct rte_flow_item_ipv4)),
56         MK_FLOW_ITEM(IPV6, sizeof(struct rte_flow_item_ipv6)),
57         MK_FLOW_ITEM(ICMP, sizeof(struct rte_flow_item_icmp)),
58         MK_FLOW_ITEM(UDP, sizeof(struct rte_flow_item_udp)),
59         MK_FLOW_ITEM(TCP, sizeof(struct rte_flow_item_tcp)),
60         MK_FLOW_ITEM(SCTP, sizeof(struct rte_flow_item_sctp)),
61         MK_FLOW_ITEM(VXLAN, sizeof(struct rte_flow_item_vxlan)),
62         MK_FLOW_ITEM(E_TAG, sizeof(struct rte_flow_item_e_tag)),
63         MK_FLOW_ITEM(NVGRE, sizeof(struct rte_flow_item_nvgre)),
64         MK_FLOW_ITEM(MPLS, sizeof(struct rte_flow_item_mpls)),
65         MK_FLOW_ITEM(GRE, sizeof(struct rte_flow_item_gre)),
66         MK_FLOW_ITEM(FUZZY, sizeof(struct rte_flow_item_fuzzy)),
67         MK_FLOW_ITEM(GTP, sizeof(struct rte_flow_item_gtp)),
68         MK_FLOW_ITEM(GTPC, sizeof(struct rte_flow_item_gtp)),
69         MK_FLOW_ITEM(GTPU, sizeof(struct rte_flow_item_gtp)),
70         MK_FLOW_ITEM(ESP, sizeof(struct rte_flow_item_esp)),
71         MK_FLOW_ITEM(GENEVE, sizeof(struct rte_flow_item_geneve)),
72         MK_FLOW_ITEM(VXLAN_GPE, sizeof(struct rte_flow_item_vxlan_gpe)),
73         MK_FLOW_ITEM(ARP_ETH_IPV4, sizeof(struct rte_flow_item_arp_eth_ipv4)),
74         MK_FLOW_ITEM(IPV6_EXT, sizeof(struct rte_flow_item_ipv6_ext)),
75         MK_FLOW_ITEM(IPV6_FRAG_EXT, sizeof(struct rte_flow_item_ipv6_frag_ext)),
76         MK_FLOW_ITEM(ICMP6, sizeof(struct rte_flow_item_icmp6)),
77         MK_FLOW_ITEM(ICMP6_ND_NS, sizeof(struct rte_flow_item_icmp6_nd_ns)),
78         MK_FLOW_ITEM(ICMP6_ND_NA, sizeof(struct rte_flow_item_icmp6_nd_na)),
79         MK_FLOW_ITEM(ICMP6_ND_OPT, sizeof(struct rte_flow_item_icmp6_nd_opt)),
80         MK_FLOW_ITEM(ICMP6_ND_OPT_SLA_ETH,
81                      sizeof(struct rte_flow_item_icmp6_nd_opt_sla_eth)),
82         MK_FLOW_ITEM(ICMP6_ND_OPT_TLA_ETH,
83                      sizeof(struct rte_flow_item_icmp6_nd_opt_tla_eth)),
84         MK_FLOW_ITEM(MARK, sizeof(struct rte_flow_item_mark)),
85         MK_FLOW_ITEM(META, sizeof(struct rte_flow_item_meta)),
86         MK_FLOW_ITEM(TAG, sizeof(struct rte_flow_item_tag)),
87         MK_FLOW_ITEM(GRE_KEY, sizeof(rte_be32_t)),
88         MK_FLOW_ITEM(GTP_PSC, sizeof(struct rte_flow_item_gtp_psc)),
89         MK_FLOW_ITEM(PPPOES, sizeof(struct rte_flow_item_pppoe)),
90         MK_FLOW_ITEM(PPPOED, sizeof(struct rte_flow_item_pppoe)),
91         MK_FLOW_ITEM(PPPOE_PROTO_ID,
92                         sizeof(struct rte_flow_item_pppoe_proto_id)),
93         MK_FLOW_ITEM(NSH, sizeof(struct rte_flow_item_nsh)),
94         MK_FLOW_ITEM(IGMP, sizeof(struct rte_flow_item_igmp)),
95         MK_FLOW_ITEM(AH, sizeof(struct rte_flow_item_ah)),
96         MK_FLOW_ITEM(HIGIG2, sizeof(struct rte_flow_item_higig2_hdr)),
97         MK_FLOW_ITEM(L2TPV3OIP, sizeof(struct rte_flow_item_l2tpv3oip)),
98         MK_FLOW_ITEM(PFCP, sizeof(struct rte_flow_item_pfcp)),
99         MK_FLOW_ITEM(ECPRI, sizeof(struct rte_flow_item_ecpri)),
100         MK_FLOW_ITEM(GENEVE_OPT, sizeof(struct rte_flow_item_geneve_opt)),
101 };
102
103 /** Generate flow_action[] entry. */
104 #define MK_FLOW_ACTION(t, s) \
105         [RTE_FLOW_ACTION_TYPE_ ## t] = { \
106                 .name = # t, \
107                 .size = s, \
108         }
109
110 /** Information about known flow actions. */
111 static const struct rte_flow_desc_data rte_flow_desc_action[] = {
112         MK_FLOW_ACTION(END, 0),
113         MK_FLOW_ACTION(VOID, 0),
114         MK_FLOW_ACTION(PASSTHRU, 0),
115         MK_FLOW_ACTION(JUMP, sizeof(struct rte_flow_action_jump)),
116         MK_FLOW_ACTION(MARK, sizeof(struct rte_flow_action_mark)),
117         MK_FLOW_ACTION(FLAG, 0),
118         MK_FLOW_ACTION(QUEUE, sizeof(struct rte_flow_action_queue)),
119         MK_FLOW_ACTION(DROP, 0),
120         MK_FLOW_ACTION(COUNT, sizeof(struct rte_flow_action_count)),
121         MK_FLOW_ACTION(RSS, sizeof(struct rte_flow_action_rss)),
122         MK_FLOW_ACTION(PF, 0),
123         MK_FLOW_ACTION(VF, sizeof(struct rte_flow_action_vf)),
124         MK_FLOW_ACTION(PHY_PORT, sizeof(struct rte_flow_action_phy_port)),
125         MK_FLOW_ACTION(PORT_ID, sizeof(struct rte_flow_action_port_id)),
126         MK_FLOW_ACTION(METER, sizeof(struct rte_flow_action_meter)),
127         MK_FLOW_ACTION(SECURITY, sizeof(struct rte_flow_action_security)),
128         MK_FLOW_ACTION(OF_SET_MPLS_TTL,
129                        sizeof(struct rte_flow_action_of_set_mpls_ttl)),
130         MK_FLOW_ACTION(OF_DEC_MPLS_TTL, 0),
131         MK_FLOW_ACTION(OF_SET_NW_TTL,
132                        sizeof(struct rte_flow_action_of_set_nw_ttl)),
133         MK_FLOW_ACTION(OF_DEC_NW_TTL, 0),
134         MK_FLOW_ACTION(OF_COPY_TTL_OUT, 0),
135         MK_FLOW_ACTION(OF_COPY_TTL_IN, 0),
136         MK_FLOW_ACTION(OF_POP_VLAN, 0),
137         MK_FLOW_ACTION(OF_PUSH_VLAN,
138                        sizeof(struct rte_flow_action_of_push_vlan)),
139         MK_FLOW_ACTION(OF_SET_VLAN_VID,
140                        sizeof(struct rte_flow_action_of_set_vlan_vid)),
141         MK_FLOW_ACTION(OF_SET_VLAN_PCP,
142                        sizeof(struct rte_flow_action_of_set_vlan_pcp)),
143         MK_FLOW_ACTION(OF_POP_MPLS,
144                        sizeof(struct rte_flow_action_of_pop_mpls)),
145         MK_FLOW_ACTION(OF_PUSH_MPLS,
146                        sizeof(struct rte_flow_action_of_push_mpls)),
147         MK_FLOW_ACTION(VXLAN_ENCAP, sizeof(struct rte_flow_action_vxlan_encap)),
148         MK_FLOW_ACTION(VXLAN_DECAP, 0),
149         MK_FLOW_ACTION(NVGRE_ENCAP, sizeof(struct rte_flow_action_vxlan_encap)),
150         MK_FLOW_ACTION(NVGRE_DECAP, 0),
151         MK_FLOW_ACTION(RAW_ENCAP, sizeof(struct rte_flow_action_raw_encap)),
152         MK_FLOW_ACTION(RAW_DECAP, sizeof(struct rte_flow_action_raw_decap)),
153         MK_FLOW_ACTION(SET_IPV4_SRC,
154                        sizeof(struct rte_flow_action_set_ipv4)),
155         MK_FLOW_ACTION(SET_IPV4_DST,
156                        sizeof(struct rte_flow_action_set_ipv4)),
157         MK_FLOW_ACTION(SET_IPV6_SRC,
158                        sizeof(struct rte_flow_action_set_ipv6)),
159         MK_FLOW_ACTION(SET_IPV6_DST,
160                        sizeof(struct rte_flow_action_set_ipv6)),
161         MK_FLOW_ACTION(SET_TP_SRC,
162                        sizeof(struct rte_flow_action_set_tp)),
163         MK_FLOW_ACTION(SET_TP_DST,
164                        sizeof(struct rte_flow_action_set_tp)),
165         MK_FLOW_ACTION(MAC_SWAP, 0),
166         MK_FLOW_ACTION(DEC_TTL, 0),
167         MK_FLOW_ACTION(SET_TTL, sizeof(struct rte_flow_action_set_ttl)),
168         MK_FLOW_ACTION(SET_MAC_SRC, sizeof(struct rte_flow_action_set_mac)),
169         MK_FLOW_ACTION(SET_MAC_DST, sizeof(struct rte_flow_action_set_mac)),
170         MK_FLOW_ACTION(INC_TCP_SEQ, sizeof(rte_be32_t)),
171         MK_FLOW_ACTION(DEC_TCP_SEQ, sizeof(rte_be32_t)),
172         MK_FLOW_ACTION(INC_TCP_ACK, sizeof(rte_be32_t)),
173         MK_FLOW_ACTION(DEC_TCP_ACK, sizeof(rte_be32_t)),
174         MK_FLOW_ACTION(SET_TAG, sizeof(struct rte_flow_action_set_tag)),
175         MK_FLOW_ACTION(SET_META, sizeof(struct rte_flow_action_set_meta)),
176         MK_FLOW_ACTION(SET_IPV4_DSCP, sizeof(struct rte_flow_action_set_dscp)),
177         MK_FLOW_ACTION(SET_IPV6_DSCP, sizeof(struct rte_flow_action_set_dscp)),
178         MK_FLOW_ACTION(AGE, sizeof(struct rte_flow_action_age)),
179         MK_FLOW_ACTION(SAMPLE, sizeof(struct rte_flow_action_sample)),
180         MK_FLOW_ACTION(MODIFY_FIELD,
181                        sizeof(struct rte_flow_action_modify_field)),
182         /**
183          * Shared action represented as handle of type
184          * (struct rte_flow_shared action *) stored in conf field (see
185          * struct rte_flow_action); no need for additional structure to * store
186          * shared action handle.
187          */
188         MK_FLOW_ACTION(SHARED, 0),
189 };
190
191 int
192 rte_flow_dynf_metadata_register(void)
193 {
194         int offset;
195         int flag;
196
197         static const struct rte_mbuf_dynfield desc_offs = {
198                 .name = RTE_MBUF_DYNFIELD_METADATA_NAME,
199                 .size = sizeof(uint32_t),
200                 .align = __alignof__(uint32_t),
201         };
202         static const struct rte_mbuf_dynflag desc_flag = {
203                 .name = RTE_MBUF_DYNFLAG_METADATA_NAME,
204         };
205
206         offset = rte_mbuf_dynfield_register(&desc_offs);
207         if (offset < 0)
208                 goto error;
209         flag = rte_mbuf_dynflag_register(&desc_flag);
210         if (flag < 0)
211                 goto error;
212         rte_flow_dynf_metadata_offs = offset;
213         rte_flow_dynf_metadata_mask = (1ULL << flag);
214         return 0;
215
216 error:
217         rte_flow_dynf_metadata_offs = -1;
218         rte_flow_dynf_metadata_mask = 0ULL;
219         return -rte_errno;
220 }
221
222 static inline void
223 fts_enter(struct rte_eth_dev *dev)
224 {
225         if (!(dev->data->dev_flags & RTE_ETH_DEV_FLOW_OPS_THREAD_SAFE))
226                 pthread_mutex_lock(&dev->data->flow_ops_mutex);
227 }
228
229 static inline void
230 fts_exit(struct rte_eth_dev *dev)
231 {
232         if (!(dev->data->dev_flags & RTE_ETH_DEV_FLOW_OPS_THREAD_SAFE))
233                 pthread_mutex_unlock(&dev->data->flow_ops_mutex);
234 }
235
236 static int
237 flow_err(uint16_t port_id, int ret, struct rte_flow_error *error)
238 {
239         if (ret == 0)
240                 return 0;
241         if (rte_eth_dev_is_removed(port_id))
242                 return rte_flow_error_set(error, EIO,
243                                           RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
244                                           NULL, rte_strerror(EIO));
245         return ret;
246 }
247
248 /* Get generic flow operations structure from a port. */
249 const struct rte_flow_ops *
250 rte_flow_ops_get(uint16_t port_id, struct rte_flow_error *error)
251 {
252         struct rte_eth_dev *dev = &rte_eth_devices[port_id];
253         const struct rte_flow_ops *ops;
254         int code;
255
256         if (unlikely(!rte_eth_dev_is_valid_port(port_id)))
257                 code = ENODEV;
258         else if (unlikely(dev->dev_ops->flow_ops_get == NULL))
259                 /* flow API not supported with this driver dev_ops */
260                 code = ENOSYS;
261         else
262                 code = dev->dev_ops->flow_ops_get(dev, &ops);
263         if (code == 0 && ops == NULL)
264                 /* flow API not supported with this device */
265                 code = ENOSYS;
266
267         if (code != 0) {
268                 rte_flow_error_set(error, code, RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
269                                    NULL, rte_strerror(code));
270                 return NULL;
271         }
272         return ops;
273 }
274
275 /* Check whether a flow rule can be created on a given port. */
276 int
277 rte_flow_validate(uint16_t port_id,
278                   const struct rte_flow_attr *attr,
279                   const struct rte_flow_item pattern[],
280                   const struct rte_flow_action actions[],
281                   struct rte_flow_error *error)
282 {
283         const struct rte_flow_ops *ops = rte_flow_ops_get(port_id, error);
284         struct rte_eth_dev *dev = &rte_eth_devices[port_id];
285         int ret;
286
287         if (unlikely(!ops))
288                 return -rte_errno;
289         if (likely(!!ops->validate)) {
290                 fts_enter(dev);
291                 ret = ops->validate(dev, attr, pattern, actions, error);
292                 fts_exit(dev);
293                 return flow_err(port_id, ret, error);
294         }
295         return rte_flow_error_set(error, ENOSYS,
296                                   RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
297                                   NULL, rte_strerror(ENOSYS));
298 }
299
300 /* Create a flow rule on a given port. */
301 struct rte_flow *
302 rte_flow_create(uint16_t port_id,
303                 const struct rte_flow_attr *attr,
304                 const struct rte_flow_item pattern[],
305                 const struct rte_flow_action actions[],
306                 struct rte_flow_error *error)
307 {
308         struct rte_eth_dev *dev = &rte_eth_devices[port_id];
309         struct rte_flow *flow;
310         const struct rte_flow_ops *ops = rte_flow_ops_get(port_id, error);
311
312         if (unlikely(!ops))
313                 return NULL;
314         if (likely(!!ops->create)) {
315                 fts_enter(dev);
316                 flow = ops->create(dev, attr, pattern, actions, error);
317                 fts_exit(dev);
318                 if (flow == NULL)
319                         flow_err(port_id, -rte_errno, error);
320                 return flow;
321         }
322         rte_flow_error_set(error, ENOSYS, RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
323                            NULL, rte_strerror(ENOSYS));
324         return NULL;
325 }
326
327 /* Destroy a flow rule on a given port. */
328 int
329 rte_flow_destroy(uint16_t port_id,
330                  struct rte_flow *flow,
331                  struct rte_flow_error *error)
332 {
333         struct rte_eth_dev *dev = &rte_eth_devices[port_id];
334         const struct rte_flow_ops *ops = rte_flow_ops_get(port_id, error);
335         int ret;
336
337         if (unlikely(!ops))
338                 return -rte_errno;
339         if (likely(!!ops->destroy)) {
340                 fts_enter(dev);
341                 ret = ops->destroy(dev, flow, error);
342                 fts_exit(dev);
343                 return flow_err(port_id, ret, error);
344         }
345         return rte_flow_error_set(error, ENOSYS,
346                                   RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
347                                   NULL, rte_strerror(ENOSYS));
348 }
349
350 /* Destroy all flow rules associated with a port. */
351 int
352 rte_flow_flush(uint16_t port_id,
353                struct rte_flow_error *error)
354 {
355         struct rte_eth_dev *dev = &rte_eth_devices[port_id];
356         const struct rte_flow_ops *ops = rte_flow_ops_get(port_id, error);
357         int ret;
358
359         if (unlikely(!ops))
360                 return -rte_errno;
361         if (likely(!!ops->flush)) {
362                 fts_enter(dev);
363                 ret = ops->flush(dev, error);
364                 fts_exit(dev);
365                 return flow_err(port_id, ret, error);
366         }
367         return rte_flow_error_set(error, ENOSYS,
368                                   RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
369                                   NULL, rte_strerror(ENOSYS));
370 }
371
372 /* Query an existing flow rule. */
373 int
374 rte_flow_query(uint16_t port_id,
375                struct rte_flow *flow,
376                const struct rte_flow_action *action,
377                void *data,
378                struct rte_flow_error *error)
379 {
380         struct rte_eth_dev *dev = &rte_eth_devices[port_id];
381         const struct rte_flow_ops *ops = rte_flow_ops_get(port_id, error);
382         int ret;
383
384         if (!ops)
385                 return -rte_errno;
386         if (likely(!!ops->query)) {
387                 fts_enter(dev);
388                 ret = ops->query(dev, flow, action, data, error);
389                 fts_exit(dev);
390                 return flow_err(port_id, ret, error);
391         }
392         return rte_flow_error_set(error, ENOSYS,
393                                   RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
394                                   NULL, rte_strerror(ENOSYS));
395 }
396
397 /* Restrict ingress traffic to the defined flow rules. */
398 int
399 rte_flow_isolate(uint16_t port_id,
400                  int set,
401                  struct rte_flow_error *error)
402 {
403         struct rte_eth_dev *dev = &rte_eth_devices[port_id];
404         const struct rte_flow_ops *ops = rte_flow_ops_get(port_id, error);
405         int ret;
406
407         if (!ops)
408                 return -rte_errno;
409         if (likely(!!ops->isolate)) {
410                 fts_enter(dev);
411                 ret = ops->isolate(dev, set, error);
412                 fts_exit(dev);
413                 return flow_err(port_id, ret, error);
414         }
415         return rte_flow_error_set(error, ENOSYS,
416                                   RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
417                                   NULL, rte_strerror(ENOSYS));
418 }
419
420 /* Initialize flow error structure. */
421 int
422 rte_flow_error_set(struct rte_flow_error *error,
423                    int code,
424                    enum rte_flow_error_type type,
425                    const void *cause,
426                    const char *message)
427 {
428         if (error) {
429                 *error = (struct rte_flow_error){
430                         .type = type,
431                         .cause = cause,
432                         .message = message,
433                 };
434         }
435         rte_errno = code;
436         return -code;
437 }
438
439 /** Pattern item specification types. */
440 enum rte_flow_conv_item_spec_type {
441         RTE_FLOW_CONV_ITEM_SPEC,
442         RTE_FLOW_CONV_ITEM_LAST,
443         RTE_FLOW_CONV_ITEM_MASK,
444 };
445
446 /**
447  * Copy pattern item specification.
448  *
449  * @param[out] buf
450  *   Output buffer. Can be NULL if @p size is zero.
451  * @param size
452  *   Size of @p buf in bytes.
453  * @param[in] item
454  *   Pattern item to copy specification from.
455  * @param type
456  *   Specification selector for either @p spec, @p last or @p mask.
457  *
458  * @return
459  *   Number of bytes needed to store pattern item specification regardless
460  *   of @p size. @p buf contents are truncated to @p size if not large
461  *   enough.
462  */
463 static size_t
464 rte_flow_conv_item_spec(void *buf, const size_t size,
465                         const struct rte_flow_item *item,
466                         enum rte_flow_conv_item_spec_type type)
467 {
468         size_t off;
469         const void *data =
470                 type == RTE_FLOW_CONV_ITEM_SPEC ? item->spec :
471                 type == RTE_FLOW_CONV_ITEM_LAST ? item->last :
472                 type == RTE_FLOW_CONV_ITEM_MASK ? item->mask :
473                 NULL;
474
475         switch (item->type) {
476                 union {
477                         const struct rte_flow_item_raw *raw;
478                 } spec;
479                 union {
480                         const struct rte_flow_item_raw *raw;
481                 } last;
482                 union {
483                         const struct rte_flow_item_raw *raw;
484                 } mask;
485                 union {
486                         const struct rte_flow_item_raw *raw;
487                 } src;
488                 union {
489                         struct rte_flow_item_raw *raw;
490                 } dst;
491                 size_t tmp;
492
493         case RTE_FLOW_ITEM_TYPE_RAW:
494                 spec.raw = item->spec;
495                 last.raw = item->last ? item->last : item->spec;
496                 mask.raw = item->mask ? item->mask : &rte_flow_item_raw_mask;
497                 src.raw = data;
498                 dst.raw = buf;
499                 rte_memcpy(dst.raw,
500                            (&(struct rte_flow_item_raw){
501                                 .relative = src.raw->relative,
502                                 .search = src.raw->search,
503                                 .reserved = src.raw->reserved,
504                                 .offset = src.raw->offset,
505                                 .limit = src.raw->limit,
506                                 .length = src.raw->length,
507                            }),
508                            size > sizeof(*dst.raw) ? sizeof(*dst.raw) : size);
509                 off = sizeof(*dst.raw);
510                 if (type == RTE_FLOW_CONV_ITEM_SPEC ||
511                     (type == RTE_FLOW_CONV_ITEM_MASK &&
512                      ((spec.raw->length & mask.raw->length) >=
513                       (last.raw->length & mask.raw->length))))
514                         tmp = spec.raw->length & mask.raw->length;
515                 else
516                         tmp = last.raw->length & mask.raw->length;
517                 if (tmp) {
518                         off = RTE_ALIGN_CEIL(off, sizeof(*dst.raw->pattern));
519                         if (size >= off + tmp)
520                                 dst.raw->pattern = rte_memcpy
521                                         ((void *)((uintptr_t)dst.raw + off),
522                                          src.raw->pattern, tmp);
523                         off += tmp;
524                 }
525                 break;
526         default:
527                 /**
528                  * allow PMD private flow item
529                  */
530                 off = (int)item->type >= 0 ?
531                       rte_flow_desc_item[item->type].size : sizeof(void *);
532                 rte_memcpy(buf, data, (size > off ? off : size));
533                 break;
534         }
535         return off;
536 }
537
538 /**
539  * Copy action configuration.
540  *
541  * @param[out] buf
542  *   Output buffer. Can be NULL if @p size is zero.
543  * @param size
544  *   Size of @p buf in bytes.
545  * @param[in] action
546  *   Action to copy configuration from.
547  *
548  * @return
549  *   Number of bytes needed to store pattern item specification regardless
550  *   of @p size. @p buf contents are truncated to @p size if not large
551  *   enough.
552  */
553 static size_t
554 rte_flow_conv_action_conf(void *buf, const size_t size,
555                           const struct rte_flow_action *action)
556 {
557         size_t off;
558
559         switch (action->type) {
560                 union {
561                         const struct rte_flow_action_rss *rss;
562                         const struct rte_flow_action_vxlan_encap *vxlan_encap;
563                         const struct rte_flow_action_nvgre_encap *nvgre_encap;
564                 } src;
565                 union {
566                         struct rte_flow_action_rss *rss;
567                         struct rte_flow_action_vxlan_encap *vxlan_encap;
568                         struct rte_flow_action_nvgre_encap *nvgre_encap;
569                 } dst;
570                 size_t tmp;
571                 int ret;
572
573         case RTE_FLOW_ACTION_TYPE_RSS:
574                 src.rss = action->conf;
575                 dst.rss = buf;
576                 rte_memcpy(dst.rss,
577                            (&(struct rte_flow_action_rss){
578                                 .func = src.rss->func,
579                                 .level = src.rss->level,
580                                 .types = src.rss->types,
581                                 .key_len = src.rss->key_len,
582                                 .queue_num = src.rss->queue_num,
583                            }),
584                            size > sizeof(*dst.rss) ? sizeof(*dst.rss) : size);
585                 off = sizeof(*dst.rss);
586                 if (src.rss->key_len && src.rss->key) {
587                         off = RTE_ALIGN_CEIL(off, sizeof(*dst.rss->key));
588                         tmp = sizeof(*src.rss->key) * src.rss->key_len;
589                         if (size >= off + tmp)
590                                 dst.rss->key = rte_memcpy
591                                         ((void *)((uintptr_t)dst.rss + off),
592                                          src.rss->key, tmp);
593                         off += tmp;
594                 }
595                 if (src.rss->queue_num) {
596                         off = RTE_ALIGN_CEIL(off, sizeof(*dst.rss->queue));
597                         tmp = sizeof(*src.rss->queue) * src.rss->queue_num;
598                         if (size >= off + tmp)
599                                 dst.rss->queue = rte_memcpy
600                                         ((void *)((uintptr_t)dst.rss + off),
601                                          src.rss->queue, tmp);
602                         off += tmp;
603                 }
604                 break;
605         case RTE_FLOW_ACTION_TYPE_VXLAN_ENCAP:
606         case RTE_FLOW_ACTION_TYPE_NVGRE_ENCAP:
607                 src.vxlan_encap = action->conf;
608                 dst.vxlan_encap = buf;
609                 RTE_BUILD_BUG_ON(sizeof(*src.vxlan_encap) !=
610                                  sizeof(*src.nvgre_encap) ||
611                                  offsetof(struct rte_flow_action_vxlan_encap,
612                                           definition) !=
613                                  offsetof(struct rte_flow_action_nvgre_encap,
614                                           definition));
615                 off = sizeof(*dst.vxlan_encap);
616                 if (src.vxlan_encap->definition) {
617                         off = RTE_ALIGN_CEIL
618                                 (off, sizeof(*dst.vxlan_encap->definition));
619                         ret = rte_flow_conv
620                                 (RTE_FLOW_CONV_OP_PATTERN,
621                                  (void *)((uintptr_t)dst.vxlan_encap + off),
622                                  size > off ? size - off : 0,
623                                  src.vxlan_encap->definition, NULL);
624                         if (ret < 0)
625                                 return 0;
626                         if (size >= off + ret)
627                                 dst.vxlan_encap->definition =
628                                         (void *)((uintptr_t)dst.vxlan_encap +
629                                                  off);
630                         off += ret;
631                 }
632                 break;
633         default:
634                 /**
635                  * allow PMD private flow action
636                  */
637                 off = (int)action->type >= 0 ?
638                       rte_flow_desc_action[action->type].size : sizeof(void *);
639                 rte_memcpy(buf, action->conf, (size > off ? off : size));
640                 break;
641         }
642         return off;
643 }
644
645 /**
646  * Copy a list of pattern items.
647  *
648  * @param[out] dst
649  *   Destination buffer. Can be NULL if @p size is zero.
650  * @param size
651  *   Size of @p dst in bytes.
652  * @param[in] src
653  *   Source pattern items.
654  * @param num
655  *   Maximum number of pattern items to process from @p src or 0 to process
656  *   the entire list. In both cases, processing stops after
657  *   RTE_FLOW_ITEM_TYPE_END is encountered.
658  * @param[out] error
659  *   Perform verbose error reporting if not NULL.
660  *
661  * @return
662  *   A positive value representing the number of bytes needed to store
663  *   pattern items regardless of @p size on success (@p buf contents are
664  *   truncated to @p size if not large enough), a negative errno value
665  *   otherwise and rte_errno is set.
666  */
667 static int
668 rte_flow_conv_pattern(struct rte_flow_item *dst,
669                       const size_t size,
670                       const struct rte_flow_item *src,
671                       unsigned int num,
672                       struct rte_flow_error *error)
673 {
674         uintptr_t data = (uintptr_t)dst;
675         size_t off;
676         size_t ret;
677         unsigned int i;
678
679         for (i = 0, off = 0; !num || i != num; ++i, ++src, ++dst) {
680                 /**
681                  * allow PMD private flow item
682                  */
683                 if (((int)src->type >= 0) &&
684                         ((size_t)src->type >= RTE_DIM(rte_flow_desc_item) ||
685                     !rte_flow_desc_item[src->type].name))
686                         return rte_flow_error_set
687                                 (error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ITEM, src,
688                                  "cannot convert unknown item type");
689                 if (size >= off + sizeof(*dst))
690                         *dst = (struct rte_flow_item){
691                                 .type = src->type,
692                         };
693                 off += sizeof(*dst);
694                 if (!src->type)
695                         num = i + 1;
696         }
697         num = i;
698         src -= num;
699         dst -= num;
700         do {
701                 if (src->spec) {
702                         off = RTE_ALIGN_CEIL(off, sizeof(double));
703                         ret = rte_flow_conv_item_spec
704                                 ((void *)(data + off),
705                                  size > off ? size - off : 0, src,
706                                  RTE_FLOW_CONV_ITEM_SPEC);
707                         if (size && size >= off + ret)
708                                 dst->spec = (void *)(data + off);
709                         off += ret;
710
711                 }
712                 if (src->last) {
713                         off = RTE_ALIGN_CEIL(off, sizeof(double));
714                         ret = rte_flow_conv_item_spec
715                                 ((void *)(data + off),
716                                  size > off ? size - off : 0, src,
717                                  RTE_FLOW_CONV_ITEM_LAST);
718                         if (size && size >= off + ret)
719                                 dst->last = (void *)(data + off);
720                         off += ret;
721                 }
722                 if (src->mask) {
723                         off = RTE_ALIGN_CEIL(off, sizeof(double));
724                         ret = rte_flow_conv_item_spec
725                                 ((void *)(data + off),
726                                  size > off ? size - off : 0, src,
727                                  RTE_FLOW_CONV_ITEM_MASK);
728                         if (size && size >= off + ret)
729                                 dst->mask = (void *)(data + off);
730                         off += ret;
731                 }
732                 ++src;
733                 ++dst;
734         } while (--num);
735         return off;
736 }
737
738 /**
739  * Copy a list of actions.
740  *
741  * @param[out] dst
742  *   Destination buffer. Can be NULL if @p size is zero.
743  * @param size
744  *   Size of @p dst in bytes.
745  * @param[in] src
746  *   Source actions.
747  * @param num
748  *   Maximum number of actions to process from @p src or 0 to process the
749  *   entire list. In both cases, processing stops after
750  *   RTE_FLOW_ACTION_TYPE_END is encountered.
751  * @param[out] error
752  *   Perform verbose error reporting if not NULL.
753  *
754  * @return
755  *   A positive value representing the number of bytes needed to store
756  *   actions regardless of @p size on success (@p buf contents are truncated
757  *   to @p size if not large enough), a negative errno value otherwise and
758  *   rte_errno is set.
759  */
760 static int
761 rte_flow_conv_actions(struct rte_flow_action *dst,
762                       const size_t size,
763                       const struct rte_flow_action *src,
764                       unsigned int num,
765                       struct rte_flow_error *error)
766 {
767         uintptr_t data = (uintptr_t)dst;
768         size_t off;
769         size_t ret;
770         unsigned int i;
771
772         for (i = 0, off = 0; !num || i != num; ++i, ++src, ++dst) {
773                 /**
774                  * allow PMD private flow action
775                  */
776                 if (((int)src->type >= 0) &&
777                     ((size_t)src->type >= RTE_DIM(rte_flow_desc_action) ||
778                     !rte_flow_desc_action[src->type].name))
779                         return rte_flow_error_set
780                                 (error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ACTION,
781                                  src, "cannot convert unknown action type");
782                 if (size >= off + sizeof(*dst))
783                         *dst = (struct rte_flow_action){
784                                 .type = src->type,
785                         };
786                 off += sizeof(*dst);
787                 if (!src->type)
788                         num = i + 1;
789         }
790         num = i;
791         src -= num;
792         dst -= num;
793         do {
794                 if (src->conf) {
795                         off = RTE_ALIGN_CEIL(off, sizeof(double));
796                         ret = rte_flow_conv_action_conf
797                                 ((void *)(data + off),
798                                  size > off ? size - off : 0, src);
799                         if (size && size >= off + ret)
800                                 dst->conf = (void *)(data + off);
801                         off += ret;
802                 }
803                 ++src;
804                 ++dst;
805         } while (--num);
806         return off;
807 }
808
809 /**
810  * Copy flow rule components.
811  *
812  * This comprises the flow rule descriptor itself, attributes, pattern and
813  * actions list. NULL components in @p src are skipped.
814  *
815  * @param[out] dst
816  *   Destination buffer. Can be NULL if @p size is zero.
817  * @param size
818  *   Size of @p dst in bytes.
819  * @param[in] src
820  *   Source flow rule descriptor.
821  * @param[out] error
822  *   Perform verbose error reporting if not NULL.
823  *
824  * @return
825  *   A positive value representing the number of bytes needed to store all
826  *   components including the descriptor regardless of @p size on success
827  *   (@p buf contents are truncated to @p size if not large enough), a
828  *   negative errno value otherwise and rte_errno is set.
829  */
830 static int
831 rte_flow_conv_rule(struct rte_flow_conv_rule *dst,
832                    const size_t size,
833                    const struct rte_flow_conv_rule *src,
834                    struct rte_flow_error *error)
835 {
836         size_t off;
837         int ret;
838
839         rte_memcpy(dst,
840                    (&(struct rte_flow_conv_rule){
841                         .attr = NULL,
842                         .pattern = NULL,
843                         .actions = NULL,
844                    }),
845                    size > sizeof(*dst) ? sizeof(*dst) : size);
846         off = sizeof(*dst);
847         if (src->attr_ro) {
848                 off = RTE_ALIGN_CEIL(off, sizeof(double));
849                 if (size && size >= off + sizeof(*dst->attr))
850                         dst->attr = rte_memcpy
851                                 ((void *)((uintptr_t)dst + off),
852                                  src->attr_ro, sizeof(*dst->attr));
853                 off += sizeof(*dst->attr);
854         }
855         if (src->pattern_ro) {
856                 off = RTE_ALIGN_CEIL(off, sizeof(double));
857                 ret = rte_flow_conv_pattern((void *)((uintptr_t)dst + off),
858                                             size > off ? size - off : 0,
859                                             src->pattern_ro, 0, error);
860                 if (ret < 0)
861                         return ret;
862                 if (size && size >= off + (size_t)ret)
863                         dst->pattern = (void *)((uintptr_t)dst + off);
864                 off += ret;
865         }
866         if (src->actions_ro) {
867                 off = RTE_ALIGN_CEIL(off, sizeof(double));
868                 ret = rte_flow_conv_actions((void *)((uintptr_t)dst + off),
869                                             size > off ? size - off : 0,
870                                             src->actions_ro, 0, error);
871                 if (ret < 0)
872                         return ret;
873                 if (size >= off + (size_t)ret)
874                         dst->actions = (void *)((uintptr_t)dst + off);
875                 off += ret;
876         }
877         return off;
878 }
879
880 /**
881  * Retrieve the name of a pattern item/action type.
882  *
883  * @param is_action
884  *   Nonzero when @p src represents an action type instead of a pattern item
885  *   type.
886  * @param is_ptr
887  *   Nonzero to write string address instead of contents into @p dst.
888  * @param[out] dst
889  *   Destination buffer. Can be NULL if @p size is zero.
890  * @param size
891  *   Size of @p dst in bytes.
892  * @param[in] src
893  *   Depending on @p is_action, source pattern item or action type cast as a
894  *   pointer.
895  * @param[out] error
896  *   Perform verbose error reporting if not NULL.
897  *
898  * @return
899  *   A positive value representing the number of bytes needed to store the
900  *   name or its address regardless of @p size on success (@p buf contents
901  *   are truncated to @p size if not large enough), a negative errno value
902  *   otherwise and rte_errno is set.
903  */
904 static int
905 rte_flow_conv_name(int is_action,
906                    int is_ptr,
907                    char *dst,
908                    const size_t size,
909                    const void *src,
910                    struct rte_flow_error *error)
911 {
912         struct desc_info {
913                 const struct rte_flow_desc_data *data;
914                 size_t num;
915         };
916         static const struct desc_info info_rep[2] = {
917                 { rte_flow_desc_item, RTE_DIM(rte_flow_desc_item), },
918                 { rte_flow_desc_action, RTE_DIM(rte_flow_desc_action), },
919         };
920         const struct desc_info *const info = &info_rep[!!is_action];
921         unsigned int type = (uintptr_t)src;
922
923         if (type >= info->num)
924                 return rte_flow_error_set
925                         (error, EINVAL, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
926                          "unknown object type to retrieve the name of");
927         if (!is_ptr)
928                 return strlcpy(dst, info->data[type].name, size);
929         if (size >= sizeof(const char **))
930                 *((const char **)dst) = info->data[type].name;
931         return sizeof(const char **);
932 }
933
934 /** Helper function to convert flow API objects. */
935 int
936 rte_flow_conv(enum rte_flow_conv_op op,
937               void *dst,
938               size_t size,
939               const void *src,
940               struct rte_flow_error *error)
941 {
942         switch (op) {
943                 const struct rte_flow_attr *attr;
944
945         case RTE_FLOW_CONV_OP_NONE:
946                 return 0;
947         case RTE_FLOW_CONV_OP_ATTR:
948                 attr = src;
949                 if (size > sizeof(*attr))
950                         size = sizeof(*attr);
951                 rte_memcpy(dst, attr, size);
952                 return sizeof(*attr);
953         case RTE_FLOW_CONV_OP_ITEM:
954                 return rte_flow_conv_pattern(dst, size, src, 1, error);
955         case RTE_FLOW_CONV_OP_ACTION:
956                 return rte_flow_conv_actions(dst, size, src, 1, error);
957         case RTE_FLOW_CONV_OP_PATTERN:
958                 return rte_flow_conv_pattern(dst, size, src, 0, error);
959         case RTE_FLOW_CONV_OP_ACTIONS:
960                 return rte_flow_conv_actions(dst, size, src, 0, error);
961         case RTE_FLOW_CONV_OP_RULE:
962                 return rte_flow_conv_rule(dst, size, src, error);
963         case RTE_FLOW_CONV_OP_ITEM_NAME:
964                 return rte_flow_conv_name(0, 0, dst, size, src, error);
965         case RTE_FLOW_CONV_OP_ACTION_NAME:
966                 return rte_flow_conv_name(1, 0, dst, size, src, error);
967         case RTE_FLOW_CONV_OP_ITEM_NAME_PTR:
968                 return rte_flow_conv_name(0, 1, dst, size, src, error);
969         case RTE_FLOW_CONV_OP_ACTION_NAME_PTR:
970                 return rte_flow_conv_name(1, 1, dst, size, src, error);
971         }
972         return rte_flow_error_set
973                 (error, ENOTSUP, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
974                  "unknown object conversion operation");
975 }
976
977 /** Store a full rte_flow description. */
978 size_t
979 rte_flow_copy(struct rte_flow_desc *desc, size_t len,
980               const struct rte_flow_attr *attr,
981               const struct rte_flow_item *items,
982               const struct rte_flow_action *actions)
983 {
984         /*
985          * Overlap struct rte_flow_conv with struct rte_flow_desc in order
986          * to convert the former to the latter without wasting space.
987          */
988         struct rte_flow_conv_rule *dst =
989                 len ?
990                 (void *)((uintptr_t)desc +
991                          (offsetof(struct rte_flow_desc, actions) -
992                           offsetof(struct rte_flow_conv_rule, actions))) :
993                 NULL;
994         size_t dst_size =
995                 len > sizeof(*desc) - sizeof(*dst) ?
996                 len - (sizeof(*desc) - sizeof(*dst)) :
997                 0;
998         struct rte_flow_conv_rule src = {
999                 .attr_ro = NULL,
1000                 .pattern_ro = items,
1001                 .actions_ro = actions,
1002         };
1003         int ret;
1004
1005         RTE_BUILD_BUG_ON(sizeof(struct rte_flow_desc) <
1006                          sizeof(struct rte_flow_conv_rule));
1007         if (dst_size &&
1008             (&dst->pattern != &desc->items ||
1009              &dst->actions != &desc->actions ||
1010              (uintptr_t)(dst + 1) != (uintptr_t)(desc + 1))) {
1011                 rte_errno = EINVAL;
1012                 return 0;
1013         }
1014         ret = rte_flow_conv(RTE_FLOW_CONV_OP_RULE, dst, dst_size, &src, NULL);
1015         if (ret < 0)
1016                 return 0;
1017         ret += sizeof(*desc) - sizeof(*dst);
1018         rte_memcpy(desc,
1019                    (&(struct rte_flow_desc){
1020                         .size = ret,
1021                         .attr = *attr,
1022                         .items = dst_size ? dst->pattern : NULL,
1023                         .actions = dst_size ? dst->actions : NULL,
1024                    }),
1025                    len > sizeof(*desc) ? sizeof(*desc) : len);
1026         return ret;
1027 }
1028
1029 int
1030 rte_flow_dev_dump(uint16_t port_id, struct rte_flow *flow,
1031                         FILE *file, struct rte_flow_error *error)
1032 {
1033         struct rte_eth_dev *dev = &rte_eth_devices[port_id];
1034         const struct rte_flow_ops *ops = rte_flow_ops_get(port_id, error);
1035         int ret;
1036
1037         if (unlikely(!ops))
1038                 return -rte_errno;
1039         if (likely(!!ops->dev_dump)) {
1040                 fts_enter(dev);
1041                 ret = ops->dev_dump(dev, flow, file, error);
1042                 fts_exit(dev);
1043                 return flow_err(port_id, ret, error);
1044         }
1045         return rte_flow_error_set(error, ENOSYS,
1046                                   RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
1047                                   NULL, rte_strerror(ENOSYS));
1048 }
1049
1050 int
1051 rte_flow_get_aged_flows(uint16_t port_id, void **contexts,
1052                     uint32_t nb_contexts, struct rte_flow_error *error)
1053 {
1054         struct rte_eth_dev *dev = &rte_eth_devices[port_id];
1055         const struct rte_flow_ops *ops = rte_flow_ops_get(port_id, error);
1056         int ret;
1057
1058         if (unlikely(!ops))
1059                 return -rte_errno;
1060         if (likely(!!ops->get_aged_flows)) {
1061                 fts_enter(dev);
1062                 ret = ops->get_aged_flows(dev, contexts, nb_contexts, error);
1063                 fts_exit(dev);
1064                 return flow_err(port_id, ret, error);
1065         }
1066         return rte_flow_error_set(error, ENOTSUP,
1067                                   RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
1068                                   NULL, rte_strerror(ENOTSUP));
1069 }
1070
1071 struct rte_flow_shared_action *
1072 rte_flow_shared_action_create(uint16_t port_id,
1073                               const struct rte_flow_shared_action_conf *conf,
1074                               const struct rte_flow_action *action,
1075                               struct rte_flow_error *error)
1076 {
1077         struct rte_flow_shared_action *shared_action;
1078         const struct rte_flow_ops *ops = rte_flow_ops_get(port_id, error);
1079
1080         if (unlikely(!ops))
1081                 return NULL;
1082         if (unlikely(!ops->shared_action_create)) {
1083                 rte_flow_error_set(error, ENOSYS,
1084                                    RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
1085                                    rte_strerror(ENOSYS));
1086                 return NULL;
1087         }
1088         shared_action = ops->shared_action_create(&rte_eth_devices[port_id],
1089                                                   conf, action, error);
1090         if (shared_action == NULL)
1091                 flow_err(port_id, -rte_errno, error);
1092         return shared_action;
1093 }
1094
1095 int
1096 rte_flow_shared_action_destroy(uint16_t port_id,
1097                               struct rte_flow_shared_action *action,
1098                               struct rte_flow_error *error)
1099 {
1100         int ret;
1101         const struct rte_flow_ops *ops = rte_flow_ops_get(port_id, error);
1102
1103         if (unlikely(!ops))
1104                 return -rte_errno;
1105         if (unlikely(!ops->shared_action_destroy))
1106                 return rte_flow_error_set(error, ENOSYS,
1107                                           RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
1108                                           NULL, rte_strerror(ENOSYS));
1109         ret = ops->shared_action_destroy(&rte_eth_devices[port_id], action,
1110                                          error);
1111         return flow_err(port_id, ret, error);
1112 }
1113
1114 int
1115 rte_flow_shared_action_update(uint16_t port_id,
1116                               struct rte_flow_shared_action *action,
1117                               const struct rte_flow_action *update,
1118                               struct rte_flow_error *error)
1119 {
1120         int ret;
1121         const struct rte_flow_ops *ops = rte_flow_ops_get(port_id, error);
1122
1123         if (unlikely(!ops))
1124                 return -rte_errno;
1125         if (unlikely(!ops->shared_action_update))
1126                 return rte_flow_error_set(error, ENOSYS,
1127                                           RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
1128                                           NULL, rte_strerror(ENOSYS));
1129         ret = ops->shared_action_update(&rte_eth_devices[port_id], action,
1130                                         update, error);
1131         return flow_err(port_id, ret, error);
1132 }
1133
1134 int
1135 rte_flow_shared_action_query(uint16_t port_id,
1136                              const struct rte_flow_shared_action *action,
1137                              void *data,
1138                              struct rte_flow_error *error)
1139 {
1140         int ret;
1141         const struct rte_flow_ops *ops = rte_flow_ops_get(port_id, error);
1142
1143         if (unlikely(!ops))
1144                 return -rte_errno;
1145         if (unlikely(!ops->shared_action_query))
1146                 return rte_flow_error_set(error, ENOSYS,
1147                                           RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
1148                                           NULL, rte_strerror(ENOSYS));
1149         ret = ops->shared_action_query(&rte_eth_devices[port_id], action,
1150                                        data, error);
1151         return flow_err(port_id, ret, error);
1152 }
1153
1154 int
1155 rte_flow_tunnel_decap_set(uint16_t port_id,
1156                           struct rte_flow_tunnel *tunnel,
1157                           struct rte_flow_action **actions,
1158                           uint32_t *num_of_actions,
1159                           struct rte_flow_error *error)
1160 {
1161         struct rte_eth_dev *dev = &rte_eth_devices[port_id];
1162         const struct rte_flow_ops *ops = rte_flow_ops_get(port_id, error);
1163
1164         if (unlikely(!ops))
1165                 return -rte_errno;
1166         if (likely(!!ops->tunnel_decap_set)) {
1167                 return flow_err(port_id,
1168                                 ops->tunnel_decap_set(dev, tunnel, actions,
1169                                                       num_of_actions, error),
1170                                 error);
1171         }
1172         return rte_flow_error_set(error, ENOTSUP,
1173                                   RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
1174                                   NULL, rte_strerror(ENOTSUP));
1175 }
1176
1177 int
1178 rte_flow_tunnel_match(uint16_t port_id,
1179                       struct rte_flow_tunnel *tunnel,
1180                       struct rte_flow_item **items,
1181                       uint32_t *num_of_items,
1182                       struct rte_flow_error *error)
1183 {
1184         struct rte_eth_dev *dev = &rte_eth_devices[port_id];
1185         const struct rte_flow_ops *ops = rte_flow_ops_get(port_id, error);
1186
1187         if (unlikely(!ops))
1188                 return -rte_errno;
1189         if (likely(!!ops->tunnel_match)) {
1190                 return flow_err(port_id,
1191                                 ops->tunnel_match(dev, tunnel, items,
1192                                                   num_of_items, error),
1193                                 error);
1194         }
1195         return rte_flow_error_set(error, ENOTSUP,
1196                                   RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
1197                                   NULL, rte_strerror(ENOTSUP));
1198 }
1199
1200 int
1201 rte_flow_get_restore_info(uint16_t port_id,
1202                           struct rte_mbuf *m,
1203                           struct rte_flow_restore_info *restore_info,
1204                           struct rte_flow_error *error)
1205 {
1206         struct rte_eth_dev *dev = &rte_eth_devices[port_id];
1207         const struct rte_flow_ops *ops = rte_flow_ops_get(port_id, error);
1208
1209         if (unlikely(!ops))
1210                 return -rte_errno;
1211         if (likely(!!ops->get_restore_info)) {
1212                 return flow_err(port_id,
1213                                 ops->get_restore_info(dev, m, restore_info,
1214                                                       error),
1215                                 error);
1216         }
1217         return rte_flow_error_set(error, ENOTSUP,
1218                                   RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
1219                                   NULL, rte_strerror(ENOTSUP));
1220 }
1221
1222 int
1223 rte_flow_tunnel_action_decap_release(uint16_t port_id,
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_action_decap_release)) {
1234                 return flow_err(port_id,
1235                                 ops->tunnel_action_decap_release(dev, actions,
1236                                                                  num_of_actions,
1237                                                                  error),
1238                                 error);
1239         }
1240         return rte_flow_error_set(error, ENOTSUP,
1241                                   RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
1242                                   NULL, rte_strerror(ENOTSUP));
1243 }
1244
1245 int
1246 rte_flow_tunnel_item_release(uint16_t port_id,
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_item_release)) {
1257                 return flow_err(port_id,
1258                                 ops->tunnel_item_release(dev, 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 }