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