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