Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : * Copyright 2016 6WIND S.A.
3 : : * Copyright 2016 Mellanox Technologies, Ltd
4 : : */
5 : :
6 : : #include <stdalign.h>
7 : : #include <errno.h>
8 : : #include <stddef.h>
9 : : #include <stdint.h>
10 : : #include <pthread.h>
11 : :
12 : : #include <eal_export.h>
13 : : #include <rte_common.h>
14 : : #include <rte_errno.h>
15 : : #include <rte_branch_prediction.h>
16 : : #include <rte_string_fns.h>
17 : : #include <rte_mbuf_dyn.h>
18 : : #include "rte_flow_driver.h"
19 : : #include "rte_flow.h"
20 : :
21 : : #include "ethdev_trace.h"
22 : :
23 : : #define FLOW_LOG RTE_ETHDEV_LOG_LINE
24 : :
25 : : /* Mbuf dynamic field name for metadata. */
26 : : RTE_EXPORT_SYMBOL(rte_flow_dynf_metadata_offs)
27 : : int32_t rte_flow_dynf_metadata_offs = -1;
28 : :
29 : : /* Mbuf dynamic field flag bit number for metadata. */
30 : : RTE_EXPORT_SYMBOL(rte_flow_dynf_metadata_mask)
31 : : uint64_t rte_flow_dynf_metadata_mask;
32 : :
33 : : /**
34 : : * Flow elements description tables.
35 : : */
36 : : struct rte_flow_desc_data {
37 : : const char *name;
38 : : size_t size;
39 : : size_t (*desc_fn)(void *dst, const void *src, size_t size);
40 : : };
41 : :
42 : : /**
43 : : *
44 : : * @param buf
45 : : * Destination memory.
46 : : * @param data
47 : : * Source memory
48 : : * @param size
49 : : * Requested copy size
50 : : * @param desc
51 : : * rte_flow_desc_item - for flow item conversion.
52 : : * rte_flow_desc_action - for flow action conversion.
53 : : * @param type
54 : : * Offset into the desc param or negative value for private flow elements.
55 : : */
56 : : static inline size_t
57 : 0 : rte_flow_conv_copy(void *buf, const void *data, const size_t size,
58 : : const struct rte_flow_desc_data *desc, int type)
59 : : {
60 : : /**
61 : : * Allow PMD private flow item
62 : : */
63 : : bool rte_type = type >= 0;
64 : :
65 [ # # ]: 0 : size_t sz = rte_type ? desc[type].size : sizeof(void *);
66 [ # # ]: 0 : if (data == NULL)
67 : : return 0;
68 [ # # ]: 0 : if (buf != NULL)
69 [ # # ]: 0 : rte_memcpy(buf, data, (size > sz ? sz : size));
70 [ # # # # ]: 0 : if (rte_type && desc[type].desc_fn)
71 [ # # # # ]: 0 : sz += desc[type].desc_fn(size > 0 ? buf : NULL, data,
72 : : size > sz ? size - sz : 0);
73 : : return sz;
74 : : }
75 : :
76 : : static size_t
77 : 0 : rte_flow_item_flex_conv(void *buf, const void *data, size_t size)
78 : : {
79 : : struct rte_flow_item_flex *dst = buf;
80 : : const struct rte_flow_item_flex *src = data;
81 [ # # # # ]: 0 : if (buf && size >= src->length) {
82 : 0 : dst->pattern = rte_memcpy
83 [ # # ]: 0 : ((void *)((uintptr_t)(dst + 1)), src->pattern,
84 : : src->length);
85 : : }
86 : 0 : return src->length;
87 : : }
88 : :
89 : : /** Generate flow_item[] entry. */
90 : : #define MK_FLOW_ITEM(t, s) \
91 : : [RTE_FLOW_ITEM_TYPE_ ## t] = { \
92 : : .name = # t, \
93 : : .size = s, \
94 : : .desc_fn = NULL,\
95 : : }
96 : :
97 : : #define MK_FLOW_ITEM_FN(t, s, fn) \
98 : : [RTE_FLOW_ITEM_TYPE_ ## t] = {\
99 : : .name = # t, \
100 : : .size = s, \
101 : : .desc_fn = fn, \
102 : : }
103 : :
104 : : /** Information about known flow pattern items. */
105 : : static const struct rte_flow_desc_data rte_flow_desc_item[] = {
106 : : MK_FLOW_ITEM(END, 0),
107 : : MK_FLOW_ITEM(VOID, 0),
108 : : MK_FLOW_ITEM(INVERT, 0),
109 : : MK_FLOW_ITEM(ANY, sizeof(struct rte_flow_item_any)),
110 : : MK_FLOW_ITEM(PORT_ID, sizeof(struct rte_flow_item_port_id)),
111 : : MK_FLOW_ITEM(RAW, sizeof(struct rte_flow_item_raw)),
112 : : MK_FLOW_ITEM(ETH, sizeof(struct rte_flow_item_eth)),
113 : : MK_FLOW_ITEM(VLAN, sizeof(struct rte_flow_item_vlan)),
114 : : MK_FLOW_ITEM(IPV4, sizeof(struct rte_flow_item_ipv4)),
115 : : MK_FLOW_ITEM(IPV6, sizeof(struct rte_flow_item_ipv6)),
116 : : MK_FLOW_ITEM(ICMP, sizeof(struct rte_flow_item_icmp)),
117 : : MK_FLOW_ITEM(UDP, sizeof(struct rte_flow_item_udp)),
118 : : MK_FLOW_ITEM(TCP, sizeof(struct rte_flow_item_tcp)),
119 : : MK_FLOW_ITEM(SCTP, sizeof(struct rte_flow_item_sctp)),
120 : : MK_FLOW_ITEM(VXLAN, sizeof(struct rte_flow_item_vxlan)),
121 : : MK_FLOW_ITEM(E_TAG, sizeof(struct rte_flow_item_e_tag)),
122 : : MK_FLOW_ITEM(NVGRE, sizeof(struct rte_flow_item_nvgre)),
123 : : MK_FLOW_ITEM(MPLS, sizeof(struct rte_flow_item_mpls)),
124 : : MK_FLOW_ITEM(GRE, sizeof(struct rte_flow_item_gre)),
125 : : MK_FLOW_ITEM(FUZZY, sizeof(struct rte_flow_item_fuzzy)),
126 : : MK_FLOW_ITEM(GTP, sizeof(struct rte_flow_item_gtp)),
127 : : MK_FLOW_ITEM(GTPC, sizeof(struct rte_flow_item_gtp)),
128 : : MK_FLOW_ITEM(GTPU, sizeof(struct rte_flow_item_gtp)),
129 : : MK_FLOW_ITEM(ESP, sizeof(struct rte_flow_item_esp)),
130 : : MK_FLOW_ITEM(GENEVE, sizeof(struct rte_flow_item_geneve)),
131 : : MK_FLOW_ITEM(VXLAN_GPE, sizeof(struct rte_flow_item_vxlan_gpe)),
132 : : MK_FLOW_ITEM(ARP_ETH_IPV4, sizeof(struct rte_flow_item_arp_eth_ipv4)),
133 : : MK_FLOW_ITEM(IPV6_EXT, sizeof(struct rte_flow_item_ipv6_ext)),
134 : : MK_FLOW_ITEM(IPV6_FRAG_EXT, sizeof(struct rte_flow_item_ipv6_frag_ext)),
135 : : MK_FLOW_ITEM(ICMP6, sizeof(struct rte_flow_item_icmp6)),
136 : : MK_FLOW_ITEM(ICMP6_ECHO_REQUEST, sizeof(struct rte_flow_item_icmp6_echo)),
137 : : MK_FLOW_ITEM(ICMP6_ECHO_REPLY, sizeof(struct rte_flow_item_icmp6_echo)),
138 : : MK_FLOW_ITEM(ICMP6_ND_NS, sizeof(struct rte_flow_item_icmp6_nd_ns)),
139 : : MK_FLOW_ITEM(ICMP6_ND_NA, sizeof(struct rte_flow_item_icmp6_nd_na)),
140 : : MK_FLOW_ITEM(ICMP6_ND_OPT, sizeof(struct rte_flow_item_icmp6_nd_opt)),
141 : : MK_FLOW_ITEM(ICMP6_ND_OPT_SLA_ETH,
142 : : sizeof(struct rte_flow_item_icmp6_nd_opt_sla_eth)),
143 : : MK_FLOW_ITEM(ICMP6_ND_OPT_TLA_ETH,
144 : : sizeof(struct rte_flow_item_icmp6_nd_opt_tla_eth)),
145 : : MK_FLOW_ITEM(MARK, sizeof(struct rte_flow_item_mark)),
146 : : MK_FLOW_ITEM(META, sizeof(struct rte_flow_item_meta)),
147 : : MK_FLOW_ITEM(RANDOM, sizeof(struct rte_flow_item_random)),
148 : : MK_FLOW_ITEM(TAG, sizeof(struct rte_flow_item_tag)),
149 : : MK_FLOW_ITEM(GRE_KEY, sizeof(rte_be32_t)),
150 : : MK_FLOW_ITEM(GRE_OPTION, sizeof(struct rte_flow_item_gre_opt)),
151 : : MK_FLOW_ITEM(GTP_PSC, sizeof(struct rte_flow_item_gtp_psc)),
152 : : MK_FLOW_ITEM(PPPOES, sizeof(struct rte_flow_item_pppoe)),
153 : : MK_FLOW_ITEM(PPPOED, sizeof(struct rte_flow_item_pppoe)),
154 : : MK_FLOW_ITEM(PPPOE_PROTO_ID,
155 : : sizeof(struct rte_flow_item_pppoe_proto_id)),
156 : : MK_FLOW_ITEM(NSH, sizeof(struct rte_flow_item_nsh)),
157 : : MK_FLOW_ITEM(IGMP, sizeof(struct rte_flow_item_igmp)),
158 : : MK_FLOW_ITEM(AH, sizeof(struct rte_flow_item_ah)),
159 : : MK_FLOW_ITEM(HIGIG2, sizeof(struct rte_flow_item_higig2_hdr)),
160 : : MK_FLOW_ITEM(L2TPV3OIP, sizeof(struct rte_flow_item_l2tpv3oip)),
161 : : MK_FLOW_ITEM(PFCP, sizeof(struct rte_flow_item_pfcp)),
162 : : MK_FLOW_ITEM(ECPRI, sizeof(struct rte_flow_item_ecpri)),
163 : : MK_FLOW_ITEM(GENEVE_OPT, sizeof(struct rte_flow_item_geneve_opt)),
164 : : MK_FLOW_ITEM(INTEGRITY, sizeof(struct rte_flow_item_integrity)),
165 : : MK_FLOW_ITEM(CONNTRACK, sizeof(uint32_t)),
166 : : MK_FLOW_ITEM(PORT_REPRESENTOR, sizeof(struct rte_flow_item_ethdev)),
167 : : MK_FLOW_ITEM(REPRESENTED_PORT, sizeof(struct rte_flow_item_ethdev)),
168 : : MK_FLOW_ITEM_FN(FLEX, sizeof(struct rte_flow_item_flex),
169 : : rte_flow_item_flex_conv),
170 : : MK_FLOW_ITEM(L2TPV2, sizeof(struct rte_flow_item_l2tpv2)),
171 : : MK_FLOW_ITEM(PPP, sizeof(struct rte_flow_item_ppp)),
172 : : MK_FLOW_ITEM(METER_COLOR, sizeof(struct rte_flow_item_meter_color)),
173 : : MK_FLOW_ITEM(IPV6_ROUTING_EXT, sizeof(struct rte_flow_item_ipv6_routing_ext)),
174 : : MK_FLOW_ITEM(QUOTA, sizeof(struct rte_flow_item_quota)),
175 : : MK_FLOW_ITEM(AGGR_AFFINITY, sizeof(struct rte_flow_item_aggr_affinity)),
176 : : MK_FLOW_ITEM(TX_QUEUE, sizeof(struct rte_flow_item_tx_queue)),
177 : : MK_FLOW_ITEM(IB_BTH, sizeof(struct rte_flow_item_ib_bth)),
178 : : MK_FLOW_ITEM(PTYPE, sizeof(struct rte_flow_item_ptype)),
179 : : MK_FLOW_ITEM(COMPARE, sizeof(struct rte_flow_item_compare)),
180 : : };
181 : :
182 : : /** Generate flow_action[] entry. */
183 : : #define MK_FLOW_ACTION(t, s) \
184 : : [RTE_FLOW_ACTION_TYPE_ ## t] = { \
185 : : .name = # t, \
186 : : .size = s, \
187 : : .desc_fn = NULL,\
188 : : }
189 : :
190 : : #define MK_FLOW_ACTION_FN(t, fn) \
191 : : [RTE_FLOW_ACTION_TYPE_ ## t] = { \
192 : : .name = # t, \
193 : : .size = 0, \
194 : : .desc_fn = fn,\
195 : : }
196 : :
197 : :
198 : : /** Information about known flow actions. */
199 : : static const struct rte_flow_desc_data rte_flow_desc_action[] = {
200 : : MK_FLOW_ACTION(END, 0),
201 : : MK_FLOW_ACTION(VOID, 0),
202 : : MK_FLOW_ACTION(PASSTHRU, 0),
203 : : MK_FLOW_ACTION(JUMP, sizeof(struct rte_flow_action_jump)),
204 : : MK_FLOW_ACTION(MARK, sizeof(struct rte_flow_action_mark)),
205 : : MK_FLOW_ACTION(FLAG, 0),
206 : : MK_FLOW_ACTION(QUEUE, sizeof(struct rte_flow_action_queue)),
207 : : MK_FLOW_ACTION(DROP, 0),
208 : : MK_FLOW_ACTION(COUNT, sizeof(struct rte_flow_action_count)),
209 : : MK_FLOW_ACTION(RSS, sizeof(struct rte_flow_action_rss)),
210 : : MK_FLOW_ACTION(PF, 0),
211 : : MK_FLOW_ACTION(VF, sizeof(struct rte_flow_action_vf)),
212 : : MK_FLOW_ACTION(PORT_ID, sizeof(struct rte_flow_action_port_id)),
213 : : MK_FLOW_ACTION(METER, sizeof(struct rte_flow_action_meter)),
214 : : MK_FLOW_ACTION(SECURITY, sizeof(struct rte_flow_action_security)),
215 : : MK_FLOW_ACTION(OF_DEC_NW_TTL, 0),
216 : : MK_FLOW_ACTION(OF_POP_VLAN, 0),
217 : : MK_FLOW_ACTION(OF_PUSH_VLAN,
218 : : sizeof(struct rte_flow_action_of_push_vlan)),
219 : : MK_FLOW_ACTION(OF_SET_VLAN_VID,
220 : : sizeof(struct rte_flow_action_of_set_vlan_vid)),
221 : : MK_FLOW_ACTION(OF_SET_VLAN_PCP,
222 : : sizeof(struct rte_flow_action_of_set_vlan_pcp)),
223 : : MK_FLOW_ACTION(OF_POP_MPLS,
224 : : sizeof(struct rte_flow_action_of_pop_mpls)),
225 : : MK_FLOW_ACTION(OF_PUSH_MPLS,
226 : : sizeof(struct rte_flow_action_of_push_mpls)),
227 : : MK_FLOW_ACTION(VXLAN_ENCAP, sizeof(struct rte_flow_action_vxlan_encap)),
228 : : MK_FLOW_ACTION(VXLAN_DECAP, 0),
229 : : MK_FLOW_ACTION(NVGRE_ENCAP, sizeof(struct rte_flow_action_nvgre_encap)),
230 : : MK_FLOW_ACTION(NVGRE_DECAP, 0),
231 : : MK_FLOW_ACTION(RAW_ENCAP, sizeof(struct rte_flow_action_raw_encap)),
232 : : MK_FLOW_ACTION(RAW_DECAP, sizeof(struct rte_flow_action_raw_decap)),
233 : : MK_FLOW_ACTION(SET_IPV4_SRC,
234 : : sizeof(struct rte_flow_action_set_ipv4)),
235 : : MK_FLOW_ACTION(SET_IPV4_DST,
236 : : sizeof(struct rte_flow_action_set_ipv4)),
237 : : MK_FLOW_ACTION(SET_IPV6_SRC,
238 : : sizeof(struct rte_flow_action_set_ipv6)),
239 : : MK_FLOW_ACTION(SET_IPV6_DST,
240 : : sizeof(struct rte_flow_action_set_ipv6)),
241 : : MK_FLOW_ACTION(SET_TP_SRC,
242 : : sizeof(struct rte_flow_action_set_tp)),
243 : : MK_FLOW_ACTION(SET_TP_DST,
244 : : sizeof(struct rte_flow_action_set_tp)),
245 : : MK_FLOW_ACTION(MAC_SWAP, 0),
246 : : MK_FLOW_ACTION(DEC_TTL, 0),
247 : : MK_FLOW_ACTION(SET_TTL, sizeof(struct rte_flow_action_set_ttl)),
248 : : MK_FLOW_ACTION(SET_MAC_SRC, sizeof(struct rte_flow_action_set_mac)),
249 : : MK_FLOW_ACTION(SET_MAC_DST, sizeof(struct rte_flow_action_set_mac)),
250 : : MK_FLOW_ACTION(INC_TCP_SEQ, sizeof(rte_be32_t)),
251 : : MK_FLOW_ACTION(DEC_TCP_SEQ, sizeof(rte_be32_t)),
252 : : MK_FLOW_ACTION(INC_TCP_ACK, sizeof(rte_be32_t)),
253 : : MK_FLOW_ACTION(DEC_TCP_ACK, sizeof(rte_be32_t)),
254 : : MK_FLOW_ACTION(SET_TAG, sizeof(struct rte_flow_action_set_tag)),
255 : : MK_FLOW_ACTION(SET_META, sizeof(struct rte_flow_action_set_meta)),
256 : : MK_FLOW_ACTION(SET_IPV4_DSCP, sizeof(struct rte_flow_action_set_dscp)),
257 : : MK_FLOW_ACTION(SET_IPV6_DSCP, sizeof(struct rte_flow_action_set_dscp)),
258 : : MK_FLOW_ACTION(AGE, sizeof(struct rte_flow_action_age)),
259 : : MK_FLOW_ACTION(SAMPLE, sizeof(struct rte_flow_action_sample)),
260 : : MK_FLOW_ACTION(MODIFY_FIELD,
261 : : sizeof(struct rte_flow_action_modify_field)),
262 : : /**
263 : : * Indirect action represented as handle of type
264 : : * (struct rte_flow_action_handle *) stored in conf field (see
265 : : * struct rte_flow_action); no need for additional structure to * store
266 : : * indirect action handle.
267 : : */
268 : : MK_FLOW_ACTION(INDIRECT, 0),
269 : : MK_FLOW_ACTION(CONNTRACK, sizeof(struct rte_flow_action_conntrack)),
270 : : MK_FLOW_ACTION(PORT_REPRESENTOR, sizeof(struct rte_flow_action_ethdev)),
271 : : MK_FLOW_ACTION(REPRESENTED_PORT, sizeof(struct rte_flow_action_ethdev)),
272 : : MK_FLOW_ACTION(METER_MARK, sizeof(struct rte_flow_action_meter_mark)),
273 : : MK_FLOW_ACTION(SEND_TO_KERNEL, 0),
274 : : MK_FLOW_ACTION(QUOTA, sizeof(struct rte_flow_action_quota)),
275 : : MK_FLOW_ACTION(IPV6_EXT_PUSH, sizeof(struct rte_flow_action_ipv6_ext_push)),
276 : : MK_FLOW_ACTION(IPV6_EXT_REMOVE, sizeof(struct rte_flow_action_ipv6_ext_remove)),
277 : : MK_FLOW_ACTION(INDIRECT_LIST,
278 : : sizeof(struct rte_flow_action_indirect_list)),
279 : : MK_FLOW_ACTION(PROG,
280 : : sizeof(struct rte_flow_action_prog)),
281 : : MK_FLOW_ACTION(NAT64, sizeof(struct rte_flow_action_nat64)),
282 : : MK_FLOW_ACTION(JUMP_TO_TABLE_INDEX, sizeof(struct rte_flow_action_jump_to_table_index)),
283 : : };
284 : :
285 : : RTE_EXPORT_SYMBOL(rte_flow_dynf_metadata_register)
286 : : int
287 : 0 : rte_flow_dynf_metadata_register(void)
288 : : {
289 : : int offset;
290 : : int flag;
291 : :
292 : : static const struct rte_mbuf_dynfield desc_offs = {
293 : : .name = RTE_MBUF_DYNFIELD_METADATA_NAME,
294 : : .size = sizeof(uint32_t),
295 : : .align = alignof(uint32_t),
296 : : };
297 : : static const struct rte_mbuf_dynflag desc_flag = {
298 : : .name = RTE_MBUF_DYNFLAG_METADATA_NAME,
299 : : };
300 : :
301 : 0 : offset = rte_mbuf_dynfield_register(&desc_offs);
302 [ # # ]: 0 : if (offset < 0)
303 : 0 : goto error;
304 : 0 : flag = rte_mbuf_dynflag_register(&desc_flag);
305 [ # # ]: 0 : if (flag < 0)
306 : 0 : goto error;
307 : 0 : rte_flow_dynf_metadata_offs = offset;
308 [ # # ]: 0 : rte_flow_dynf_metadata_mask = RTE_BIT64(flag);
309 : :
310 : 0 : rte_flow_trace_dynf_metadata_register(offset, RTE_BIT64(flag));
311 : :
312 : 0 : return 0;
313 : :
314 : 0 : error:
315 : 0 : rte_flow_dynf_metadata_offs = -1;
316 : 0 : rte_flow_dynf_metadata_mask = UINT64_C(0);
317 : 0 : return -rte_errno;
318 : : }
319 : :
320 : : static inline void
321 : : fts_enter(struct rte_eth_dev *dev)
322 : : {
323 [ # # # # : 0 : if (!(dev->data->dev_flags & RTE_ETH_DEV_FLOW_OPS_THREAD_SAFE))
# # # # #
# # # # #
# # # # #
# ]
324 : 0 : pthread_mutex_lock(&dev->data->flow_ops_mutex);
325 : : }
326 : :
327 : : static inline void
328 : : fts_exit(struct rte_eth_dev *dev)
329 : : {
330 [ # # # # : 0 : if (!(dev->data->dev_flags & RTE_ETH_DEV_FLOW_OPS_THREAD_SAFE))
# # # # #
# # # # #
# # # # #
# ]
331 : 0 : pthread_mutex_unlock(&dev->data->flow_ops_mutex);
332 : : }
333 : :
334 : : static int
335 : 0 : flow_err(uint16_t port_id, int ret, struct rte_flow_error *error)
336 : : {
337 [ # # ]: 0 : if (ret == 0)
338 : : return 0;
339 [ # # ]: 0 : if (rte_eth_dev_is_removed(port_id))
340 : 0 : return rte_flow_error_set(error, EIO,
341 : : RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
342 : : NULL, rte_strerror(EIO));
343 : : return ret;
344 : : }
345 : :
346 : : /* Get generic flow operations structure from a port. */
347 : : const struct rte_flow_ops *
348 : 0 : rte_flow_ops_get(uint16_t port_id, struct rte_flow_error *error)
349 : : {
350 : 0 : struct rte_eth_dev *dev = &rte_eth_devices[port_id];
351 : : const struct rte_flow_ops *ops;
352 : : int code;
353 : :
354 [ # # ]: 0 : if (unlikely(!rte_eth_dev_is_valid_port(port_id)))
355 : : code = ENODEV;
356 [ # # ]: 0 : else if (unlikely(dev->dev_ops->flow_ops_get == NULL))
357 : : /* flow API not supported with this driver dev_ops */
358 : : code = ENOSYS;
359 : : else
360 : 0 : code = dev->dev_ops->flow_ops_get(dev, &ops);
361 [ # # # # ]: 0 : if (code == 0 && ops == NULL)
362 : : /* flow API not supported with this device */
363 : : code = ENOSYS;
364 : :
365 [ # # ]: 0 : if (code != 0) {
366 : 0 : rte_flow_error_set(error, code, RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
367 : : NULL, rte_strerror(code));
368 : 0 : return NULL;
369 : : }
370 : 0 : return ops;
371 : : }
372 : :
373 : : /* Check whether a flow rule can be created on a given port. */
374 : : RTE_EXPORT_SYMBOL(rte_flow_validate)
375 : : int
376 : 0 : rte_flow_validate(uint16_t port_id,
377 : : const struct rte_flow_attr *attr,
378 : : const struct rte_flow_item pattern[],
379 : : const struct rte_flow_action actions[],
380 : : struct rte_flow_error *error)
381 : : {
382 : 0 : const struct rte_flow_ops *ops = rte_flow_ops_get(port_id, error);
383 : 0 : struct rte_eth_dev *dev = &rte_eth_devices[port_id];
384 : : int ret;
385 : :
386 [ # # # # ]: 0 : if (likely(!!attr) && attr->transfer &&
387 [ # # ]: 0 : (attr->ingress || attr->egress)) {
388 : 0 : return rte_flow_error_set(error, EINVAL,
389 : : RTE_FLOW_ERROR_TYPE_ATTR,
390 : : attr, "cannot use attr ingress/egress with attr transfer");
391 : : }
392 : :
393 [ # # ]: 0 : if (unlikely(!ops))
394 : 0 : return -rte_errno;
395 [ # # ]: 0 : if (likely(!!ops->validate)) {
396 : : fts_enter(dev);
397 : 0 : ret = ops->validate(dev, attr, pattern, actions, error);
398 : : fts_exit(dev);
399 : 0 : ret = flow_err(port_id, ret, error);
400 : :
401 : 0 : rte_flow_trace_validate(port_id, attr, pattern, actions, ret);
402 : :
403 : 0 : return ret;
404 : : }
405 : 0 : return rte_flow_error_set(error, ENOSYS,
406 : : RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
407 : : NULL, rte_strerror(ENOSYS));
408 : : }
409 : :
410 : : /* Create a flow rule on a given port. */
411 : : RTE_EXPORT_SYMBOL(rte_flow_create)
412 : : struct rte_flow *
413 : 0 : rte_flow_create(uint16_t port_id,
414 : : const struct rte_flow_attr *attr,
415 : : const struct rte_flow_item pattern[],
416 : : const struct rte_flow_action actions[],
417 : : struct rte_flow_error *error)
418 : : {
419 : 0 : struct rte_eth_dev *dev = &rte_eth_devices[port_id];
420 : : struct rte_flow *flow;
421 : 0 : const struct rte_flow_ops *ops = rte_flow_ops_get(port_id, error);
422 : :
423 [ # # ]: 0 : if (unlikely(!ops))
424 : : return NULL;
425 [ # # ]: 0 : if (likely(!!ops->create)) {
426 : : fts_enter(dev);
427 : 0 : flow = ops->create(dev, attr, pattern, actions, error);
428 : : fts_exit(dev);
429 [ # # ]: 0 : if (flow == NULL)
430 : 0 : flow_err(port_id, -rte_errno, error);
431 : :
432 : : rte_flow_trace_create(port_id, attr, pattern, actions, flow);
433 : :
434 : 0 : return flow;
435 : : }
436 : 0 : rte_flow_error_set(error, ENOSYS, RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
437 : : NULL, rte_strerror(ENOSYS));
438 : 0 : return NULL;
439 : : }
440 : :
441 : : /* Destroy a flow rule on a given port. */
442 : : RTE_EXPORT_SYMBOL(rte_flow_destroy)
443 : : int
444 : 0 : rte_flow_destroy(uint16_t port_id,
445 : : struct rte_flow *flow,
446 : : struct rte_flow_error *error)
447 : : {
448 : 0 : struct rte_eth_dev *dev = &rte_eth_devices[port_id];
449 : 0 : const struct rte_flow_ops *ops = rte_flow_ops_get(port_id, error);
450 : : int ret;
451 : :
452 [ # # ]: 0 : if (unlikely(!ops))
453 : 0 : return -rte_errno;
454 [ # # ]: 0 : if (likely(!!ops->destroy)) {
455 : : fts_enter(dev);
456 : 0 : ret = ops->destroy(dev, flow, error);
457 : : fts_exit(dev);
458 : 0 : ret = flow_err(port_id, ret, error);
459 : :
460 : : rte_flow_trace_destroy(port_id, flow, ret);
461 : :
462 : 0 : return ret;
463 : : }
464 : 0 : return rte_flow_error_set(error, ENOSYS,
465 : : RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
466 : : NULL, rte_strerror(ENOSYS));
467 : : }
468 : :
469 : : RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_flow_actions_update, 23.07)
470 : : int
471 : 0 : rte_flow_actions_update(uint16_t port_id,
472 : : struct rte_flow *flow,
473 : : const struct rte_flow_action actions[],
474 : : struct rte_flow_error *error)
475 : : {
476 : 0 : struct rte_eth_dev *dev = &rte_eth_devices[port_id];
477 : 0 : const struct rte_flow_ops *ops = rte_flow_ops_get(port_id, error);
478 : : int ret;
479 : :
480 [ # # ]: 0 : if (unlikely(!ops))
481 : 0 : return -rte_errno;
482 [ # # ]: 0 : if (likely(!!ops->actions_update)) {
483 : : fts_enter(dev);
484 : 0 : ret = ops->actions_update(dev, flow, actions, error);
485 : : fts_exit(dev);
486 : :
487 : : rte_flow_trace_actions_update(port_id, flow, actions, ret);
488 : :
489 : 0 : return flow_err(port_id, ret, error);
490 : : }
491 : 0 : return rte_flow_error_set(error, ENOSYS,
492 : : RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
493 : : NULL, rte_strerror(ENOSYS));
494 : : }
495 : :
496 : : /* Destroy all flow rules associated with a port. */
497 : : RTE_EXPORT_SYMBOL(rte_flow_flush)
498 : : int
499 : 0 : rte_flow_flush(uint16_t port_id,
500 : : struct rte_flow_error *error)
501 : : {
502 : 0 : struct rte_eth_dev *dev = &rte_eth_devices[port_id];
503 : 0 : const struct rte_flow_ops *ops = rte_flow_ops_get(port_id, error);
504 : : int ret;
505 : :
506 [ # # ]: 0 : if (unlikely(!ops))
507 : 0 : return -rte_errno;
508 [ # # ]: 0 : if (likely(!!ops->flush)) {
509 : : fts_enter(dev);
510 : 0 : ret = ops->flush(dev, error);
511 : : fts_exit(dev);
512 : 0 : ret = flow_err(port_id, ret, error);
513 : :
514 : 0 : rte_flow_trace_flush(port_id, ret);
515 : :
516 : 0 : return ret;
517 : : }
518 : 0 : return rte_flow_error_set(error, ENOSYS,
519 : : RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
520 : : NULL, rte_strerror(ENOSYS));
521 : : }
522 : :
523 : : /* Query an existing flow rule. */
524 : : RTE_EXPORT_SYMBOL(rte_flow_query)
525 : : int
526 : 0 : rte_flow_query(uint16_t port_id,
527 : : struct rte_flow *flow,
528 : : const struct rte_flow_action *action,
529 : : void *data,
530 : : struct rte_flow_error *error)
531 : : {
532 : 0 : struct rte_eth_dev *dev = &rte_eth_devices[port_id];
533 : 0 : const struct rte_flow_ops *ops = rte_flow_ops_get(port_id, error);
534 : : int ret;
535 : :
536 [ # # ]: 0 : if (!ops)
537 : 0 : return -rte_errno;
538 [ # # ]: 0 : if (likely(!!ops->query)) {
539 : : fts_enter(dev);
540 : 0 : ret = ops->query(dev, flow, action, data, error);
541 : : fts_exit(dev);
542 : 0 : ret = flow_err(port_id, ret, error);
543 : :
544 : : rte_flow_trace_query(port_id, flow, action, data, ret);
545 : :
546 : 0 : return ret;
547 : : }
548 : 0 : return rte_flow_error_set(error, ENOSYS,
549 : : RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
550 : : NULL, rte_strerror(ENOSYS));
551 : : }
552 : :
553 : : /* Restrict ingress traffic to the defined flow rules. */
554 : : RTE_EXPORT_SYMBOL(rte_flow_isolate)
555 : : int
556 : 0 : rte_flow_isolate(uint16_t port_id,
557 : : int set,
558 : : struct rte_flow_error *error)
559 : : {
560 : 0 : struct rte_eth_dev *dev = &rte_eth_devices[port_id];
561 : 0 : const struct rte_flow_ops *ops = rte_flow_ops_get(port_id, error);
562 : : int ret;
563 : :
564 [ # # ]: 0 : if (!ops)
565 : 0 : return -rte_errno;
566 [ # # ]: 0 : if (likely(!!ops->isolate)) {
567 : : fts_enter(dev);
568 : 0 : ret = ops->isolate(dev, set, error);
569 : : fts_exit(dev);
570 : 0 : ret = flow_err(port_id, ret, error);
571 : :
572 : : rte_flow_trace_isolate(port_id, set, ret);
573 : :
574 : 0 : return ret;
575 : : }
576 : 0 : return rte_flow_error_set(error, ENOSYS,
577 : : RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
578 : : NULL, rte_strerror(ENOSYS));
579 : : }
580 : :
581 : : /* Initialize flow error structure. */
582 : : RTE_EXPORT_SYMBOL(rte_flow_error_set)
583 : : int
584 : 0 : rte_flow_error_set(struct rte_flow_error *error,
585 : : int code,
586 : : enum rte_flow_error_type type,
587 : : const void *cause,
588 : : const char *message)
589 : : {
590 [ # # ]: 0 : if (error) {
591 : 0 : *error = (struct rte_flow_error){
592 : : .type = type,
593 : : .cause = cause,
594 : : .message = message,
595 : : };
596 : : }
597 : 0 : rte_errno = code;
598 : 0 : return -code;
599 : : }
600 : :
601 : : /** Pattern item specification types. */
602 : : enum rte_flow_conv_item_spec_type {
603 : : RTE_FLOW_CONV_ITEM_SPEC,
604 : : RTE_FLOW_CONV_ITEM_LAST,
605 : : RTE_FLOW_CONV_ITEM_MASK,
606 : : };
607 : :
608 : : /**
609 : : * Copy pattern item specification.
610 : : *
611 : : * @param[out] buf
612 : : * Output buffer. Can be NULL if @p size is zero.
613 : : * @param size
614 : : * Size of @p buf in bytes.
615 : : * @param[in] item
616 : : * Pattern item to copy specification from.
617 : : * @param type
618 : : * Specification selector for either @p spec, @p last or @p mask.
619 : : *
620 : : * @return
621 : : * Number of bytes needed to store pattern item specification regardless
622 : : * of @p size. @p buf contents are truncated to @p size if not large
623 : : * enough.
624 : : */
625 : : static size_t
626 : 0 : rte_flow_conv_item_spec(void *buf, const size_t size,
627 : : const struct rte_flow_item *item,
628 : : enum rte_flow_conv_item_spec_type type)
629 : : {
630 : : size_t off;
631 : : const void *data =
632 [ # # ]: 0 : type == RTE_FLOW_CONV_ITEM_SPEC ? item->spec :
633 [ # # ]: 0 : type == RTE_FLOW_CONV_ITEM_LAST ? item->last :
634 [ # # ]: 0 : type == RTE_FLOW_CONV_ITEM_MASK ? item->mask :
635 : : NULL;
636 : :
637 [ # # # ]: 0 : switch (item->type) {
638 : : union {
639 : : const struct rte_flow_item_raw *raw;
640 : : const struct rte_flow_item_geneve_opt *geneve_opt;
641 : : } spec;
642 : : union {
643 : : const struct rte_flow_item_raw *raw;
644 : : } last;
645 : : union {
646 : : const struct rte_flow_item_raw *raw;
647 : : } mask;
648 : : union {
649 : : const struct rte_flow_item_raw *raw;
650 : : const struct rte_flow_item_geneve_opt *geneve_opt;
651 : : } src;
652 : : union {
653 : : struct rte_flow_item_raw *raw;
654 : : struct rte_flow_item_geneve_opt *geneve_opt;
655 : : } dst;
656 : : void *deep_src;
657 : : size_t tmp;
658 : :
659 : 0 : case RTE_FLOW_ITEM_TYPE_RAW:
660 : 0 : spec.raw = item->spec;
661 [ # # ]: 0 : last.raw = item->last ? item->last : item->spec;
662 [ # # ]: 0 : mask.raw = item->mask ? item->mask : &rte_flow_item_raw_mask;
663 : : src.raw = data;
664 : : dst.raw = buf;
665 : : rte_memcpy(dst.raw,
666 : 0 : (&(struct rte_flow_item_raw){
667 : 0 : .relative = src.raw->relative,
668 : 0 : .search = src.raw->search,
669 : 0 : .reserved = src.raw->reserved,
670 : 0 : .offset = src.raw->offset,
671 : 0 : .limit = src.raw->limit,
672 : 0 : .length = src.raw->length,
673 : : }),
674 [ # # ]: 0 : size > sizeof(*dst.raw) ? sizeof(*dst.raw) : size);
675 : : off = sizeof(*dst.raw);
676 [ # # # # ]: 0 : if (type == RTE_FLOW_CONV_ITEM_SPEC && spec.raw)
677 : 0 : tmp = spec.raw->length & mask.raw->length;
678 [ # # # # : 0 : else if (type == RTE_FLOW_CONV_ITEM_MASK && spec.raw && last.raw &&
# # ]
679 : 0 : ((spec.raw->length & mask.raw->length) >=
680 [ # # ]: 0 : (last.raw->length & mask.raw->length)))
681 : 0 : tmp = spec.raw->length & mask.raw->length;
682 [ # # ]: 0 : else if (last.raw)
683 : 0 : tmp = last.raw->length & mask.raw->length;
684 : : else
685 : : tmp = 0;
686 : :
687 [ # # ]: 0 : if (tmp) {
688 : : off = RTE_ALIGN_CEIL(off, sizeof(*dst.raw->pattern));
689 [ # # ]: 0 : if (size >= off + tmp) {
690 : 0 : deep_src = (void *)((uintptr_t)dst.raw + off);
691 : 0 : dst.raw->pattern = rte_memcpy(deep_src,
692 [ # # ]: 0 : src.raw->pattern,
693 : : tmp);
694 : : }
695 : : off += tmp;
696 : : }
697 : : break;
698 : 0 : case RTE_FLOW_ITEM_TYPE_GENEVE_OPT:
699 : 0 : off = rte_flow_conv_copy(buf, data, size,
700 : : rte_flow_desc_item, item->type);
701 : 0 : spec.geneve_opt = item->spec;
702 : : src.geneve_opt = data;
703 : : dst.geneve_opt = buf;
704 [ # # ]: 0 : tmp = spec.geneve_opt ? (spec.geneve_opt->option_len << 2) : 0;
705 [ # # # # : 0 : if (size >= off + tmp && tmp > 0 && src.geneve_opt->data) {
# # ]
706 [ # # ]: 0 : deep_src = (void *)((uintptr_t)(dst.geneve_opt + 1));
707 : 0 : dst.geneve_opt->data = rte_memcpy(deep_src,
708 : : src.geneve_opt->data,
709 : : tmp);
710 : : }
711 : : off += tmp;
712 : : break;
713 : 0 : default:
714 : 0 : off = rte_flow_conv_copy(buf, data, size,
715 : : rte_flow_desc_item, item->type);
716 : 0 : break;
717 : : }
718 : 0 : return off;
719 : : }
720 : :
721 : : /**
722 : : * Copy action configuration.
723 : : *
724 : : * @param[out] buf
725 : : * Output buffer. Can be NULL if @p size is zero.
726 : : * @param size
727 : : * Size of @p buf in bytes.
728 : : * @param[in] action
729 : : * Action to copy configuration from.
730 : : *
731 : : * @return
732 : : * Number of bytes needed to store pattern item specification regardless
733 : : * of @p size. @p buf contents are truncated to @p size if not large
734 : : * enough.
735 : : */
736 : : static size_t
737 : 0 : rte_flow_conv_action_conf(void *buf, const size_t size,
738 : : const struct rte_flow_action *action)
739 : : {
740 : : size_t off;
741 : :
742 [ # # # ]: 0 : switch (action->type) {
743 : : union {
744 : : const struct rte_flow_action_rss *rss;
745 : : const struct rte_flow_action_vxlan_encap *vxlan_encap;
746 : : const struct rte_flow_action_nvgre_encap *nvgre_encap;
747 : : } src;
748 : : union {
749 : : struct rte_flow_action_rss *rss;
750 : : struct rte_flow_action_vxlan_encap *vxlan_encap;
751 : : struct rte_flow_action_nvgre_encap *nvgre_encap;
752 : : } dst;
753 : : size_t tmp;
754 : : int ret;
755 : :
756 : 0 : case RTE_FLOW_ACTION_TYPE_RSS:
757 : 0 : src.rss = action->conf;
758 : : dst.rss = buf;
759 : : rte_memcpy(dst.rss,
760 : 0 : (&(struct rte_flow_action_rss){
761 : 0 : .func = src.rss->func,
762 : 0 : .level = src.rss->level,
763 : 0 : .types = src.rss->types,
764 : 0 : .key_len = src.rss->key_len,
765 : 0 : .queue_num = src.rss->queue_num,
766 : : }),
767 [ # # ]: 0 : size > sizeof(*dst.rss) ? sizeof(*dst.rss) : size);
768 : : off = sizeof(*dst.rss);
769 [ # # # # ]: 0 : if (src.rss->key_len && src.rss->key) {
770 : : off = RTE_ALIGN_CEIL(off, sizeof(*dst.rss->key));
771 : 0 : tmp = sizeof(*src.rss->key) * src.rss->key_len;
772 [ # # ]: 0 : if (size >= (uint64_t)off + (uint64_t)tmp)
773 : 0 : dst.rss->key = rte_memcpy
774 [ # # ]: 0 : ((void *)((uintptr_t)dst.rss + off),
775 : : src.rss->key, tmp);
776 : : off += tmp;
777 : : }
778 [ # # ]: 0 : if (src.rss->queue_num) {
779 : 0 : off = RTE_ALIGN_CEIL(off, sizeof(*dst.rss->queue));
780 : 0 : tmp = sizeof(*src.rss->queue) * src.rss->queue_num;
781 [ # # ]: 0 : if (size >= (uint64_t)off + (uint64_t)tmp)
782 : 0 : dst.rss->queue = rte_memcpy
783 : 0 : ((void *)((uintptr_t)dst.rss + off),
784 [ # # ]: 0 : src.rss->queue, tmp);
785 : : off += tmp;
786 : : }
787 : 0 : break;
788 : 0 : case RTE_FLOW_ACTION_TYPE_VXLAN_ENCAP:
789 : : case RTE_FLOW_ACTION_TYPE_NVGRE_ENCAP:
790 : 0 : src.vxlan_encap = action->conf;
791 : : dst.vxlan_encap = buf;
792 : : RTE_BUILD_BUG_ON(sizeof(*src.vxlan_encap) !=
793 : : sizeof(*src.nvgre_encap) ||
794 : : offsetof(struct rte_flow_action_vxlan_encap,
795 : : definition) !=
796 : : offsetof(struct rte_flow_action_nvgre_encap,
797 : : definition));
798 : : off = sizeof(*dst.vxlan_encap);
799 [ # # ]: 0 : if (src.vxlan_encap->definition) {
800 : : off = RTE_ALIGN_CEIL
801 : : (off, sizeof(*dst.vxlan_encap->definition));
802 [ # # ]: 0 : ret = rte_flow_conv
803 : : (RTE_FLOW_CONV_OP_PATTERN,
804 : 0 : (void *)((uintptr_t)dst.vxlan_encap + off),
805 : : size > off ? size - off : 0,
806 : : src.vxlan_encap->definition, NULL);
807 [ # # ]: 0 : if (ret < 0)
808 : 0 : return 0;
809 [ # # ]: 0 : if (size >= off + ret)
810 : 0 : dst.vxlan_encap->definition =
811 : : (void *)((uintptr_t)dst.vxlan_encap +
812 : : off);
813 : : off += ret;
814 : : }
815 : : break;
816 : 0 : default:
817 : 0 : off = rte_flow_conv_copy(buf, action->conf, size,
818 : : rte_flow_desc_action, action->type);
819 : 0 : break;
820 : : }
821 : 0 : return off;
822 : : }
823 : :
824 : : /**
825 : : * Copy a list of pattern items.
826 : : *
827 : : * @param[out] dst
828 : : * Destination buffer. Can be NULL if @p size is zero.
829 : : * @param size
830 : : * Size of @p dst in bytes.
831 : : * @param[in] src
832 : : * Source pattern items.
833 : : * @param num
834 : : * Maximum number of pattern items to process from @p src or 0 to process
835 : : * the entire list. In both cases, processing stops after
836 : : * RTE_FLOW_ITEM_TYPE_END is encountered.
837 : : * @param[out] error
838 : : * Perform verbose error reporting if not NULL.
839 : : *
840 : : * @return
841 : : * A positive value representing the number of bytes needed to store
842 : : * pattern items regardless of @p size on success (@p buf contents are
843 : : * truncated to @p size if not large enough), a negative errno value
844 : : * otherwise and rte_errno is set.
845 : : */
846 : : static int
847 : 0 : rte_flow_conv_pattern(struct rte_flow_item *dst,
848 : : const size_t size,
849 : : const struct rte_flow_item *src,
850 : : unsigned int num,
851 : : struct rte_flow_error *error)
852 : : {
853 : 0 : uintptr_t data = (uintptr_t)dst;
854 : : size_t off;
855 : : size_t ret;
856 : : unsigned int i;
857 : :
858 [ # # ]: 0 : for (i = 0, off = 0; !num || i != num; ++i, ++src, ++dst) {
859 : : /**
860 : : * allow PMD private flow item
861 : : */
862 [ # # # # ]: 0 : if (((int)src->type >= 0) &&
863 : 0 : ((size_t)src->type >= RTE_DIM(rte_flow_desc_item) ||
864 [ # # ]: 0 : !rte_flow_desc_item[src->type].name))
865 : 0 : return rte_flow_error_set
866 : : (error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ITEM, src,
867 : : "cannot convert unknown item type");
868 [ # # ]: 0 : if (size >= off + sizeof(*dst))
869 : 0 : *dst = (struct rte_flow_item){
870 : : .type = src->type,
871 : : };
872 : : off += sizeof(*dst);
873 [ # # ]: 0 : if (!src->type)
874 : 0 : num = i + 1;
875 : : }
876 : : num = i;
877 : 0 : src -= num;
878 : 0 : dst -= num;
879 : : do {
880 [ # # ]: 0 : if (src->spec) {
881 : 0 : off = RTE_ALIGN_CEIL(off, sizeof(double));
882 [ # # ]: 0 : ret = rte_flow_conv_item_spec
883 : 0 : ((void *)(data + off),
884 : : size > off ? size - off : 0, src,
885 : : RTE_FLOW_CONV_ITEM_SPEC);
886 [ # # # # ]: 0 : if (size && size >= off + ret)
887 : 0 : dst->spec = (void *)(data + off);
888 : 0 : off += ret;
889 : :
890 : : }
891 [ # # ]: 0 : if (src->last) {
892 : 0 : off = RTE_ALIGN_CEIL(off, sizeof(double));
893 [ # # ]: 0 : ret = rte_flow_conv_item_spec
894 : 0 : ((void *)(data + off),
895 : : size > off ? size - off : 0, src,
896 : : RTE_FLOW_CONV_ITEM_LAST);
897 [ # # # # ]: 0 : if (size && size >= off + ret)
898 : 0 : dst->last = (void *)(data + off);
899 : 0 : off += ret;
900 : : }
901 [ # # ]: 0 : if (src->mask) {
902 : 0 : off = RTE_ALIGN_CEIL(off, sizeof(double));
903 [ # # ]: 0 : ret = rte_flow_conv_item_spec
904 : 0 : ((void *)(data + off),
905 : : size > off ? size - off : 0, src,
906 : : RTE_FLOW_CONV_ITEM_MASK);
907 [ # # # # ]: 0 : if (size && size >= off + ret)
908 : 0 : dst->mask = (void *)(data + off);
909 : 0 : off += ret;
910 : : }
911 : 0 : ++src;
912 : 0 : ++dst;
913 [ # # ]: 0 : } while (--num);
914 : 0 : return off;
915 : : }
916 : :
917 : : /**
918 : : * Copy a list of actions.
919 : : *
920 : : * @param[out] dst
921 : : * Destination buffer. Can be NULL if @p size is zero.
922 : : * @param size
923 : : * Size of @p dst in bytes.
924 : : * @param[in] src
925 : : * Source actions.
926 : : * @param num
927 : : * Maximum number of actions to process from @p src or 0 to process the
928 : : * entire list. In both cases, processing stops after
929 : : * RTE_FLOW_ACTION_TYPE_END is encountered.
930 : : * @param[out] error
931 : : * Perform verbose error reporting if not NULL.
932 : : *
933 : : * @return
934 : : * A positive value representing the number of bytes needed to store
935 : : * actions regardless of @p size on success (@p buf contents are truncated
936 : : * to @p size if not large enough), a negative errno value otherwise and
937 : : * rte_errno is set.
938 : : */
939 : : static int
940 : 0 : rte_flow_conv_actions(struct rte_flow_action *dst,
941 : : const size_t size,
942 : : const struct rte_flow_action *src,
943 : : unsigned int num,
944 : : struct rte_flow_error *error)
945 : : {
946 : 0 : uintptr_t data = (uintptr_t)dst;
947 : : size_t off;
948 : : size_t ret;
949 : : unsigned int i;
950 : :
951 [ # # ]: 0 : for (i = 0, off = 0; !num || i != num; ++i, ++src, ++dst) {
952 : : /**
953 : : * allow PMD private flow action
954 : : */
955 [ # # # # ]: 0 : if (((int)src->type >= 0) &&
956 : 0 : ((size_t)src->type >= RTE_DIM(rte_flow_desc_action) ||
957 [ # # ]: 0 : !rte_flow_desc_action[src->type].name))
958 : 0 : return rte_flow_error_set
959 : : (error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ACTION,
960 : : src, "cannot convert unknown action type");
961 [ # # ]: 0 : if (size >= off + sizeof(*dst))
962 : 0 : *dst = (struct rte_flow_action){
963 : : .type = src->type,
964 : : };
965 : : off += sizeof(*dst);
966 [ # # ]: 0 : if (!src->type)
967 : 0 : num = i + 1;
968 : : }
969 : : num = i;
970 : 0 : src -= num;
971 : 0 : dst -= num;
972 : : do {
973 [ # # ]: 0 : if (src->type == RTE_FLOW_ACTION_TYPE_INDIRECT) {
974 : : /*
975 : : * Indirect action conf fills the indirect action
976 : : * handler. Copy the action handle directly instead
977 : : * of duplicating the pointer memory.
978 : : */
979 [ # # ]: 0 : if (size)
980 : 0 : dst->conf = src->conf;
981 [ # # ]: 0 : } else if (src->conf) {
982 : 0 : off = RTE_ALIGN_CEIL(off, sizeof(double));
983 [ # # ]: 0 : ret = rte_flow_conv_action_conf
984 : 0 : ((void *)(data + off),
985 : : size > off ? size - off : 0, src);
986 [ # # # # ]: 0 : if (size && size >= off + ret)
987 : 0 : dst->conf = (void *)(data + off);
988 : 0 : off += ret;
989 : : }
990 : 0 : ++src;
991 : 0 : ++dst;
992 [ # # ]: 0 : } while (--num);
993 : 0 : return off;
994 : : }
995 : :
996 : : /**
997 : : * Copy flow rule components.
998 : : *
999 : : * This comprises the flow rule descriptor itself, attributes, pattern and
1000 : : * actions list. NULL components in @p src are skipped.
1001 : : *
1002 : : * @param[out] dst
1003 : : * Destination buffer. Can be NULL if @p size is zero.
1004 : : * @param size
1005 : : * Size of @p dst in bytes.
1006 : : * @param[in] src
1007 : : * Source flow rule descriptor.
1008 : : * @param[out] error
1009 : : * Perform verbose error reporting if not NULL.
1010 : : *
1011 : : * @return
1012 : : * A positive value representing the number of bytes needed to store all
1013 : : * components including the descriptor regardless of @p size on success
1014 : : * (@p buf contents are truncated to @p size if not large enough), a
1015 : : * negative errno value otherwise and rte_errno is set.
1016 : : */
1017 : : static int
1018 : 0 : rte_flow_conv_rule(struct rte_flow_conv_rule *dst,
1019 : : const size_t size,
1020 : : const struct rte_flow_conv_rule *src,
1021 : : struct rte_flow_error *error)
1022 : : {
1023 : : size_t off;
1024 : : int ret;
1025 : :
1026 : : rte_memcpy(dst,
1027 : 0 : (&(struct rte_flow_conv_rule){
1028 : : .attr = NULL,
1029 : : .pattern = NULL,
1030 : : .actions = NULL,
1031 : : }),
1032 [ # # ]: 0 : size > sizeof(*dst) ? sizeof(*dst) : size);
1033 : : off = sizeof(*dst);
1034 [ # # ]: 0 : if (src->attr_ro) {
1035 : : off = RTE_ALIGN_CEIL(off, sizeof(double));
1036 [ # # # # ]: 0 : if (size && size >= off + sizeof(*dst->attr))
1037 : 0 : dst->attr = rte_memcpy
1038 : 0 : ((void *)((uintptr_t)dst + off),
1039 : : src->attr_ro, sizeof(*dst->attr));
1040 : : off += sizeof(*dst->attr);
1041 : : }
1042 [ # # ]: 0 : if (src->pattern_ro) {
1043 : 0 : off = RTE_ALIGN_CEIL(off, sizeof(double));
1044 [ # # ]: 0 : ret = rte_flow_conv_pattern((void *)((uintptr_t)dst + off),
1045 : : size > off ? size - off : 0,
1046 : : src->pattern_ro, 0, error);
1047 [ # # ]: 0 : if (ret < 0)
1048 : : return ret;
1049 [ # # # # ]: 0 : if (size && size >= off + (size_t)ret)
1050 : 0 : dst->pattern = (void *)((uintptr_t)dst + off);
1051 : 0 : off += ret;
1052 : : }
1053 [ # # ]: 0 : if (src->actions_ro) {
1054 : 0 : off = RTE_ALIGN_CEIL(off, sizeof(double));
1055 [ # # ]: 0 : ret = rte_flow_conv_actions((void *)((uintptr_t)dst + off),
1056 : : size > off ? size - off : 0,
1057 : : src->actions_ro, 0, error);
1058 [ # # ]: 0 : if (ret < 0)
1059 : : return ret;
1060 [ # # ]: 0 : if (size >= off + (size_t)ret)
1061 : 0 : dst->actions = (void *)((uintptr_t)dst + off);
1062 : : off += ret;
1063 : : }
1064 : 0 : return off;
1065 : : }
1066 : :
1067 : : /**
1068 : : * Retrieve the name of a pattern item/action type.
1069 : : *
1070 : : * @param is_action
1071 : : * Nonzero when @p src represents an action type instead of a pattern item
1072 : : * type.
1073 : : * @param is_ptr
1074 : : * Nonzero to write string address instead of contents into @p dst.
1075 : : * @param[out] dst
1076 : : * Destination buffer. Can be NULL if @p size is zero.
1077 : : * @param size
1078 : : * Size of @p dst in bytes.
1079 : : * @param[in] src
1080 : : * Depending on @p is_action, source pattern item or action type cast as a
1081 : : * pointer.
1082 : : * @param[out] error
1083 : : * Perform verbose error reporting if not NULL.
1084 : : *
1085 : : * @return
1086 : : * A positive value representing the number of bytes needed to store the
1087 : : * name or its address regardless of @p size on success (@p buf contents
1088 : : * are truncated to @p size if not large enough), a negative errno value
1089 : : * otherwise and rte_errno is set.
1090 : : */
1091 : : static int
1092 : 0 : rte_flow_conv_name(int is_action,
1093 : : int is_ptr,
1094 : : char *dst,
1095 : : const size_t size,
1096 : : const void *src,
1097 : : struct rte_flow_error *error)
1098 : : {
1099 : : struct desc_info {
1100 : : const struct rte_flow_desc_data *data;
1101 : : size_t num;
1102 : : };
1103 : : static const struct desc_info info_rep[2] = {
1104 : : { rte_flow_desc_item, RTE_DIM(rte_flow_desc_item), },
1105 : : { rte_flow_desc_action, RTE_DIM(rte_flow_desc_action), },
1106 : : };
1107 : 0 : const struct desc_info *const info = &info_rep[!!is_action];
1108 : 0 : unsigned int type = (uintptr_t)src;
1109 : :
1110 [ # # ]: 0 : if (type >= info->num)
1111 : 0 : return rte_flow_error_set
1112 : : (error, EINVAL, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
1113 : : "unknown object type to retrieve the name of");
1114 [ # # ]: 0 : if (!is_ptr)
1115 : 0 : return strlcpy(dst, info->data[type].name, size);
1116 [ # # ]: 0 : if (size >= sizeof(const char **))
1117 : 0 : *((const char **)dst) = info->data[type].name;
1118 : : return sizeof(const char **);
1119 : : }
1120 : :
1121 : : /** Helper function to convert flow API objects. */
1122 : : RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_flow_conv, 18.11)
1123 : : int
1124 : 0 : rte_flow_conv(enum rte_flow_conv_op op,
1125 : : void *dst,
1126 : : size_t size,
1127 : : const void *src,
1128 : : struct rte_flow_error *error)
1129 : : {
1130 : : int ret;
1131 : :
1132 [ # # # # : 0 : switch (op) {
# # # # #
# # # # ]
1133 : : const struct rte_flow_attr *attr;
1134 : : const struct rte_flow_item *item;
1135 : :
1136 : : case RTE_FLOW_CONV_OP_NONE:
1137 : : ret = 0;
1138 : : break;
1139 [ # # ]: 0 : case RTE_FLOW_CONV_OP_ATTR:
1140 : : attr = src;
1141 : : if (size > sizeof(*attr))
1142 : : size = sizeof(*attr);
1143 : : rte_memcpy(dst, attr, size);
1144 : : ret = sizeof(*attr);
1145 : : break;
1146 : 0 : case RTE_FLOW_CONV_OP_ITEM:
1147 : 0 : ret = rte_flow_conv_pattern(dst, size, src, 1, error);
1148 : 0 : break;
1149 : 0 : case RTE_FLOW_CONV_OP_ITEM_MASK:
1150 : : item = src;
1151 [ # # ]: 0 : if (item->mask == NULL) {
1152 : 0 : ret = rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_ITEM_MASK,
1153 : : item, "Mask not provided");
1154 : 0 : break;
1155 : : }
1156 : 0 : ret = rte_flow_conv_item_spec(dst, size, src, RTE_FLOW_CONV_ITEM_MASK);
1157 : 0 : break;
1158 : 0 : case RTE_FLOW_CONV_OP_ACTION:
1159 : 0 : ret = rte_flow_conv_actions(dst, size, src, 1, error);
1160 : 0 : break;
1161 : 0 : case RTE_FLOW_CONV_OP_PATTERN:
1162 : 0 : ret = rte_flow_conv_pattern(dst, size, src, 0, error);
1163 : 0 : break;
1164 : 0 : case RTE_FLOW_CONV_OP_ACTIONS:
1165 : 0 : ret = rte_flow_conv_actions(dst, size, src, 0, error);
1166 : 0 : break;
1167 : 0 : case RTE_FLOW_CONV_OP_RULE:
1168 : 0 : ret = rte_flow_conv_rule(dst, size, src, error);
1169 : 0 : break;
1170 : 0 : case RTE_FLOW_CONV_OP_ITEM_NAME:
1171 : 0 : ret = rte_flow_conv_name(0, 0, dst, size, src, error);
1172 : 0 : break;
1173 : 0 : case RTE_FLOW_CONV_OP_ACTION_NAME:
1174 : 0 : ret = rte_flow_conv_name(1, 0, dst, size, src, error);
1175 : 0 : break;
1176 : 0 : case RTE_FLOW_CONV_OP_ITEM_NAME_PTR:
1177 : 0 : ret = rte_flow_conv_name(0, 1, dst, size, src, error);
1178 : 0 : break;
1179 : 0 : case RTE_FLOW_CONV_OP_ACTION_NAME_PTR:
1180 : 0 : ret = rte_flow_conv_name(1, 1, dst, size, src, error);
1181 : 0 : break;
1182 : 0 : default:
1183 : 0 : ret = rte_flow_error_set
1184 : : (error, ENOTSUP, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
1185 : : "unknown object conversion operation");
1186 : : }
1187 : :
1188 : 0 : rte_flow_trace_conv(op, dst, size, src, ret);
1189 : :
1190 : 0 : return ret;
1191 : : }
1192 : :
1193 : : /** Store a full rte_flow description. */
1194 : : RTE_EXPORT_SYMBOL(rte_flow_copy)
1195 : : size_t
1196 : 0 : rte_flow_copy(struct rte_flow_desc *desc, size_t len,
1197 : : const struct rte_flow_attr *attr,
1198 : : const struct rte_flow_item *items,
1199 : : const struct rte_flow_action *actions)
1200 : : {
1201 : : /*
1202 : : * Overlap struct rte_flow_conv with struct rte_flow_desc in order
1203 : : * to convert the former to the latter without wasting space.
1204 : : */
1205 : : struct rte_flow_conv_rule *dst =
1206 : : len ?
1207 : 0 : (void *)((uintptr_t)desc +
1208 : : (offsetof(struct rte_flow_desc, actions) -
1209 [ # # ]: 0 : offsetof(struct rte_flow_conv_rule, actions))) :
1210 : : NULL;
1211 : 0 : size_t dst_size =
1212 : : len > sizeof(*desc) - sizeof(*dst) ?
1213 : 0 : len - (sizeof(*desc) - sizeof(*dst)) :
1214 : : 0;
1215 : 0 : struct rte_flow_conv_rule src = {
1216 : : .attr_ro = NULL,
1217 : : .pattern_ro = items,
1218 : : .actions_ro = actions,
1219 : : };
1220 : : int ret;
1221 : :
1222 : : RTE_BUILD_BUG_ON(sizeof(struct rte_flow_desc) <
1223 : : sizeof(struct rte_flow_conv_rule));
1224 [ # # ]: 0 : if (dst_size &&
1225 [ # # ]: 0 : (&dst->pattern != &desc->items ||
1226 [ # # ]: 0 : &dst->actions != &desc->actions ||
1227 [ # # ]: 0 : (uintptr_t)(dst + 1) != (uintptr_t)(desc + 1))) {
1228 : 0 : rte_errno = EINVAL;
1229 : 0 : return 0;
1230 : : }
1231 : 0 : ret = rte_flow_conv(RTE_FLOW_CONV_OP_RULE, dst, dst_size, &src, NULL);
1232 [ # # ]: 0 : if (ret < 0)
1233 : : return 0;
1234 : 0 : ret += sizeof(*desc) - sizeof(*dst);
1235 : : rte_memcpy(desc,
1236 [ # # ]: 0 : (&(struct rte_flow_desc){
1237 : : .size = ret,
1238 : : .attr = *attr,
1239 : 0 : .items = dst_size ? dst->pattern : NULL,
1240 [ # # ]: 0 : .actions = dst_size ? dst->actions : NULL,
1241 : : }),
1242 [ # # ]: 0 : len > sizeof(*desc) ? sizeof(*desc) : len);
1243 : :
1244 : 0 : rte_flow_trace_copy(desc, len, attr, items, actions, ret);
1245 : :
1246 : 0 : return ret;
1247 : : }
1248 : :
1249 : : RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_flow_dev_dump, 20.02)
1250 : : int
1251 : 0 : rte_flow_dev_dump(uint16_t port_id, struct rte_flow *flow,
1252 : : FILE *file, struct rte_flow_error *error)
1253 : : {
1254 : 0 : struct rte_eth_dev *dev = &rte_eth_devices[port_id];
1255 : 0 : const struct rte_flow_ops *ops = rte_flow_ops_get(port_id, error);
1256 : : int ret;
1257 : :
1258 [ # # ]: 0 : if (unlikely(!ops))
1259 : 0 : return -rte_errno;
1260 [ # # ]: 0 : if (likely(!!ops->dev_dump)) {
1261 : : fts_enter(dev);
1262 : 0 : ret = ops->dev_dump(dev, flow, file, error);
1263 : : fts_exit(dev);
1264 : 0 : return flow_err(port_id, ret, error);
1265 : : }
1266 : 0 : return rte_flow_error_set(error, ENOSYS,
1267 : : RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
1268 : : NULL, rte_strerror(ENOSYS));
1269 : : }
1270 : :
1271 : : RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_flow_get_aged_flows, 20.05)
1272 : : int
1273 : 0 : rte_flow_get_aged_flows(uint16_t port_id, void **contexts,
1274 : : uint32_t nb_contexts, struct rte_flow_error *error)
1275 : : {
1276 : 0 : struct rte_eth_dev *dev = &rte_eth_devices[port_id];
1277 : 0 : const struct rte_flow_ops *ops = rte_flow_ops_get(port_id, error);
1278 : : int ret;
1279 : :
1280 [ # # ]: 0 : if (unlikely(!ops))
1281 : 0 : return -rte_errno;
1282 [ # # ]: 0 : if (likely(!!ops->get_aged_flows)) {
1283 : : fts_enter(dev);
1284 : 0 : ret = ops->get_aged_flows(dev, contexts, nb_contexts, error);
1285 : : fts_exit(dev);
1286 : 0 : ret = flow_err(port_id, ret, error);
1287 : :
1288 : : rte_flow_trace_get_aged_flows(port_id, contexts, nb_contexts, ret);
1289 : :
1290 : 0 : return ret;
1291 : : }
1292 : 0 : return rte_flow_error_set(error, ENOTSUP,
1293 : : RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
1294 : : NULL, rte_strerror(ENOTSUP));
1295 : : }
1296 : :
1297 : : RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_flow_get_q_aged_flows, 22.11)
1298 : : int
1299 : 0 : rte_flow_get_q_aged_flows(uint16_t port_id, uint32_t queue_id, void **contexts,
1300 : : uint32_t nb_contexts, struct rte_flow_error *error)
1301 : : {
1302 : 0 : struct rte_eth_dev *dev = &rte_eth_devices[port_id];
1303 : 0 : const struct rte_flow_ops *ops = rte_flow_ops_get(port_id, error);
1304 : : int ret;
1305 : :
1306 [ # # ]: 0 : if (unlikely(!ops))
1307 : 0 : return -rte_errno;
1308 [ # # ]: 0 : if (likely(!!ops->get_q_aged_flows)) {
1309 : : fts_enter(dev);
1310 : 0 : ret = ops->get_q_aged_flows(dev, queue_id, contexts,
1311 : : nb_contexts, error);
1312 : : fts_exit(dev);
1313 : 0 : ret = flow_err(port_id, ret, error);
1314 : :
1315 : : rte_flow_trace_get_q_aged_flows(port_id, queue_id, contexts,
1316 : : nb_contexts, ret);
1317 : :
1318 : 0 : return ret;
1319 : : }
1320 : 0 : return rte_flow_error_set(error, ENOTSUP,
1321 : : RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
1322 : : NULL, rte_strerror(ENOTSUP));
1323 : : }
1324 : :
1325 : : RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_flow_action_handle_create, 21.05)
1326 : : struct rte_flow_action_handle *
1327 : 0 : rte_flow_action_handle_create(uint16_t port_id,
1328 : : const struct rte_flow_indir_action_conf *conf,
1329 : : const struct rte_flow_action *action,
1330 : : struct rte_flow_error *error)
1331 : : {
1332 : : struct rte_flow_action_handle *handle;
1333 : 0 : const struct rte_flow_ops *ops = rte_flow_ops_get(port_id, error);
1334 : :
1335 [ # # ]: 0 : if (unlikely(!ops))
1336 : : return NULL;
1337 [ # # ]: 0 : if (unlikely(!ops->action_handle_create)) {
1338 : 0 : rte_flow_error_set(error, ENOSYS,
1339 : : RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
1340 : : rte_strerror(ENOSYS));
1341 : 0 : return NULL;
1342 : : }
1343 : 0 : handle = ops->action_handle_create(&rte_eth_devices[port_id],
1344 : : conf, action, error);
1345 [ # # ]: 0 : if (handle == NULL)
1346 : 0 : flow_err(port_id, -rte_errno, error);
1347 : :
1348 : : rte_flow_trace_action_handle_create(port_id, conf, action, handle);
1349 : :
1350 : : return handle;
1351 : : }
1352 : :
1353 : : RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_flow_action_handle_destroy, 21.05)
1354 : : int
1355 : 0 : rte_flow_action_handle_destroy(uint16_t port_id,
1356 : : struct rte_flow_action_handle *handle,
1357 : : struct rte_flow_error *error)
1358 : : {
1359 : : int ret;
1360 : 0 : const struct rte_flow_ops *ops = rte_flow_ops_get(port_id, error);
1361 : :
1362 [ # # ]: 0 : if (unlikely(!ops))
1363 : 0 : return -rte_errno;
1364 [ # # ]: 0 : if (unlikely(!ops->action_handle_destroy))
1365 : 0 : return rte_flow_error_set(error, ENOSYS,
1366 : : RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
1367 : : NULL, rte_strerror(ENOSYS));
1368 : 0 : ret = ops->action_handle_destroy(&rte_eth_devices[port_id],
1369 : : handle, error);
1370 : 0 : ret = flow_err(port_id, ret, error);
1371 : :
1372 : : rte_flow_trace_action_handle_destroy(port_id, handle, ret);
1373 : :
1374 : 0 : return ret;
1375 : : }
1376 : :
1377 : : RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_flow_action_handle_update, 21.05)
1378 : : int
1379 : 0 : rte_flow_action_handle_update(uint16_t port_id,
1380 : : struct rte_flow_action_handle *handle,
1381 : : const void *update,
1382 : : struct rte_flow_error *error)
1383 : : {
1384 : : int ret;
1385 : 0 : const struct rte_flow_ops *ops = rte_flow_ops_get(port_id, error);
1386 : :
1387 [ # # ]: 0 : if (unlikely(!ops))
1388 : 0 : return -rte_errno;
1389 [ # # ]: 0 : if (unlikely(!ops->action_handle_update))
1390 : 0 : return rte_flow_error_set(error, ENOSYS,
1391 : : RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
1392 : : NULL, rte_strerror(ENOSYS));
1393 : 0 : ret = ops->action_handle_update(&rte_eth_devices[port_id], handle,
1394 : : update, error);
1395 : 0 : ret = flow_err(port_id, ret, error);
1396 : :
1397 : : rte_flow_trace_action_handle_update(port_id, handle, update, ret);
1398 : :
1399 : 0 : return ret;
1400 : : }
1401 : :
1402 : : RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_flow_action_handle_query, 21.05)
1403 : : int
1404 : 0 : rte_flow_action_handle_query(uint16_t port_id,
1405 : : const struct rte_flow_action_handle *handle,
1406 : : void *data,
1407 : : struct rte_flow_error *error)
1408 : : {
1409 : : int ret;
1410 : 0 : const struct rte_flow_ops *ops = rte_flow_ops_get(port_id, error);
1411 : :
1412 [ # # ]: 0 : if (unlikely(!ops))
1413 : 0 : return -rte_errno;
1414 [ # # ]: 0 : if (unlikely(!ops->action_handle_query))
1415 : 0 : return rte_flow_error_set(error, ENOSYS,
1416 : : RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
1417 : : NULL, rte_strerror(ENOSYS));
1418 : 0 : ret = ops->action_handle_query(&rte_eth_devices[port_id], handle,
1419 : : data, error);
1420 : 0 : ret = flow_err(port_id, ret, error);
1421 : :
1422 : : rte_flow_trace_action_handle_query(port_id, handle, data, ret);
1423 : :
1424 : 0 : return ret;
1425 : : }
1426 : :
1427 : : RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_flow_tunnel_decap_set, 20.11)
1428 : : int
1429 : 0 : rte_flow_tunnel_decap_set(uint16_t port_id,
1430 : : struct rte_flow_tunnel *tunnel,
1431 : : struct rte_flow_action **actions,
1432 : : uint32_t *num_of_actions,
1433 : : struct rte_flow_error *error)
1434 : : {
1435 : 0 : struct rte_eth_dev *dev = &rte_eth_devices[port_id];
1436 : 0 : const struct rte_flow_ops *ops = rte_flow_ops_get(port_id, error);
1437 : : int ret;
1438 : :
1439 [ # # ]: 0 : if (unlikely(!ops))
1440 : 0 : return -rte_errno;
1441 [ # # ]: 0 : if (likely(!!ops->tunnel_decap_set)) {
1442 : 0 : ret = flow_err(port_id,
1443 : : ops->tunnel_decap_set(dev, tunnel, actions,
1444 : : num_of_actions, error),
1445 : : error);
1446 : :
1447 : 0 : rte_flow_trace_tunnel_decap_set(port_id, tunnel, actions,
1448 : : num_of_actions, ret);
1449 : :
1450 : 0 : return ret;
1451 : : }
1452 : 0 : return rte_flow_error_set(error, ENOTSUP,
1453 : : RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
1454 : : NULL, rte_strerror(ENOTSUP));
1455 : : }
1456 : :
1457 : : RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_flow_tunnel_match, 20.11)
1458 : : int
1459 : 0 : rte_flow_tunnel_match(uint16_t port_id,
1460 : : struct rte_flow_tunnel *tunnel,
1461 : : struct rte_flow_item **items,
1462 : : uint32_t *num_of_items,
1463 : : struct rte_flow_error *error)
1464 : : {
1465 : 0 : struct rte_eth_dev *dev = &rte_eth_devices[port_id];
1466 : 0 : const struct rte_flow_ops *ops = rte_flow_ops_get(port_id, error);
1467 : : int ret;
1468 : :
1469 [ # # ]: 0 : if (unlikely(!ops))
1470 : 0 : return -rte_errno;
1471 [ # # ]: 0 : if (likely(!!ops->tunnel_match)) {
1472 : 0 : ret = flow_err(port_id,
1473 : : ops->tunnel_match(dev, tunnel, items,
1474 : : num_of_items, error),
1475 : : error);
1476 : :
1477 : 0 : rte_flow_trace_tunnel_match(port_id, tunnel, items, num_of_items,
1478 : : ret);
1479 : :
1480 : 0 : return ret;
1481 : : }
1482 : 0 : return rte_flow_error_set(error, ENOTSUP,
1483 : : RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
1484 : : NULL, rte_strerror(ENOTSUP));
1485 : : }
1486 : :
1487 : : RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_flow_get_restore_info, 20.11)
1488 : : int
1489 : 0 : rte_flow_get_restore_info(uint16_t port_id,
1490 : : struct rte_mbuf *m,
1491 : : struct rte_flow_restore_info *restore_info,
1492 : : struct rte_flow_error *error)
1493 : : {
1494 : 0 : struct rte_eth_dev *dev = &rte_eth_devices[port_id];
1495 : 0 : const struct rte_flow_ops *ops = rte_flow_ops_get(port_id, error);
1496 : : int ret;
1497 : :
1498 [ # # ]: 0 : if (unlikely(!ops))
1499 : 0 : return -rte_errno;
1500 [ # # ]: 0 : if (likely(!!ops->get_restore_info)) {
1501 : 0 : ret = flow_err(port_id,
1502 : : ops->get_restore_info(dev, m, restore_info,
1503 : : error),
1504 : : error);
1505 : :
1506 : : rte_flow_trace_get_restore_info(port_id, m, restore_info, ret);
1507 : :
1508 : 0 : return ret;
1509 : : }
1510 : 0 : return rte_flow_error_set(error, ENOTSUP,
1511 : : RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
1512 : : NULL, rte_strerror(ENOTSUP));
1513 : : }
1514 : :
1515 : : static struct {
1516 : : const struct rte_mbuf_dynflag desc;
1517 : : uint64_t value;
1518 : : } flow_restore_info_dynflag = {
1519 : : .desc = { .name = "RTE_MBUF_F_RX_RESTORE_INFO", },
1520 : : };
1521 : :
1522 : : RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_flow_restore_info_dynflag, 23.07)
1523 : : uint64_t
1524 : 0 : rte_flow_restore_info_dynflag(void)
1525 : : {
1526 : 0 : return flow_restore_info_dynflag.value;
1527 : : }
1528 : :
1529 : : int
1530 : 0 : rte_flow_restore_info_dynflag_register(void)
1531 : : {
1532 [ # # ]: 0 : if (flow_restore_info_dynflag.value == 0) {
1533 : 0 : int offset = rte_mbuf_dynflag_register(&flow_restore_info_dynflag.desc);
1534 : :
1535 [ # # ]: 0 : if (offset < 0)
1536 : : return -1;
1537 : 0 : flow_restore_info_dynflag.value = RTE_BIT64(offset);
1538 : : }
1539 : :
1540 : : return 0;
1541 : : }
1542 : :
1543 : : RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_flow_tunnel_action_decap_release, 20.11)
1544 : : int
1545 : 0 : rte_flow_tunnel_action_decap_release(uint16_t port_id,
1546 : : struct rte_flow_action *actions,
1547 : : uint32_t num_of_actions,
1548 : : struct rte_flow_error *error)
1549 : : {
1550 : 0 : struct rte_eth_dev *dev = &rte_eth_devices[port_id];
1551 : 0 : const struct rte_flow_ops *ops = rte_flow_ops_get(port_id, error);
1552 : : int ret;
1553 : :
1554 [ # # ]: 0 : if (unlikely(!ops))
1555 : 0 : return -rte_errno;
1556 [ # # ]: 0 : if (likely(!!ops->tunnel_action_decap_release)) {
1557 : 0 : ret = flow_err(port_id,
1558 : : ops->tunnel_action_decap_release(dev, actions,
1559 : : num_of_actions,
1560 : : error),
1561 : : error);
1562 : :
1563 : 0 : rte_flow_trace_tunnel_action_decap_release(port_id, actions,
1564 : : num_of_actions, ret);
1565 : :
1566 : 0 : return ret;
1567 : : }
1568 : 0 : return rte_flow_error_set(error, ENOTSUP,
1569 : : RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
1570 : : NULL, rte_strerror(ENOTSUP));
1571 : : }
1572 : :
1573 : : RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_flow_tunnel_item_release, 20.11)
1574 : : int
1575 : 0 : rte_flow_tunnel_item_release(uint16_t port_id,
1576 : : struct rte_flow_item *items,
1577 : : uint32_t num_of_items,
1578 : : struct rte_flow_error *error)
1579 : : {
1580 : 0 : struct rte_eth_dev *dev = &rte_eth_devices[port_id];
1581 : 0 : const struct rte_flow_ops *ops = rte_flow_ops_get(port_id, error);
1582 : : int ret;
1583 : :
1584 [ # # ]: 0 : if (unlikely(!ops))
1585 : 0 : return -rte_errno;
1586 [ # # ]: 0 : if (likely(!!ops->tunnel_item_release)) {
1587 : 0 : ret = flow_err(port_id,
1588 : : ops->tunnel_item_release(dev, items,
1589 : : num_of_items, error),
1590 : : error);
1591 : :
1592 : 0 : rte_flow_trace_tunnel_item_release(port_id, items, num_of_items, ret);
1593 : :
1594 : 0 : return ret;
1595 : : }
1596 : 0 : return rte_flow_error_set(error, ENOTSUP,
1597 : : RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
1598 : : NULL, rte_strerror(ENOTSUP));
1599 : : }
1600 : :
1601 : : RTE_EXPORT_SYMBOL(rte_flow_pick_transfer_proxy)
1602 : : int
1603 : 0 : rte_flow_pick_transfer_proxy(uint16_t port_id, uint16_t *proxy_port_id,
1604 : : struct rte_flow_error *error)
1605 : : {
1606 : 0 : const struct rte_flow_ops *ops = rte_flow_ops_get(port_id, error);
1607 : : struct rte_eth_dev *dev;
1608 : : int ret;
1609 : :
1610 [ # # ]: 0 : if (unlikely(ops == NULL))
1611 : 0 : return -rte_errno;
1612 : :
1613 [ # # ]: 0 : if (ops->pick_transfer_proxy == NULL) {
1614 : 0 : *proxy_port_id = port_id;
1615 : 0 : return 0;
1616 : : }
1617 : :
1618 : 0 : dev = &rte_eth_devices[port_id];
1619 : :
1620 : 0 : ret = flow_err(port_id,
1621 : : ops->pick_transfer_proxy(dev, proxy_port_id, error),
1622 : : error);
1623 : :
1624 : : rte_flow_trace_pick_transfer_proxy(port_id, proxy_port_id, ret);
1625 : :
1626 : 0 : return ret;
1627 : : }
1628 : :
1629 : : RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_flow_flex_item_create, 21.11)
1630 : : struct rte_flow_item_flex_handle *
1631 : 0 : rte_flow_flex_item_create(uint16_t port_id,
1632 : : const struct rte_flow_item_flex_conf *conf,
1633 : : struct rte_flow_error *error)
1634 : : {
1635 : 0 : struct rte_eth_dev *dev = &rte_eth_devices[port_id];
1636 : 0 : const struct rte_flow_ops *ops = rte_flow_ops_get(port_id, error);
1637 : : struct rte_flow_item_flex_handle *handle;
1638 : :
1639 [ # # ]: 0 : if (unlikely(!ops))
1640 : : return NULL;
1641 [ # # ]: 0 : if (unlikely(!ops->flex_item_create)) {
1642 : 0 : rte_flow_error_set(error, ENOTSUP,
1643 : : RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
1644 : : NULL, rte_strerror(ENOTSUP));
1645 : 0 : return NULL;
1646 : : }
1647 : 0 : handle = ops->flex_item_create(dev, conf, error);
1648 [ # # ]: 0 : if (handle == NULL)
1649 : 0 : flow_err(port_id, -rte_errno, error);
1650 : :
1651 : 0 : rte_flow_trace_flex_item_create(port_id, conf, handle);
1652 : :
1653 : 0 : return handle;
1654 : : }
1655 : :
1656 : : RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_flow_flex_item_release, 21.11)
1657 : : int
1658 : 0 : rte_flow_flex_item_release(uint16_t port_id,
1659 : : const struct rte_flow_item_flex_handle *handle,
1660 : : struct rte_flow_error *error)
1661 : : {
1662 : : int ret;
1663 : 0 : struct rte_eth_dev *dev = &rte_eth_devices[port_id];
1664 : 0 : const struct rte_flow_ops *ops = rte_flow_ops_get(port_id, error);
1665 : :
1666 [ # # # # ]: 0 : if (unlikely(!ops || !ops->flex_item_release))
1667 : 0 : return rte_flow_error_set(error, ENOTSUP,
1668 : : RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
1669 : : NULL, rte_strerror(ENOTSUP));
1670 : 0 : ret = ops->flex_item_release(dev, handle, error);
1671 : 0 : ret = flow_err(port_id, ret, error);
1672 : :
1673 : 0 : rte_flow_trace_flex_item_release(port_id, handle, ret);
1674 : :
1675 : 0 : return ret;
1676 : : }
1677 : :
1678 : : RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_flow_info_get, 22.03)
1679 : : int
1680 : 0 : rte_flow_info_get(uint16_t port_id,
1681 : : struct rte_flow_port_info *port_info,
1682 : : struct rte_flow_queue_info *queue_info,
1683 : : struct rte_flow_error *error)
1684 : : {
1685 : 0 : struct rte_eth_dev *dev = &rte_eth_devices[port_id];
1686 : 0 : const struct rte_flow_ops *ops = rte_flow_ops_get(port_id, error);
1687 : : int ret;
1688 : :
1689 [ # # ]: 0 : if (unlikely(!ops))
1690 : 0 : return -rte_errno;
1691 [ # # ]: 0 : if (dev->data->dev_configured == 0) {
1692 : 0 : FLOW_LOG(INFO,
1693 : : "Device with port_id=%"PRIu16" is not configured.",
1694 : : port_id);
1695 : 0 : return -EINVAL;
1696 : : }
1697 [ # # ]: 0 : if (port_info == NULL) {
1698 : 0 : FLOW_LOG(ERR, "Port %"PRIu16" info is NULL.", port_id);
1699 : 0 : return -EINVAL;
1700 : : }
1701 [ # # ]: 0 : if (likely(!!ops->info_get)) {
1702 : 0 : ret = flow_err(port_id,
1703 : : ops->info_get(dev, port_info, queue_info, error),
1704 : : error);
1705 : :
1706 : 0 : rte_flow_trace_info_get(port_id, port_info, queue_info, ret);
1707 : :
1708 : 0 : return ret;
1709 : : }
1710 : 0 : return rte_flow_error_set(error, ENOTSUP,
1711 : : RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
1712 : : NULL, rte_strerror(ENOTSUP));
1713 : : }
1714 : :
1715 : : RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_flow_configure, 22.03)
1716 : : int
1717 : 0 : rte_flow_configure(uint16_t port_id,
1718 : : const struct rte_flow_port_attr *port_attr,
1719 : : uint16_t nb_queue,
1720 : : const struct rte_flow_queue_attr *queue_attr[],
1721 : : struct rte_flow_error *error)
1722 : : {
1723 : 0 : struct rte_eth_dev *dev = &rte_eth_devices[port_id];
1724 : 0 : const struct rte_flow_ops *ops = rte_flow_ops_get(port_id, error);
1725 : : int ret;
1726 : :
1727 [ # # ]: 0 : if (unlikely(!ops))
1728 : 0 : return -rte_errno;
1729 [ # # ]: 0 : if (dev->data->dev_configured == 0) {
1730 : 0 : FLOW_LOG(INFO,
1731 : : "Device with port_id=%"PRIu16" is not configured.",
1732 : : port_id);
1733 : 0 : goto error;
1734 : : }
1735 [ # # ]: 0 : if (dev->data->dev_started != 0) {
1736 : 0 : FLOW_LOG(INFO,
1737 : : "Device with port_id=%"PRIu16" already started.",
1738 : : port_id);
1739 : 0 : goto error;
1740 : : }
1741 [ # # ]: 0 : if (port_attr == NULL) {
1742 : 0 : FLOW_LOG(ERR, "Port %"PRIu16" info is NULL.", port_id);
1743 : 0 : goto error;
1744 : : }
1745 [ # # ]: 0 : if (queue_attr == NULL) {
1746 : 0 : FLOW_LOG(ERR, "Port %"PRIu16" queue info is NULL.", port_id);
1747 : 0 : goto error;
1748 : : }
1749 [ # # # # ]: 0 : if ((port_attr->flags & RTE_FLOW_PORT_FLAG_SHARE_INDIRECT) &&
1750 : 0 : !rte_eth_dev_is_valid_port(port_attr->host_port_id)) {
1751 : 0 : return rte_flow_error_set(error, ENODEV,
1752 : : RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
1753 : : NULL, rte_strerror(ENODEV));
1754 : : }
1755 [ # # ]: 0 : if (likely(!!ops->configure)) {
1756 : 0 : ret = ops->configure(dev, port_attr, nb_queue, queue_attr, error);
1757 [ # # ]: 0 : if (ret == 0)
1758 : 0 : dev->data->flow_configured = 1;
1759 : 0 : ret = flow_err(port_id, ret, error);
1760 : :
1761 : 0 : rte_flow_trace_configure(port_id, port_attr, nb_queue, queue_attr, ret);
1762 : :
1763 : 0 : return ret;
1764 : : }
1765 : 0 : return rte_flow_error_set(error, ENOTSUP,
1766 : : RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
1767 : : NULL, rte_strerror(ENOTSUP));
1768 : 0 : error:
1769 : 0 : return rte_flow_error_set(error, EINVAL,
1770 : : RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
1771 : : NULL, rte_strerror(EINVAL));
1772 : : }
1773 : :
1774 : : RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_flow_pattern_template_create, 22.03)
1775 : : struct rte_flow_pattern_template *
1776 : 0 : rte_flow_pattern_template_create(uint16_t port_id,
1777 : : const struct rte_flow_pattern_template_attr *template_attr,
1778 : : const struct rte_flow_item pattern[],
1779 : : struct rte_flow_error *error)
1780 : : {
1781 : 0 : struct rte_eth_dev *dev = &rte_eth_devices[port_id];
1782 : 0 : const struct rte_flow_ops *ops = rte_flow_ops_get(port_id, error);
1783 : : struct rte_flow_pattern_template *template;
1784 : :
1785 [ # # ]: 0 : if (unlikely(!ops))
1786 : : return NULL;
1787 [ # # ]: 0 : if (dev->data->flow_configured == 0) {
1788 : 0 : FLOW_LOG(INFO,
1789 : : "Flow engine on port_id=%"PRIu16" is not configured.",
1790 : : port_id);
1791 : 0 : rte_flow_error_set(error, EINVAL,
1792 : : RTE_FLOW_ERROR_TYPE_STATE,
1793 : : NULL, rte_strerror(EINVAL));
1794 : 0 : return NULL;
1795 : : }
1796 [ # # ]: 0 : if (template_attr == NULL) {
1797 : 0 : FLOW_LOG(ERR,
1798 : : "Port %"PRIu16" template attr is NULL.",
1799 : : port_id);
1800 : 0 : rte_flow_error_set(error, EINVAL,
1801 : : RTE_FLOW_ERROR_TYPE_ATTR,
1802 : : NULL, rte_strerror(EINVAL));
1803 : 0 : return NULL;
1804 : : }
1805 [ # # ]: 0 : if (pattern == NULL) {
1806 : 0 : FLOW_LOG(ERR,
1807 : : "Port %"PRIu16" pattern is NULL.",
1808 : : port_id);
1809 : 0 : rte_flow_error_set(error, EINVAL,
1810 : : RTE_FLOW_ERROR_TYPE_ATTR,
1811 : : NULL, rte_strerror(EINVAL));
1812 : 0 : return NULL;
1813 : : }
1814 [ # # ]: 0 : if (likely(!!ops->pattern_template_create)) {
1815 : 0 : template = ops->pattern_template_create(dev, template_attr,
1816 : : pattern, error);
1817 [ # # ]: 0 : if (template == NULL)
1818 : 0 : flow_err(port_id, -rte_errno, error);
1819 : :
1820 : 0 : rte_flow_trace_pattern_template_create(port_id, template_attr,
1821 : : pattern, template);
1822 : :
1823 : 0 : return template;
1824 : : }
1825 : 0 : rte_flow_error_set(error, ENOTSUP,
1826 : : RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
1827 : : NULL, rte_strerror(ENOTSUP));
1828 : 0 : return NULL;
1829 : : }
1830 : :
1831 : : RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_flow_pattern_template_destroy, 22.03)
1832 : : int
1833 : 0 : rte_flow_pattern_template_destroy(uint16_t port_id,
1834 : : struct rte_flow_pattern_template *pattern_template,
1835 : : struct rte_flow_error *error)
1836 : : {
1837 : 0 : struct rte_eth_dev *dev = &rte_eth_devices[port_id];
1838 : 0 : const struct rte_flow_ops *ops = rte_flow_ops_get(port_id, error);
1839 : : int ret;
1840 : :
1841 [ # # ]: 0 : if (unlikely(!ops))
1842 : 0 : return -rte_errno;
1843 [ # # ]: 0 : if (unlikely(pattern_template == NULL))
1844 : : return 0;
1845 [ # # ]: 0 : if (likely(!!ops->pattern_template_destroy)) {
1846 : 0 : ret = flow_err(port_id,
1847 : : ops->pattern_template_destroy(dev,
1848 : : pattern_template,
1849 : : error),
1850 : : error);
1851 : :
1852 : 0 : rte_flow_trace_pattern_template_destroy(port_id, pattern_template,
1853 : : ret);
1854 : :
1855 : 0 : return ret;
1856 : : }
1857 : 0 : return rte_flow_error_set(error, ENOTSUP,
1858 : : RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
1859 : : NULL, rte_strerror(ENOTSUP));
1860 : : }
1861 : :
1862 : : RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_flow_actions_template_create, 22.03)
1863 : : struct rte_flow_actions_template *
1864 : 0 : rte_flow_actions_template_create(uint16_t port_id,
1865 : : const struct rte_flow_actions_template_attr *template_attr,
1866 : : const struct rte_flow_action actions[],
1867 : : const struct rte_flow_action masks[],
1868 : : struct rte_flow_error *error)
1869 : : {
1870 : 0 : struct rte_eth_dev *dev = &rte_eth_devices[port_id];
1871 : 0 : const struct rte_flow_ops *ops = rte_flow_ops_get(port_id, error);
1872 : : struct rte_flow_actions_template *template;
1873 : :
1874 [ # # ]: 0 : if (unlikely(!ops))
1875 : : return NULL;
1876 [ # # ]: 0 : if (dev->data->flow_configured == 0) {
1877 : 0 : FLOW_LOG(INFO,
1878 : : "Flow engine on port_id=%"PRIu16" is not configured.",
1879 : : port_id);
1880 : 0 : rte_flow_error_set(error, EINVAL,
1881 : : RTE_FLOW_ERROR_TYPE_STATE,
1882 : : NULL, rte_strerror(EINVAL));
1883 : 0 : return NULL;
1884 : : }
1885 [ # # ]: 0 : if (template_attr == NULL) {
1886 : 0 : FLOW_LOG(ERR,
1887 : : "Port %"PRIu16" template attr is NULL.",
1888 : : port_id);
1889 : 0 : rte_flow_error_set(error, EINVAL,
1890 : : RTE_FLOW_ERROR_TYPE_ATTR,
1891 : : NULL, rte_strerror(EINVAL));
1892 : 0 : return NULL;
1893 : : }
1894 [ # # ]: 0 : if (actions == NULL) {
1895 : 0 : FLOW_LOG(ERR,
1896 : : "Port %"PRIu16" actions is NULL.",
1897 : : port_id);
1898 : 0 : rte_flow_error_set(error, EINVAL,
1899 : : RTE_FLOW_ERROR_TYPE_ATTR,
1900 : : NULL, rte_strerror(EINVAL));
1901 : 0 : return NULL;
1902 : : }
1903 [ # # ]: 0 : if (masks == NULL) {
1904 : 0 : FLOW_LOG(ERR,
1905 : : "Port %"PRIu16" masks is NULL.",
1906 : : port_id);
1907 : 0 : rte_flow_error_set(error, EINVAL,
1908 : : RTE_FLOW_ERROR_TYPE_ATTR,
1909 : : NULL, rte_strerror(EINVAL));
1910 : :
1911 : : }
1912 [ # # ]: 0 : if (likely(!!ops->actions_template_create)) {
1913 : 0 : template = ops->actions_template_create(dev, template_attr,
1914 : : actions, masks, error);
1915 [ # # ]: 0 : if (template == NULL)
1916 : 0 : flow_err(port_id, -rte_errno, error);
1917 : :
1918 : 0 : rte_flow_trace_actions_template_create(port_id, template_attr, actions,
1919 : : masks, template);
1920 : :
1921 : 0 : return template;
1922 : : }
1923 : 0 : rte_flow_error_set(error, ENOTSUP,
1924 : : RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
1925 : : NULL, rte_strerror(ENOTSUP));
1926 : 0 : return NULL;
1927 : : }
1928 : :
1929 : : RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_flow_actions_template_destroy, 22.03)
1930 : : int
1931 : 0 : rte_flow_actions_template_destroy(uint16_t port_id,
1932 : : struct rte_flow_actions_template *actions_template,
1933 : : struct rte_flow_error *error)
1934 : : {
1935 : 0 : struct rte_eth_dev *dev = &rte_eth_devices[port_id];
1936 : 0 : const struct rte_flow_ops *ops = rte_flow_ops_get(port_id, error);
1937 : : int ret;
1938 : :
1939 [ # # ]: 0 : if (unlikely(!ops))
1940 : 0 : return -rte_errno;
1941 [ # # ]: 0 : if (unlikely(actions_template == NULL))
1942 : : return 0;
1943 [ # # ]: 0 : if (likely(!!ops->actions_template_destroy)) {
1944 : 0 : ret = flow_err(port_id,
1945 : : ops->actions_template_destroy(dev,
1946 : : actions_template,
1947 : : error),
1948 : : error);
1949 : :
1950 : 0 : rte_flow_trace_actions_template_destroy(port_id, actions_template,
1951 : : ret);
1952 : :
1953 : 0 : return ret;
1954 : : }
1955 : 0 : return rte_flow_error_set(error, ENOTSUP,
1956 : : RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
1957 : : NULL, rte_strerror(ENOTSUP));
1958 : : }
1959 : :
1960 : : RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_flow_template_table_create, 22.03)
1961 : : struct rte_flow_template_table *
1962 : 0 : rte_flow_template_table_create(uint16_t port_id,
1963 : : const struct rte_flow_template_table_attr *table_attr,
1964 : : struct rte_flow_pattern_template *pattern_templates[],
1965 : : uint8_t nb_pattern_templates,
1966 : : struct rte_flow_actions_template *actions_templates[],
1967 : : uint8_t nb_actions_templates,
1968 : : struct rte_flow_error *error)
1969 : : {
1970 : 0 : struct rte_eth_dev *dev = &rte_eth_devices[port_id];
1971 : 0 : const struct rte_flow_ops *ops = rte_flow_ops_get(port_id, error);
1972 : : struct rte_flow_template_table *table;
1973 : :
1974 [ # # ]: 0 : if (unlikely(!ops))
1975 : : return NULL;
1976 [ # # ]: 0 : if (dev->data->flow_configured == 0) {
1977 : 0 : FLOW_LOG(INFO,
1978 : : "Flow engine on port_id=%"PRIu16" is not configured.",
1979 : : port_id);
1980 : 0 : rte_flow_error_set(error, EINVAL,
1981 : : RTE_FLOW_ERROR_TYPE_STATE,
1982 : : NULL, rte_strerror(EINVAL));
1983 : 0 : return NULL;
1984 : : }
1985 [ # # ]: 0 : if (table_attr == NULL) {
1986 : 0 : FLOW_LOG(ERR,
1987 : : "Port %"PRIu16" table attr is NULL.",
1988 : : port_id);
1989 : 0 : rte_flow_error_set(error, EINVAL,
1990 : : RTE_FLOW_ERROR_TYPE_ATTR,
1991 : : NULL, rte_strerror(EINVAL));
1992 : 0 : return NULL;
1993 : : }
1994 [ # # ]: 0 : if (pattern_templates == NULL) {
1995 : 0 : FLOW_LOG(ERR,
1996 : : "Port %"PRIu16" pattern templates is NULL.",
1997 : : port_id);
1998 : 0 : rte_flow_error_set(error, EINVAL,
1999 : : RTE_FLOW_ERROR_TYPE_ATTR,
2000 : : NULL, rte_strerror(EINVAL));
2001 : 0 : return NULL;
2002 : : }
2003 [ # # ]: 0 : if (actions_templates == NULL) {
2004 : 0 : FLOW_LOG(ERR,
2005 : : "Port %"PRIu16" actions templates is NULL.",
2006 : : port_id);
2007 : 0 : rte_flow_error_set(error, EINVAL,
2008 : : RTE_FLOW_ERROR_TYPE_ATTR,
2009 : : NULL, rte_strerror(EINVAL));
2010 : 0 : return NULL;
2011 : : }
2012 [ # # ]: 0 : if (likely(!!ops->template_table_create)) {
2013 : 0 : table = ops->template_table_create(dev, table_attr,
2014 : : pattern_templates, nb_pattern_templates,
2015 : : actions_templates, nb_actions_templates,
2016 : : error);
2017 [ # # ]: 0 : if (table == NULL)
2018 : 0 : flow_err(port_id, -rte_errno, error);
2019 : :
2020 : 0 : rte_flow_trace_template_table_create(port_id, table_attr,
2021 : : pattern_templates,
2022 : : nb_pattern_templates,
2023 : : actions_templates,
2024 : : nb_actions_templates, table);
2025 : :
2026 : 0 : return table;
2027 : : }
2028 : 0 : rte_flow_error_set(error, ENOTSUP,
2029 : : RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
2030 : : NULL, rte_strerror(ENOTSUP));
2031 : 0 : return NULL;
2032 : : }
2033 : :
2034 : : RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_flow_template_table_destroy, 22.03)
2035 : : int
2036 : 0 : rte_flow_template_table_destroy(uint16_t port_id,
2037 : : struct rte_flow_template_table *template_table,
2038 : : struct rte_flow_error *error)
2039 : : {
2040 : 0 : struct rte_eth_dev *dev = &rte_eth_devices[port_id];
2041 : 0 : const struct rte_flow_ops *ops = rte_flow_ops_get(port_id, error);
2042 : : int ret;
2043 : :
2044 [ # # ]: 0 : if (unlikely(!ops))
2045 : 0 : return -rte_errno;
2046 [ # # ]: 0 : if (unlikely(template_table == NULL))
2047 : : return 0;
2048 [ # # ]: 0 : if (likely(!!ops->template_table_destroy)) {
2049 : 0 : ret = flow_err(port_id,
2050 : : ops->template_table_destroy(dev,
2051 : : template_table,
2052 : : error),
2053 : : error);
2054 : :
2055 : 0 : rte_flow_trace_template_table_destroy(port_id, template_table,
2056 : : ret);
2057 : :
2058 : 0 : return ret;
2059 : : }
2060 : 0 : return rte_flow_error_set(error, ENOTSUP,
2061 : : RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
2062 : : NULL, rte_strerror(ENOTSUP));
2063 : : }
2064 : :
2065 : : RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_flow_group_set_miss_actions, 23.11)
2066 : : int
2067 : 0 : rte_flow_group_set_miss_actions(uint16_t port_id,
2068 : : uint32_t group_id,
2069 : : const struct rte_flow_group_attr *attr,
2070 : : const struct rte_flow_action actions[],
2071 : : struct rte_flow_error *error)
2072 : : {
2073 : 0 : struct rte_eth_dev *dev = &rte_eth_devices[port_id];
2074 : 0 : const struct rte_flow_ops *ops = rte_flow_ops_get(port_id, error);
2075 : :
2076 [ # # ]: 0 : if (unlikely(!ops))
2077 : 0 : return -rte_errno;
2078 [ # # ]: 0 : if (likely(!!ops->group_set_miss_actions)) {
2079 : 0 : return flow_err(port_id,
2080 : : ops->group_set_miss_actions(dev, group_id, attr, actions, error),
2081 : : error);
2082 : : }
2083 : 0 : return rte_flow_error_set(error, ENOTSUP,
2084 : : RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
2085 : : NULL, rte_strerror(ENOTSUP));
2086 : : }
2087 : :
2088 : : RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_flow_async_create, 22.03)
2089 : : struct rte_flow *
2090 : 0 : rte_flow_async_create(uint16_t port_id,
2091 : : uint32_t queue_id,
2092 : : const struct rte_flow_op_attr *op_attr,
2093 : : struct rte_flow_template_table *template_table,
2094 : : const struct rte_flow_item pattern[],
2095 : : uint8_t pattern_template_index,
2096 : : const struct rte_flow_action actions[],
2097 : : uint8_t actions_template_index,
2098 : : void *user_data,
2099 : : struct rte_flow_error *error)
2100 : : {
2101 : 0 : struct rte_eth_dev *dev = &rte_eth_devices[port_id];
2102 : : struct rte_flow *flow;
2103 : :
2104 : : #ifdef RTE_FLOW_DEBUG
2105 : : if (!rte_eth_dev_is_valid_port(port_id)) {
2106 : : rte_flow_error_set(error, ENODEV, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
2107 : : rte_strerror(ENODEV));
2108 : : return NULL;
2109 : : }
2110 : : if (dev->flow_fp_ops == NULL || dev->flow_fp_ops->async_create == NULL) {
2111 : : rte_flow_error_set(error, ENOSYS, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
2112 : : rte_strerror(ENOSYS));
2113 : : return NULL;
2114 : : }
2115 : : #endif
2116 : :
2117 : 0 : flow = dev->flow_fp_ops->async_create(dev, queue_id,
2118 : : op_attr, template_table,
2119 : : pattern, pattern_template_index,
2120 : : actions, actions_template_index,
2121 : : user_data, error);
2122 : :
2123 : : rte_flow_trace_async_create(port_id, queue_id, op_attr, template_table,
2124 : : pattern, pattern_template_index, actions,
2125 : : actions_template_index, user_data, flow);
2126 : :
2127 : 0 : return flow;
2128 : : }
2129 : :
2130 : : RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_flow_async_create_by_index, 23.03)
2131 : : struct rte_flow *
2132 : 0 : rte_flow_async_create_by_index(uint16_t port_id,
2133 : : uint32_t queue_id,
2134 : : const struct rte_flow_op_attr *op_attr,
2135 : : struct rte_flow_template_table *template_table,
2136 : : uint32_t rule_index,
2137 : : const struct rte_flow_action actions[],
2138 : : uint8_t actions_template_index,
2139 : : void *user_data,
2140 : : struct rte_flow_error *error)
2141 : : {
2142 : 0 : struct rte_eth_dev *dev = &rte_eth_devices[port_id];
2143 : : struct rte_flow *flow;
2144 : :
2145 : : #ifdef RTE_FLOW_DEBUG
2146 : : if (!rte_eth_dev_is_valid_port(port_id)) {
2147 : : rte_flow_error_set(error, ENODEV, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
2148 : : rte_strerror(ENODEV));
2149 : : return NULL;
2150 : : }
2151 : : if (dev->flow_fp_ops == NULL || dev->flow_fp_ops->async_create_by_index == NULL) {
2152 : : rte_flow_error_set(error, ENOSYS, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
2153 : : rte_strerror(ENOSYS));
2154 : : return NULL;
2155 : : }
2156 : : #endif
2157 : :
2158 : 0 : flow = dev->flow_fp_ops->async_create_by_index(dev, queue_id,
2159 : : op_attr, template_table, rule_index,
2160 : : actions, actions_template_index,
2161 : : user_data, error);
2162 : :
2163 : : rte_flow_trace_async_create_by_index(port_id, queue_id, op_attr, template_table, rule_index,
2164 : : actions, actions_template_index, user_data, flow);
2165 : :
2166 : 0 : return flow;
2167 : : }
2168 : :
2169 : : RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_flow_async_create_by_index_with_pattern, 24.11)
2170 : : struct rte_flow *
2171 : 0 : rte_flow_async_create_by_index_with_pattern(uint16_t port_id,
2172 : : uint32_t queue_id,
2173 : : const struct rte_flow_op_attr *op_attr,
2174 : : struct rte_flow_template_table *template_table,
2175 : : uint32_t rule_index,
2176 : : const struct rte_flow_item pattern[],
2177 : : uint8_t pattern_template_index,
2178 : : const struct rte_flow_action actions[],
2179 : : uint8_t actions_template_index,
2180 : : void *user_data,
2181 : : struct rte_flow_error *error)
2182 : : {
2183 : 0 : struct rte_eth_dev *dev = &rte_eth_devices[port_id];
2184 : : struct rte_flow *flow;
2185 : :
2186 : : #ifdef RTE_FLOW_DEBUG
2187 : : if (!rte_eth_dev_is_valid_port(port_id)) {
2188 : : rte_flow_error_set(error, ENODEV, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
2189 : : rte_strerror(ENODEV));
2190 : : return NULL;
2191 : : }
2192 : : if (dev->flow_fp_ops == NULL ||
2193 : : dev->flow_fp_ops->async_create_by_index_with_pattern == NULL) {
2194 : : rte_flow_error_set(error, ENOSYS, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
2195 : : rte_strerror(ENOSYS));
2196 : : return NULL;
2197 : : }
2198 : : #endif
2199 : :
2200 : 0 : flow = dev->flow_fp_ops->async_create_by_index_with_pattern(dev, queue_id, op_attr,
2201 : : template_table, rule_index,
2202 : : pattern, pattern_template_index,
2203 : : actions, actions_template_index,
2204 : : user_data, error);
2205 : :
2206 : : rte_flow_trace_async_create_by_index_with_pattern(port_id, queue_id, op_attr,
2207 : : template_table, rule_index, pattern,
2208 : : pattern_template_index, actions,
2209 : : actions_template_index, user_data, flow);
2210 : :
2211 : 0 : return flow;
2212 : : }
2213 : :
2214 : : RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_flow_async_destroy, 22.03)
2215 : : int
2216 : 0 : rte_flow_async_destroy(uint16_t port_id,
2217 : : uint32_t queue_id,
2218 : : const struct rte_flow_op_attr *op_attr,
2219 : : struct rte_flow *flow,
2220 : : void *user_data,
2221 : : struct rte_flow_error *error)
2222 : : {
2223 : 0 : struct rte_eth_dev *dev = &rte_eth_devices[port_id];
2224 : : int ret;
2225 : :
2226 : : #ifdef RTE_FLOW_DEBUG
2227 : : if (!rte_eth_dev_is_valid_port(port_id))
2228 : : return rte_flow_error_set(error, ENODEV, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
2229 : : rte_strerror(ENODEV));
2230 : : if (dev->flow_fp_ops == NULL || dev->flow_fp_ops->async_destroy == NULL)
2231 : : return rte_flow_error_set(error, ENOSYS, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
2232 : : rte_strerror(ENOSYS));
2233 : : #endif
2234 : :
2235 : 0 : ret = dev->flow_fp_ops->async_destroy(dev, queue_id,
2236 : : op_attr, flow,
2237 : : user_data, error);
2238 : :
2239 : : rte_flow_trace_async_destroy(port_id, queue_id, op_attr, flow,
2240 : : user_data, ret);
2241 : :
2242 : 0 : return ret;
2243 : : }
2244 : :
2245 : : RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_flow_async_actions_update, 23.07)
2246 : : int
2247 : 0 : rte_flow_async_actions_update(uint16_t port_id,
2248 : : uint32_t queue_id,
2249 : : const struct rte_flow_op_attr *op_attr,
2250 : : struct rte_flow *flow,
2251 : : const struct rte_flow_action actions[],
2252 : : uint8_t actions_template_index,
2253 : : void *user_data,
2254 : : struct rte_flow_error *error)
2255 : : {
2256 : 0 : struct rte_eth_dev *dev = &rte_eth_devices[port_id];
2257 : : int ret;
2258 : :
2259 : : #ifdef RTE_FLOW_DEBUG
2260 : : if (!rte_eth_dev_is_valid_port(port_id))
2261 : : return rte_flow_error_set(error, ENODEV, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
2262 : : rte_strerror(ENODEV));
2263 : : if (dev->flow_fp_ops == NULL || dev->flow_fp_ops->async_actions_update == NULL)
2264 : : return rte_flow_error_set(error, ENOSYS, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
2265 : : rte_strerror(ENOSYS));
2266 : : #endif
2267 : :
2268 : 0 : ret = dev->flow_fp_ops->async_actions_update(dev, queue_id, op_attr,
2269 : : flow, actions,
2270 : : actions_template_index,
2271 : : user_data, error);
2272 : :
2273 : : rte_flow_trace_async_actions_update(port_id, queue_id, op_attr, flow,
2274 : : actions, actions_template_index,
2275 : : user_data, ret);
2276 : :
2277 : 0 : return ret;
2278 : : }
2279 : :
2280 : : RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_flow_push, 22.03)
2281 : : int
2282 : 0 : rte_flow_push(uint16_t port_id,
2283 : : uint32_t queue_id,
2284 : : struct rte_flow_error *error)
2285 : : {
2286 : 0 : struct rte_eth_dev *dev = &rte_eth_devices[port_id];
2287 : : int ret;
2288 : :
2289 : : #ifdef RTE_FLOW_DEBUG
2290 : : if (!rte_eth_dev_is_valid_port(port_id))
2291 : : return rte_flow_error_set(error, ENODEV, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
2292 : : rte_strerror(ENODEV));
2293 : : if (dev->flow_fp_ops == NULL || dev->flow_fp_ops->push == NULL)
2294 : : return rte_flow_error_set(error, ENOSYS, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
2295 : : rte_strerror(ENOSYS));
2296 : : #endif
2297 : :
2298 : 0 : ret = dev->flow_fp_ops->push(dev, queue_id, error);
2299 : :
2300 : : rte_flow_trace_push(port_id, queue_id, ret);
2301 : :
2302 : 0 : return ret;
2303 : : }
2304 : :
2305 : : RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_flow_pull, 22.03)
2306 : : int
2307 : 0 : rte_flow_pull(uint16_t port_id,
2308 : : uint32_t queue_id,
2309 : : struct rte_flow_op_result res[],
2310 : : uint16_t n_res,
2311 : : struct rte_flow_error *error)
2312 : : {
2313 : 0 : struct rte_eth_dev *dev = &rte_eth_devices[port_id];
2314 : : int ret;
2315 : :
2316 : : #ifdef RTE_FLOW_DEBUG
2317 : : if (!rte_eth_dev_is_valid_port(port_id))
2318 : : return rte_flow_error_set(error, ENODEV, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
2319 : : rte_strerror(ENODEV));
2320 : : if (dev->flow_fp_ops == NULL || dev->flow_fp_ops->pull == NULL)
2321 : : return rte_flow_error_set(error, ENOSYS, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
2322 : : rte_strerror(ENOSYS));
2323 : : #endif
2324 : :
2325 : 0 : ret = dev->flow_fp_ops->pull(dev, queue_id, res, n_res, error);
2326 : :
2327 : : rte_flow_trace_pull(port_id, queue_id, res, n_res, ret);
2328 : :
2329 : 0 : return ret;
2330 : : }
2331 : :
2332 : : RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_flow_async_action_handle_create, 22.03)
2333 : : struct rte_flow_action_handle *
2334 : 0 : rte_flow_async_action_handle_create(uint16_t port_id,
2335 : : uint32_t queue_id,
2336 : : const struct rte_flow_op_attr *op_attr,
2337 : : const struct rte_flow_indir_action_conf *indir_action_conf,
2338 : : const struct rte_flow_action *action,
2339 : : void *user_data,
2340 : : struct rte_flow_error *error)
2341 : : {
2342 : 0 : struct rte_eth_dev *dev = &rte_eth_devices[port_id];
2343 : : struct rte_flow_action_handle *handle;
2344 : :
2345 : : #ifdef RTE_FLOW_DEBUG
2346 : : if (!rte_eth_dev_is_valid_port(port_id)) {
2347 : : rte_flow_error_set(error, ENODEV, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
2348 : : rte_strerror(ENODEV));
2349 : : return NULL;
2350 : : }
2351 : : if (dev->flow_fp_ops == NULL || dev->flow_fp_ops->async_action_handle_create == NULL) {
2352 : : rte_flow_error_set(error, ENOSYS, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
2353 : : rte_strerror(ENOSYS));
2354 : : return NULL;
2355 : : }
2356 : : #endif
2357 : :
2358 : 0 : handle = dev->flow_fp_ops->async_action_handle_create(dev, queue_id, op_attr,
2359 : : indir_action_conf, action,
2360 : : user_data, error);
2361 : :
2362 : : rte_flow_trace_async_action_handle_create(port_id, queue_id, op_attr,
2363 : : indir_action_conf, action,
2364 : : user_data, handle);
2365 : :
2366 : 0 : return handle;
2367 : : }
2368 : :
2369 : : RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_flow_async_action_handle_destroy, 22.03)
2370 : : int
2371 : 0 : rte_flow_async_action_handle_destroy(uint16_t port_id,
2372 : : uint32_t queue_id,
2373 : : const struct rte_flow_op_attr *op_attr,
2374 : : struct rte_flow_action_handle *action_handle,
2375 : : void *user_data,
2376 : : struct rte_flow_error *error)
2377 : : {
2378 : 0 : struct rte_eth_dev *dev = &rte_eth_devices[port_id];
2379 : : int ret;
2380 : :
2381 : : #ifdef RTE_FLOW_DEBUG
2382 : : if (!rte_eth_dev_is_valid_port(port_id))
2383 : : return rte_flow_error_set(error, ENODEV, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
2384 : : rte_strerror(ENODEV));
2385 : : if (dev->flow_fp_ops == NULL || dev->flow_fp_ops->async_action_handle_destroy == NULL)
2386 : : return rte_flow_error_set(error, ENOSYS, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
2387 : : rte_strerror(ENOSYS));
2388 : : #endif
2389 : :
2390 : 0 : ret = dev->flow_fp_ops->async_action_handle_destroy(dev, queue_id, op_attr,
2391 : : action_handle, user_data, error);
2392 : :
2393 : : rte_flow_trace_async_action_handle_destroy(port_id, queue_id, op_attr,
2394 : : action_handle, user_data, ret);
2395 : :
2396 : 0 : return ret;
2397 : : }
2398 : :
2399 : : RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_flow_async_action_handle_update, 22.03)
2400 : : int
2401 : 0 : rte_flow_async_action_handle_update(uint16_t port_id,
2402 : : uint32_t queue_id,
2403 : : const struct rte_flow_op_attr *op_attr,
2404 : : struct rte_flow_action_handle *action_handle,
2405 : : const void *update,
2406 : : void *user_data,
2407 : : struct rte_flow_error *error)
2408 : : {
2409 : 0 : struct rte_eth_dev *dev = &rte_eth_devices[port_id];
2410 : : int ret;
2411 : :
2412 : : #ifdef RTE_FLOW_DEBUG
2413 : : if (!rte_eth_dev_is_valid_port(port_id))
2414 : : return rte_flow_error_set(error, ENODEV, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
2415 : : rte_strerror(ENODEV));
2416 : : if (dev->flow_fp_ops == NULL || dev->flow_fp_ops->async_action_handle_update == NULL)
2417 : : return rte_flow_error_set(error, ENOSYS, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
2418 : : rte_strerror(ENOSYS));
2419 : : #endif
2420 : :
2421 : 0 : ret = dev->flow_fp_ops->async_action_handle_update(dev, queue_id, op_attr,
2422 : : action_handle, update, user_data, error);
2423 : :
2424 : : rte_flow_trace_async_action_handle_update(port_id, queue_id, op_attr,
2425 : : action_handle, update,
2426 : : user_data, ret);
2427 : :
2428 : 0 : return ret;
2429 : : }
2430 : :
2431 : : RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_flow_async_action_handle_query, 22.11)
2432 : : int
2433 : 0 : rte_flow_async_action_handle_query(uint16_t port_id,
2434 : : uint32_t queue_id,
2435 : : const struct rte_flow_op_attr *op_attr,
2436 : : const struct rte_flow_action_handle *action_handle,
2437 : : void *data,
2438 : : void *user_data,
2439 : : struct rte_flow_error *error)
2440 : : {
2441 : 0 : struct rte_eth_dev *dev = &rte_eth_devices[port_id];
2442 : : int ret;
2443 : :
2444 : : #ifdef RTE_FLOW_DEBUG
2445 : : if (!rte_eth_dev_is_valid_port(port_id))
2446 : : return rte_flow_error_set(error, ENODEV, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
2447 : : rte_strerror(ENODEV));
2448 : : if (dev->flow_fp_ops == NULL || dev->flow_fp_ops->async_action_handle_query == NULL)
2449 : : return rte_flow_error_set(error, ENOSYS, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
2450 : : rte_strerror(ENOSYS));
2451 : : #endif
2452 : :
2453 : 0 : ret = dev->flow_fp_ops->async_action_handle_query(dev, queue_id, op_attr,
2454 : : action_handle, data, user_data, error);
2455 : :
2456 : : rte_flow_trace_async_action_handle_query(port_id, queue_id, op_attr,
2457 : : action_handle, data, user_data,
2458 : : ret);
2459 : :
2460 : 0 : return ret;
2461 : : }
2462 : :
2463 : : RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_flow_action_handle_query_update, 23.03)
2464 : : int
2465 : 0 : rte_flow_action_handle_query_update(uint16_t port_id,
2466 : : struct rte_flow_action_handle *handle,
2467 : : const void *update, void *query,
2468 : : enum rte_flow_query_update_mode mode,
2469 : : struct rte_flow_error *error)
2470 : : {
2471 : : int ret;
2472 : : struct rte_eth_dev *dev;
2473 : : const struct rte_flow_ops *ops;
2474 : :
2475 [ # # ]: 0 : RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
2476 [ # # ]: 0 : if (!handle)
2477 : : return -EINVAL;
2478 [ # # ]: 0 : if (!update && !query)
2479 : : return -EINVAL;
2480 : 0 : dev = &rte_eth_devices[port_id];
2481 : 0 : ops = rte_flow_ops_get(port_id, error);
2482 [ # # # # ]: 0 : if (!ops || !ops->action_handle_query_update)
2483 : : return -ENOTSUP;
2484 : 0 : ret = ops->action_handle_query_update(dev, handle, update,
2485 : : query, mode, error);
2486 : 0 : return flow_err(port_id, ret, error);
2487 : : }
2488 : :
2489 : : RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_flow_async_action_handle_query_update, 23.03)
2490 : : int
2491 : 0 : rte_flow_async_action_handle_query_update(uint16_t port_id, uint32_t queue_id,
2492 : : const struct rte_flow_op_attr *attr,
2493 : : struct rte_flow_action_handle *handle,
2494 : : const void *update, void *query,
2495 : : enum rte_flow_query_update_mode mode,
2496 : : void *user_data,
2497 : : struct rte_flow_error *error)
2498 : : {
2499 : 0 : struct rte_eth_dev *dev = &rte_eth_devices[port_id];
2500 : :
2501 : : #ifdef RTE_FLOW_DEBUG
2502 : : if (!rte_eth_dev_is_valid_port(port_id))
2503 : : return rte_flow_error_set(error, ENODEV, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
2504 : : rte_strerror(ENODEV));
2505 : : if (dev->flow_fp_ops == NULL || dev->flow_fp_ops->async_action_handle_query_update == NULL)
2506 : : return rte_flow_error_set(error, ENOSYS, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
2507 : : rte_strerror(ENOSYS));
2508 : : #endif
2509 : :
2510 : 0 : return dev->flow_fp_ops->async_action_handle_query_update(dev, queue_id, attr,
2511 : : handle, update,
2512 : : query, mode,
2513 : : user_data, error);
2514 : : }
2515 : :
2516 : : RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_flow_action_list_handle_create, 23.07)
2517 : : struct rte_flow_action_list_handle *
2518 : 0 : rte_flow_action_list_handle_create(uint16_t port_id,
2519 : : const
2520 : : struct rte_flow_indir_action_conf *conf,
2521 : : const struct rte_flow_action *actions,
2522 : : struct rte_flow_error *error)
2523 : : {
2524 : : int ret;
2525 : : struct rte_eth_dev *dev;
2526 : : const struct rte_flow_ops *ops;
2527 : : struct rte_flow_action_list_handle *handle;
2528 : :
2529 [ # # ]: 0 : RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, NULL);
2530 : 0 : ops = rte_flow_ops_get(port_id, error);
2531 [ # # # # ]: 0 : if (!ops || !ops->action_list_handle_create) {
2532 : 0 : rte_flow_error_set(error, ENOTSUP,
2533 : : RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
2534 : : "action_list handle not supported");
2535 : 0 : return NULL;
2536 : : }
2537 : 0 : dev = &rte_eth_devices[port_id];
2538 : 0 : handle = ops->action_list_handle_create(dev, conf, actions, error);
2539 : 0 : ret = flow_err(port_id, -rte_errno, error);
2540 : : rte_flow_trace_action_list_handle_create(port_id, conf, actions, ret);
2541 : 0 : return handle;
2542 : : }
2543 : :
2544 : : RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_flow_action_list_handle_destroy, 23.07)
2545 : : int
2546 : 0 : rte_flow_action_list_handle_destroy(uint16_t port_id,
2547 : : struct rte_flow_action_list_handle *handle,
2548 : : struct rte_flow_error *error)
2549 : : {
2550 : : int ret;
2551 : : struct rte_eth_dev *dev;
2552 : : const struct rte_flow_ops *ops;
2553 : :
2554 [ # # ]: 0 : RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
2555 : 0 : ops = rte_flow_ops_get(port_id, error);
2556 [ # # # # ]: 0 : if (!ops || !ops->action_list_handle_destroy)
2557 : 0 : return rte_flow_error_set(error, ENOTSUP,
2558 : : RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
2559 : : "action_list handle not supported");
2560 : 0 : dev = &rte_eth_devices[port_id];
2561 : 0 : ret = ops->action_list_handle_destroy(dev, handle, error);
2562 : 0 : ret = flow_err(port_id, ret, error);
2563 : : rte_flow_trace_action_list_handle_destroy(port_id, handle, ret);
2564 : 0 : return ret;
2565 : : }
2566 : :
2567 : : RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_flow_async_action_list_handle_create, 23.07)
2568 : : struct rte_flow_action_list_handle *
2569 : 0 : rte_flow_async_action_list_handle_create(uint16_t port_id, uint32_t queue_id,
2570 : : const struct rte_flow_op_attr *attr,
2571 : : const struct rte_flow_indir_action_conf *conf,
2572 : : const struct rte_flow_action *actions,
2573 : : void *user_data,
2574 : : struct rte_flow_error *error)
2575 : : {
2576 : 0 : struct rte_eth_dev *dev = &rte_eth_devices[port_id];
2577 : : struct rte_flow_action_list_handle *handle;
2578 : : int ret;
2579 : :
2580 : : #ifdef RTE_FLOW_DEBUG
2581 : : if (!rte_eth_dev_is_valid_port(port_id)) {
2582 : : rte_flow_error_set(error, ENODEV, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
2583 : : rte_strerror(ENODEV));
2584 : : return NULL;
2585 : : }
2586 : : if (dev->flow_fp_ops == NULL || dev->flow_fp_ops->async_action_list_handle_create == NULL) {
2587 : : rte_flow_error_set(error, ENOSYS, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
2588 : : rte_strerror(ENOSYS));
2589 : : return NULL;
2590 : : }
2591 : : #endif
2592 : :
2593 : 0 : handle = dev->flow_fp_ops->async_action_list_handle_create(dev, queue_id, attr, conf,
2594 : : actions, user_data,
2595 : : error);
2596 : 0 : ret = flow_err(port_id, -rte_errno, error);
2597 : :
2598 : : rte_flow_trace_async_action_list_handle_create(port_id, queue_id, attr,
2599 : : conf, actions, user_data,
2600 : : ret);
2601 : 0 : return handle;
2602 : : }
2603 : :
2604 : : RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_flow_async_action_list_handle_destroy, 23.07)
2605 : : int
2606 : 0 : rte_flow_async_action_list_handle_destroy(uint16_t port_id, uint32_t queue_id,
2607 : : const struct rte_flow_op_attr *op_attr,
2608 : : struct rte_flow_action_list_handle *handle,
2609 : : void *user_data, struct rte_flow_error *error)
2610 : : {
2611 : 0 : struct rte_eth_dev *dev = &rte_eth_devices[port_id];
2612 : : int ret;
2613 : :
2614 : : #ifdef RTE_FLOW_DEBUG
2615 : : if (!rte_eth_dev_is_valid_port(port_id))
2616 : : return rte_flow_error_set(error, ENODEV, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
2617 : : rte_strerror(ENODEV));
2618 : : if (dev->flow_fp_ops == NULL || dev->flow_fp_ops->async_action_list_handle_destroy == NULL)
2619 : : return rte_flow_error_set(error, ENOSYS, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
2620 : : rte_strerror(ENOSYS));
2621 : : #endif
2622 : :
2623 : 0 : ret = dev->flow_fp_ops->async_action_list_handle_destroy(dev, queue_id, op_attr,
2624 : : handle, user_data, error);
2625 : :
2626 : : rte_flow_trace_async_action_list_handle_destroy(port_id, queue_id,
2627 : : op_attr, handle,
2628 : : user_data, ret);
2629 : 0 : return ret;
2630 : : }
2631 : :
2632 : : RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_flow_action_list_handle_query_update, 23.07)
2633 : : int
2634 : 0 : rte_flow_action_list_handle_query_update(uint16_t port_id,
2635 : : const struct rte_flow_action_list_handle *handle,
2636 : : const void **update, void **query,
2637 : : enum rte_flow_query_update_mode mode,
2638 : : struct rte_flow_error *error)
2639 : : {
2640 : : int ret;
2641 : : struct rte_eth_dev *dev;
2642 : : const struct rte_flow_ops *ops;
2643 : :
2644 [ # # ]: 0 : RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
2645 : 0 : ops = rte_flow_ops_get(port_id, error);
2646 [ # # # # ]: 0 : if (!ops || !ops->action_list_handle_query_update)
2647 : 0 : return rte_flow_error_set(error, ENOTSUP,
2648 : : RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
2649 : : "action_list query_update not supported");
2650 : 0 : dev = &rte_eth_devices[port_id];
2651 : 0 : ret = ops->action_list_handle_query_update(dev, handle, update, query,
2652 : : mode, error);
2653 : 0 : ret = flow_err(port_id, ret, error);
2654 : : rte_flow_trace_action_list_handle_query_update(port_id, handle, update,
2655 : : query, mode, ret);
2656 : 0 : return ret;
2657 : : }
2658 : :
2659 : : RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_flow_async_action_list_handle_query_update, 23.07)
2660 : : int
2661 : 0 : rte_flow_async_action_list_handle_query_update(uint16_t port_id, uint32_t queue_id,
2662 : : const struct rte_flow_op_attr *attr,
2663 : : const struct rte_flow_action_list_handle *handle,
2664 : : const void **update, void **query,
2665 : : enum rte_flow_query_update_mode mode,
2666 : : void *user_data, struct rte_flow_error *error)
2667 : : {
2668 : 0 : struct rte_eth_dev *dev = &rte_eth_devices[port_id];
2669 : : int ret;
2670 : :
2671 : : #ifdef RTE_FLOW_DEBUG
2672 : : if (!rte_eth_dev_is_valid_port(port_id))
2673 : : return rte_flow_error_set(error, ENODEV, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
2674 : : rte_strerror(ENODEV));
2675 : : if (dev->flow_fp_ops == NULL ||
2676 : : dev->flow_fp_ops->async_action_list_handle_query_update == NULL)
2677 : : return rte_flow_error_set(error, ENOSYS, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
2678 : : rte_strerror(ENOSYS));
2679 : : #endif
2680 : :
2681 : 0 : ret = dev->flow_fp_ops->async_action_list_handle_query_update(dev, queue_id, attr,
2682 : : handle, update, query,
2683 : : mode, user_data,
2684 : : error);
2685 : :
2686 : : rte_flow_trace_async_action_list_handle_query_update(port_id, queue_id,
2687 : : attr, handle,
2688 : : update, query,
2689 : : mode, user_data,
2690 : : ret);
2691 : 0 : return ret;
2692 : : }
2693 : :
2694 : : RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_flow_calc_table_hash, 23.11)
2695 : : int
2696 : 0 : rte_flow_calc_table_hash(uint16_t port_id, const struct rte_flow_template_table *table,
2697 : : const struct rte_flow_item pattern[], uint8_t pattern_template_index,
2698 : : uint32_t *hash, struct rte_flow_error *error)
2699 : : {
2700 : : int ret;
2701 : : struct rte_eth_dev *dev;
2702 : : const struct rte_flow_ops *ops;
2703 : :
2704 [ # # ]: 0 : RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
2705 : 0 : ops = rte_flow_ops_get(port_id, error);
2706 [ # # # # ]: 0 : if (!ops || !ops->flow_calc_table_hash)
2707 : 0 : return rte_flow_error_set(error, ENOTSUP,
2708 : : RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
2709 : : "action_list async query_update not supported");
2710 : 0 : dev = &rte_eth_devices[port_id];
2711 : 0 : ret = ops->flow_calc_table_hash(dev, table, pattern, pattern_template_index,
2712 : : hash, error);
2713 : 0 : return flow_err(port_id, ret, error);
2714 : : }
2715 : :
2716 : : RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_flow_calc_encap_hash, 24.03)
2717 : : int
2718 : 0 : rte_flow_calc_encap_hash(uint16_t port_id, const struct rte_flow_item pattern[],
2719 : : enum rte_flow_encap_hash_field dest_field, uint8_t hash_len,
2720 : : uint8_t *hash, struct rte_flow_error *error)
2721 : : {
2722 : : int ret;
2723 : : struct rte_eth_dev *dev;
2724 : : const struct rte_flow_ops *ops;
2725 : :
2726 [ # # ]: 0 : RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
2727 : 0 : ops = rte_flow_ops_get(port_id, error);
2728 [ # # # # ]: 0 : if (!ops || !ops->flow_calc_encap_hash)
2729 : 0 : return rte_flow_error_set(error, ENOTSUP,
2730 : : RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
2731 : : "calc encap hash is not supported");
2732 [ # # ]: 0 : if (dest_field > RTE_FLOW_ENCAP_HASH_FIELD_NVGRE_FLOW_ID)
2733 : 0 : return rte_flow_error_set(error, EINVAL,
2734 : : RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
2735 : : "hash dest field is not defined");
2736 [ # # ]: 0 : if ((dest_field == RTE_FLOW_ENCAP_HASH_FIELD_SRC_PORT && hash_len != 2) ||
2737 [ # # ]: 0 : (dest_field == RTE_FLOW_ENCAP_HASH_FIELD_NVGRE_FLOW_ID && hash_len != 1))
2738 : 0 : return rte_flow_error_set(error, EINVAL,
2739 : : RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
2740 : : "hash len doesn't match the requested field len");
2741 : 0 : dev = &rte_eth_devices[port_id];
2742 : 0 : ret = ops->flow_calc_encap_hash(dev, pattern, dest_field, hash, error);
2743 : 0 : return flow_err(port_id, ret, error);
2744 : : }
2745 : :
2746 : : RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_flow_template_table_resizable, 24.03)
2747 : : bool
2748 : 0 : rte_flow_template_table_resizable(__rte_unused uint16_t port_id,
2749 : : const struct rte_flow_template_table_attr *tbl_attr)
2750 : : {
2751 : 0 : return (tbl_attr->specialize &
2752 : 0 : RTE_FLOW_TABLE_SPECIALIZE_RESIZABLE) != 0;
2753 : : }
2754 : :
2755 : : RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_flow_template_table_resize, 24.03)
2756 : : int
2757 : 0 : rte_flow_template_table_resize(uint16_t port_id,
2758 : : struct rte_flow_template_table *table,
2759 : : uint32_t nb_rules,
2760 : : struct rte_flow_error *error)
2761 : : {
2762 : : int ret;
2763 : : struct rte_eth_dev *dev;
2764 : : const struct rte_flow_ops *ops;
2765 : :
2766 [ # # ]: 0 : RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
2767 : 0 : ops = rte_flow_ops_get(port_id, error);
2768 [ # # # # ]: 0 : if (!ops || !ops->flow_template_table_resize)
2769 : 0 : return rte_flow_error_set(error, ENOTSUP,
2770 : : RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
2771 : : "flow_template_table_resize not supported");
2772 : 0 : dev = &rte_eth_devices[port_id];
2773 : 0 : ret = ops->flow_template_table_resize(dev, table, nb_rules, error);
2774 : 0 : ret = flow_err(port_id, ret, error);
2775 : : rte_flow_trace_template_table_resize(port_id, table, nb_rules, ret);
2776 : 0 : return ret;
2777 : : }
2778 : :
2779 : : RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_flow_async_update_resized, 24.03)
2780 : : int
2781 : 0 : rte_flow_async_update_resized(uint16_t port_id, uint32_t queue,
2782 : : const struct rte_flow_op_attr *attr,
2783 : : struct rte_flow *rule, void *user_data,
2784 : : struct rte_flow_error *error)
2785 : : {
2786 : : int ret;
2787 : : struct rte_eth_dev *dev;
2788 : : const struct rte_flow_ops *ops;
2789 : :
2790 [ # # ]: 0 : RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
2791 : 0 : ops = rte_flow_ops_get(port_id, error);
2792 [ # # # # ]: 0 : if (!ops || !ops->flow_update_resized)
2793 : 0 : return rte_flow_error_set(error, ENOTSUP,
2794 : : RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
2795 : : "async_flow_async_transfer not supported");
2796 : 0 : dev = &rte_eth_devices[port_id];
2797 : 0 : ret = ops->flow_update_resized(dev, queue, attr, rule, user_data, error);
2798 : 0 : ret = flow_err(port_id, ret, error);
2799 : : rte_flow_trace_async_update_resized(port_id, queue, attr,
2800 : : rule, user_data, ret);
2801 : 0 : return ret;
2802 : : }
2803 : :
2804 : : RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_flow_template_table_resize_complete, 24.03)
2805 : : int
2806 : 0 : rte_flow_template_table_resize_complete(uint16_t port_id,
2807 : : struct rte_flow_template_table *table,
2808 : : struct rte_flow_error *error)
2809 : : {
2810 : : int ret;
2811 : : struct rte_eth_dev *dev;
2812 : : const struct rte_flow_ops *ops;
2813 : :
2814 [ # # ]: 0 : RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
2815 : 0 : ops = rte_flow_ops_get(port_id, error);
2816 [ # # # # ]: 0 : if (!ops || !ops->flow_template_table_resize_complete)
2817 : 0 : return rte_flow_error_set(error, ENOTSUP,
2818 : : RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
2819 : : "flow_template_table_transfer_complete not supported");
2820 : 0 : dev = &rte_eth_devices[port_id];
2821 : 0 : ret = ops->flow_template_table_resize_complete(dev, table, error);
2822 : 0 : ret = flow_err(port_id, ret, error);
2823 : : rte_flow_trace_table_resize_complete(port_id, table, ret);
2824 : 0 : return ret;
2825 : : }
2826 : :
2827 : : static struct rte_flow *
2828 : 0 : rte_flow_dummy_async_create(struct rte_eth_dev *dev __rte_unused,
2829 : : uint32_t queue __rte_unused,
2830 : : const struct rte_flow_op_attr *attr __rte_unused,
2831 : : struct rte_flow_template_table *table __rte_unused,
2832 : : const struct rte_flow_item items[] __rte_unused,
2833 : : uint8_t pattern_template_index __rte_unused,
2834 : : const struct rte_flow_action actions[] __rte_unused,
2835 : : uint8_t action_template_index __rte_unused,
2836 : : void *user_data __rte_unused,
2837 : : struct rte_flow_error *error)
2838 : : {
2839 : 0 : rte_flow_error_set(error, ENOSYS, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
2840 : : rte_strerror(ENOSYS));
2841 : 0 : return NULL;
2842 : : }
2843 : :
2844 : : static struct rte_flow *
2845 : 0 : rte_flow_dummy_async_create_by_index(struct rte_eth_dev *dev __rte_unused,
2846 : : uint32_t queue __rte_unused,
2847 : : const struct rte_flow_op_attr *attr __rte_unused,
2848 : : struct rte_flow_template_table *table __rte_unused,
2849 : : uint32_t rule_index __rte_unused,
2850 : : const struct rte_flow_action actions[] __rte_unused,
2851 : : uint8_t action_template_index __rte_unused,
2852 : : void *user_data __rte_unused,
2853 : : struct rte_flow_error *error)
2854 : : {
2855 : 0 : rte_flow_error_set(error, ENOSYS, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
2856 : : rte_strerror(ENOSYS));
2857 : 0 : return NULL;
2858 : : }
2859 : :
2860 : : static struct rte_flow *
2861 : 0 : rte_flow_dummy_async_create_by_index_with_pattern(struct rte_eth_dev *dev __rte_unused,
2862 : : uint32_t queue __rte_unused,
2863 : : const struct rte_flow_op_attr *attr __rte_unused,
2864 : : struct rte_flow_template_table *table __rte_unused,
2865 : : uint32_t rule_index __rte_unused,
2866 : : const struct rte_flow_item items[] __rte_unused,
2867 : : uint8_t pattern_template_index __rte_unused,
2868 : : const struct rte_flow_action actions[] __rte_unused,
2869 : : uint8_t action_template_index __rte_unused,
2870 : : void *user_data __rte_unused,
2871 : : struct rte_flow_error *error)
2872 : : {
2873 : 0 : rte_flow_error_set(error, ENOSYS, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
2874 : : rte_strerror(ENOSYS));
2875 : 0 : return NULL;
2876 : : }
2877 : :
2878 : : static int
2879 : 0 : rte_flow_dummy_async_actions_update(struct rte_eth_dev *dev __rte_unused,
2880 : : uint32_t queue_id __rte_unused,
2881 : : const struct rte_flow_op_attr *op_attr __rte_unused,
2882 : : struct rte_flow *flow __rte_unused,
2883 : : const struct rte_flow_action actions[] __rte_unused,
2884 : : uint8_t actions_template_index __rte_unused,
2885 : : void *user_data __rte_unused,
2886 : : struct rte_flow_error *error)
2887 : : {
2888 : 0 : return rte_flow_error_set(error, ENOSYS, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
2889 : : rte_strerror(ENOSYS));
2890 : : }
2891 : :
2892 : : static int
2893 : 0 : rte_flow_dummy_async_destroy(struct rte_eth_dev *dev __rte_unused,
2894 : : uint32_t queue_id __rte_unused,
2895 : : const struct rte_flow_op_attr *op_attr __rte_unused,
2896 : : struct rte_flow *flow __rte_unused,
2897 : : void *user_data __rte_unused,
2898 : : struct rte_flow_error *error)
2899 : : {
2900 : 0 : return rte_flow_error_set(error, ENOSYS, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
2901 : : rte_strerror(ENOSYS));
2902 : : }
2903 : :
2904 : : static int
2905 : 0 : rte_flow_dummy_push(struct rte_eth_dev *dev __rte_unused,
2906 : : uint32_t queue_id __rte_unused,
2907 : : struct rte_flow_error *error)
2908 : : {
2909 : 0 : return rte_flow_error_set(error, ENOSYS, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
2910 : : rte_strerror(ENOSYS));
2911 : : }
2912 : :
2913 : : static int
2914 : 0 : rte_flow_dummy_pull(struct rte_eth_dev *dev __rte_unused,
2915 : : uint32_t queue_id __rte_unused,
2916 : : struct rte_flow_op_result res[] __rte_unused,
2917 : : uint16_t n_res __rte_unused,
2918 : : struct rte_flow_error *error)
2919 : : {
2920 : 0 : return rte_flow_error_set(error, ENOSYS, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
2921 : : rte_strerror(ENOSYS));
2922 : : }
2923 : :
2924 : : static struct rte_flow_action_handle *
2925 : 0 : rte_flow_dummy_async_action_handle_create(
2926 : : struct rte_eth_dev *dev __rte_unused,
2927 : : uint32_t queue_id __rte_unused,
2928 : : const struct rte_flow_op_attr *op_attr __rte_unused,
2929 : : const struct rte_flow_indir_action_conf *indir_action_conf __rte_unused,
2930 : : const struct rte_flow_action *action __rte_unused,
2931 : : void *user_data __rte_unused,
2932 : : struct rte_flow_error *error)
2933 : : {
2934 : 0 : rte_flow_error_set(error, ENOSYS, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
2935 : : rte_strerror(ENOSYS));
2936 : 0 : return NULL;
2937 : : }
2938 : :
2939 : : static int
2940 : 0 : rte_flow_dummy_async_action_handle_destroy(
2941 : : struct rte_eth_dev *dev __rte_unused,
2942 : : uint32_t queue_id __rte_unused,
2943 : : const struct rte_flow_op_attr *op_attr __rte_unused,
2944 : : struct rte_flow_action_handle *action_handle __rte_unused,
2945 : : void *user_data __rte_unused,
2946 : : struct rte_flow_error *error)
2947 : : {
2948 : 0 : return rte_flow_error_set(error, ENOSYS, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
2949 : : rte_strerror(ENOSYS));
2950 : : }
2951 : :
2952 : : static int
2953 : 0 : rte_flow_dummy_async_action_handle_update(
2954 : : struct rte_eth_dev *dev __rte_unused,
2955 : : uint32_t queue_id __rte_unused,
2956 : : const struct rte_flow_op_attr *op_attr __rte_unused,
2957 : : struct rte_flow_action_handle *action_handle __rte_unused,
2958 : : const void *update __rte_unused,
2959 : : void *user_data __rte_unused,
2960 : : struct rte_flow_error *error)
2961 : : {
2962 : 0 : return rte_flow_error_set(error, ENOSYS, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
2963 : : rte_strerror(ENOSYS));
2964 : : }
2965 : :
2966 : : static int
2967 : 0 : rte_flow_dummy_async_action_handle_query(
2968 : : struct rte_eth_dev *dev __rte_unused,
2969 : : uint32_t queue_id __rte_unused,
2970 : : const struct rte_flow_op_attr *op_attr __rte_unused,
2971 : : const struct rte_flow_action_handle *action_handle __rte_unused,
2972 : : void *data __rte_unused,
2973 : : void *user_data __rte_unused,
2974 : : struct rte_flow_error *error)
2975 : : {
2976 : 0 : return rte_flow_error_set(error, ENOSYS, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
2977 : : rte_strerror(ENOSYS));
2978 : : }
2979 : :
2980 : : static int
2981 : 0 : rte_flow_dummy_async_action_handle_query_update(
2982 : : struct rte_eth_dev *dev __rte_unused,
2983 : : uint32_t queue_id __rte_unused,
2984 : : const struct rte_flow_op_attr *attr __rte_unused,
2985 : : struct rte_flow_action_handle *handle __rte_unused,
2986 : : const void *update __rte_unused,
2987 : : void *query __rte_unused,
2988 : : enum rte_flow_query_update_mode mode __rte_unused,
2989 : : void *user_data __rte_unused,
2990 : : struct rte_flow_error *error)
2991 : : {
2992 : 0 : return rte_flow_error_set(error, ENOSYS, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
2993 : : rte_strerror(ENOSYS));
2994 : : }
2995 : :
2996 : : static struct rte_flow_action_list_handle *
2997 : 0 : rte_flow_dummy_async_action_list_handle_create(
2998 : : struct rte_eth_dev *dev __rte_unused,
2999 : : uint32_t queue_id __rte_unused,
3000 : : const struct rte_flow_op_attr *attr __rte_unused,
3001 : : const struct rte_flow_indir_action_conf *conf __rte_unused,
3002 : : const struct rte_flow_action *actions __rte_unused,
3003 : : void *user_data __rte_unused,
3004 : : struct rte_flow_error *error)
3005 : : {
3006 : 0 : rte_flow_error_set(error, ENOSYS, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
3007 : : rte_strerror(ENOSYS));
3008 : 0 : return NULL;
3009 : : }
3010 : :
3011 : : static int
3012 : 0 : rte_flow_dummy_async_action_list_handle_destroy(
3013 : : struct rte_eth_dev *dev __rte_unused,
3014 : : uint32_t queue_id __rte_unused,
3015 : : const struct rte_flow_op_attr *op_attr __rte_unused,
3016 : : struct rte_flow_action_list_handle *handle __rte_unused,
3017 : : void *user_data __rte_unused,
3018 : : struct rte_flow_error *error)
3019 : : {
3020 : 0 : return rte_flow_error_set(error, ENOSYS, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
3021 : : rte_strerror(ENOSYS));
3022 : : }
3023 : :
3024 : : static int
3025 : 0 : rte_flow_dummy_async_action_list_handle_query_update(
3026 : : struct rte_eth_dev *dev __rte_unused,
3027 : : uint32_t queue_id __rte_unused,
3028 : : const struct rte_flow_op_attr *attr __rte_unused,
3029 : : const struct rte_flow_action_list_handle *handle __rte_unused,
3030 : : const void **update __rte_unused,
3031 : : void **query __rte_unused,
3032 : : enum rte_flow_query_update_mode mode __rte_unused,
3033 : : void *user_data __rte_unused,
3034 : : struct rte_flow_error *error)
3035 : : {
3036 : 0 : return rte_flow_error_set(error, ENOSYS, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
3037 : : rte_strerror(ENOSYS));
3038 : : }
3039 : :
3040 : : RTE_EXPORT_INTERNAL_SYMBOL(rte_flow_fp_default_ops)
3041 : : struct rte_flow_fp_ops rte_flow_fp_default_ops = {
3042 : : .async_create = rte_flow_dummy_async_create,
3043 : : .async_create_by_index = rte_flow_dummy_async_create_by_index,
3044 : : .async_actions_update = rte_flow_dummy_async_actions_update,
3045 : : .async_create_by_index_with_pattern = rte_flow_dummy_async_create_by_index_with_pattern,
3046 : : .async_destroy = rte_flow_dummy_async_destroy,
3047 : : .push = rte_flow_dummy_push,
3048 : : .pull = rte_flow_dummy_pull,
3049 : : .async_action_handle_create = rte_flow_dummy_async_action_handle_create,
3050 : : .async_action_handle_destroy = rte_flow_dummy_async_action_handle_destroy,
3051 : : .async_action_handle_update = rte_flow_dummy_async_action_handle_update,
3052 : : .async_action_handle_query = rte_flow_dummy_async_action_handle_query,
3053 : : .async_action_handle_query_update = rte_flow_dummy_async_action_handle_query_update,
3054 : : .async_action_list_handle_create = rte_flow_dummy_async_action_list_handle_create,
3055 : : .async_action_list_handle_destroy = rte_flow_dummy_async_action_list_handle_destroy,
3056 : : .async_action_list_handle_query_update =
3057 : : rte_flow_dummy_async_action_list_handle_query_update,
3058 : : };
|