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