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