1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright 2016 6WIND S.A.
3 * Copyright 2016 Mellanox Technologies, Ltd
11 #include <rte_common.h>
12 #include <rte_errno.h>
13 #include <rte_branch_prediction.h>
14 #include <rte_string_fns.h>
16 #include <rte_mbuf_dyn.h>
17 #include "rte_ethdev.h"
18 #include "rte_flow_driver.h"
21 /* Mbuf dynamic field name for metadata. */
22 int32_t rte_flow_dynf_metadata_offs = -1;
24 /* Mbuf dynamic field flag bit number for metadata. */
25 uint64_t rte_flow_dynf_metadata_mask;
28 * Flow elements description tables.
30 struct rte_flow_desc_data {
33 size_t (*desc_fn)(void *dst, const void *src);
45 * rte_flow_desc_item - for flow item conversion.
46 * rte_flow_desc_action - for flow action conversion.
48 * Offset into the desc param or negative value for private flow elements.
51 rte_flow_conv_copy(void *buf, const void *data, const size_t size,
52 const struct rte_flow_desc_data *desc, int type)
55 * Allow PMD private flow item
57 bool rte_type = type >= 0;
59 size_t sz = rte_type ? desc[type].size : sizeof(void *);
60 if (buf == NULL || data == NULL)
62 rte_memcpy(buf, data, (size > sz ? sz : size));
63 if (rte_type && desc[type].desc_fn)
64 sz += desc[type].desc_fn(size > 0 ? buf : NULL, data);
69 rte_flow_item_flex_conv(void *buf, const void *data)
71 struct rte_flow_item_flex *dst = buf;
72 const struct rte_flow_item_flex *src = data;
74 dst->pattern = rte_memcpy
75 ((void *)((uintptr_t)(dst + 1)), src->pattern,
81 /** Generate flow_item[] entry. */
82 #define MK_FLOW_ITEM(t, s) \
83 [RTE_FLOW_ITEM_TYPE_ ## t] = { \
89 #define MK_FLOW_ITEM_FN(t, s, fn) \
90 [RTE_FLOW_ITEM_TYPE_ ## t] = {\
96 /** Information about known flow pattern items. */
97 static const struct rte_flow_desc_data rte_flow_desc_item[] = {
99 MK_FLOW_ITEM(VOID, 0),
100 MK_FLOW_ITEM(INVERT, 0),
101 MK_FLOW_ITEM(ANY, sizeof(struct rte_flow_item_any)),
103 MK_FLOW_ITEM(VF, sizeof(struct rte_flow_item_vf)),
104 MK_FLOW_ITEM(PHY_PORT, sizeof(struct rte_flow_item_phy_port)),
105 MK_FLOW_ITEM(PORT_ID, sizeof(struct rte_flow_item_port_id)),
106 MK_FLOW_ITEM(RAW, sizeof(struct rte_flow_item_raw)),
107 MK_FLOW_ITEM(ETH, sizeof(struct rte_flow_item_eth)),
108 MK_FLOW_ITEM(VLAN, sizeof(struct rte_flow_item_vlan)),
109 MK_FLOW_ITEM(IPV4, sizeof(struct rte_flow_item_ipv4)),
110 MK_FLOW_ITEM(IPV6, sizeof(struct rte_flow_item_ipv6)),
111 MK_FLOW_ITEM(ICMP, sizeof(struct rte_flow_item_icmp)),
112 MK_FLOW_ITEM(UDP, sizeof(struct rte_flow_item_udp)),
113 MK_FLOW_ITEM(TCP, sizeof(struct rte_flow_item_tcp)),
114 MK_FLOW_ITEM(SCTP, sizeof(struct rte_flow_item_sctp)),
115 MK_FLOW_ITEM(VXLAN, sizeof(struct rte_flow_item_vxlan)),
116 MK_FLOW_ITEM(E_TAG, sizeof(struct rte_flow_item_e_tag)),
117 MK_FLOW_ITEM(NVGRE, sizeof(struct rte_flow_item_nvgre)),
118 MK_FLOW_ITEM(MPLS, sizeof(struct rte_flow_item_mpls)),
119 MK_FLOW_ITEM(GRE, sizeof(struct rte_flow_item_gre)),
120 MK_FLOW_ITEM(FUZZY, sizeof(struct rte_flow_item_fuzzy)),
121 MK_FLOW_ITEM(GTP, sizeof(struct rte_flow_item_gtp)),
122 MK_FLOW_ITEM(GTPC, sizeof(struct rte_flow_item_gtp)),
123 MK_FLOW_ITEM(GTPU, sizeof(struct rte_flow_item_gtp)),
124 MK_FLOW_ITEM(ESP, sizeof(struct rte_flow_item_esp)),
125 MK_FLOW_ITEM(GENEVE, sizeof(struct rte_flow_item_geneve)),
126 MK_FLOW_ITEM(VXLAN_GPE, sizeof(struct rte_flow_item_vxlan_gpe)),
127 MK_FLOW_ITEM(ARP_ETH_IPV4, sizeof(struct rte_flow_item_arp_eth_ipv4)),
128 MK_FLOW_ITEM(IPV6_EXT, sizeof(struct rte_flow_item_ipv6_ext)),
129 MK_FLOW_ITEM(IPV6_FRAG_EXT, sizeof(struct rte_flow_item_ipv6_frag_ext)),
130 MK_FLOW_ITEM(ICMP6, sizeof(struct rte_flow_item_icmp6)),
131 MK_FLOW_ITEM(ICMP6_ND_NS, sizeof(struct rte_flow_item_icmp6_nd_ns)),
132 MK_FLOW_ITEM(ICMP6_ND_NA, sizeof(struct rte_flow_item_icmp6_nd_na)),
133 MK_FLOW_ITEM(ICMP6_ND_OPT, sizeof(struct rte_flow_item_icmp6_nd_opt)),
134 MK_FLOW_ITEM(ICMP6_ND_OPT_SLA_ETH,
135 sizeof(struct rte_flow_item_icmp6_nd_opt_sla_eth)),
136 MK_FLOW_ITEM(ICMP6_ND_OPT_TLA_ETH,
137 sizeof(struct rte_flow_item_icmp6_nd_opt_tla_eth)),
138 MK_FLOW_ITEM(MARK, sizeof(struct rte_flow_item_mark)),
139 MK_FLOW_ITEM(META, sizeof(struct rte_flow_item_meta)),
140 MK_FLOW_ITEM(TAG, sizeof(struct rte_flow_item_tag)),
141 MK_FLOW_ITEM(GRE_KEY, sizeof(rte_be32_t)),
142 MK_FLOW_ITEM(GTP_PSC, sizeof(struct rte_flow_item_gtp_psc)),
143 MK_FLOW_ITEM(PPPOES, sizeof(struct rte_flow_item_pppoe)),
144 MK_FLOW_ITEM(PPPOED, sizeof(struct rte_flow_item_pppoe)),
145 MK_FLOW_ITEM(PPPOE_PROTO_ID,
146 sizeof(struct rte_flow_item_pppoe_proto_id)),
147 MK_FLOW_ITEM(NSH, sizeof(struct rte_flow_item_nsh)),
148 MK_FLOW_ITEM(IGMP, sizeof(struct rte_flow_item_igmp)),
149 MK_FLOW_ITEM(AH, sizeof(struct rte_flow_item_ah)),
150 MK_FLOW_ITEM(HIGIG2, sizeof(struct rte_flow_item_higig2_hdr)),
151 MK_FLOW_ITEM(L2TPV3OIP, sizeof(struct rte_flow_item_l2tpv3oip)),
152 MK_FLOW_ITEM(PFCP, sizeof(struct rte_flow_item_pfcp)),
153 MK_FLOW_ITEM(ECPRI, sizeof(struct rte_flow_item_ecpri)),
154 MK_FLOW_ITEM(GENEVE_OPT, sizeof(struct rte_flow_item_geneve_opt)),
155 MK_FLOW_ITEM(INTEGRITY, sizeof(struct rte_flow_item_integrity)),
156 MK_FLOW_ITEM(CONNTRACK, sizeof(uint32_t)),
157 MK_FLOW_ITEM(PORT_REPRESENTOR, sizeof(struct rte_flow_item_ethdev)),
158 MK_FLOW_ITEM(REPRESENTED_PORT, sizeof(struct rte_flow_item_ethdev)),
159 MK_FLOW_ITEM_FN(FLEX, sizeof(struct rte_flow_item_flex),
160 rte_flow_item_flex_conv),
161 MK_FLOW_ITEM(L2TPV2, sizeof(struct rte_flow_item_l2tpv2)),
162 MK_FLOW_ITEM(PPP, sizeof(struct rte_flow_item_ppp)),
165 /** Generate flow_action[] entry. */
166 #define MK_FLOW_ACTION(t, s) \
167 [RTE_FLOW_ACTION_TYPE_ ## t] = { \
173 #define MK_FLOW_ACTION_FN(t, fn) \
174 [RTE_FLOW_ACTION_TYPE_ ## t] = { \
181 /** Information about known flow actions. */
182 static const struct rte_flow_desc_data rte_flow_desc_action[] = {
183 MK_FLOW_ACTION(END, 0),
184 MK_FLOW_ACTION(VOID, 0),
185 MK_FLOW_ACTION(PASSTHRU, 0),
186 MK_FLOW_ACTION(JUMP, sizeof(struct rte_flow_action_jump)),
187 MK_FLOW_ACTION(MARK, sizeof(struct rte_flow_action_mark)),
188 MK_FLOW_ACTION(FLAG, 0),
189 MK_FLOW_ACTION(QUEUE, sizeof(struct rte_flow_action_queue)),
190 MK_FLOW_ACTION(DROP, 0),
191 MK_FLOW_ACTION(COUNT, sizeof(struct rte_flow_action_count)),
192 MK_FLOW_ACTION(RSS, sizeof(struct rte_flow_action_rss)),
193 MK_FLOW_ACTION(PF, 0),
194 MK_FLOW_ACTION(VF, sizeof(struct rte_flow_action_vf)),
195 MK_FLOW_ACTION(PHY_PORT, sizeof(struct rte_flow_action_phy_port)),
196 MK_FLOW_ACTION(PORT_ID, sizeof(struct rte_flow_action_port_id)),
197 MK_FLOW_ACTION(METER, sizeof(struct rte_flow_action_meter)),
198 MK_FLOW_ACTION(SECURITY, sizeof(struct rte_flow_action_security)),
199 MK_FLOW_ACTION(OF_SET_MPLS_TTL,
200 sizeof(struct rte_flow_action_of_set_mpls_ttl)),
201 MK_FLOW_ACTION(OF_DEC_MPLS_TTL, 0),
202 MK_FLOW_ACTION(OF_SET_NW_TTL,
203 sizeof(struct rte_flow_action_of_set_nw_ttl)),
204 MK_FLOW_ACTION(OF_DEC_NW_TTL, 0),
205 MK_FLOW_ACTION(OF_COPY_TTL_OUT, 0),
206 MK_FLOW_ACTION(OF_COPY_TTL_IN, 0),
207 MK_FLOW_ACTION(OF_POP_VLAN, 0),
208 MK_FLOW_ACTION(OF_PUSH_VLAN,
209 sizeof(struct rte_flow_action_of_push_vlan)),
210 MK_FLOW_ACTION(OF_SET_VLAN_VID,
211 sizeof(struct rte_flow_action_of_set_vlan_vid)),
212 MK_FLOW_ACTION(OF_SET_VLAN_PCP,
213 sizeof(struct rte_flow_action_of_set_vlan_pcp)),
214 MK_FLOW_ACTION(OF_POP_MPLS,
215 sizeof(struct rte_flow_action_of_pop_mpls)),
216 MK_FLOW_ACTION(OF_PUSH_MPLS,
217 sizeof(struct rte_flow_action_of_push_mpls)),
218 MK_FLOW_ACTION(VXLAN_ENCAP, sizeof(struct rte_flow_action_vxlan_encap)),
219 MK_FLOW_ACTION(VXLAN_DECAP, 0),
220 MK_FLOW_ACTION(NVGRE_ENCAP, sizeof(struct rte_flow_action_vxlan_encap)),
221 MK_FLOW_ACTION(NVGRE_DECAP, 0),
222 MK_FLOW_ACTION(RAW_ENCAP, sizeof(struct rte_flow_action_raw_encap)),
223 MK_FLOW_ACTION(RAW_DECAP, sizeof(struct rte_flow_action_raw_decap)),
224 MK_FLOW_ACTION(SET_IPV4_SRC,
225 sizeof(struct rte_flow_action_set_ipv4)),
226 MK_FLOW_ACTION(SET_IPV4_DST,
227 sizeof(struct rte_flow_action_set_ipv4)),
228 MK_FLOW_ACTION(SET_IPV6_SRC,
229 sizeof(struct rte_flow_action_set_ipv6)),
230 MK_FLOW_ACTION(SET_IPV6_DST,
231 sizeof(struct rte_flow_action_set_ipv6)),
232 MK_FLOW_ACTION(SET_TP_SRC,
233 sizeof(struct rte_flow_action_set_tp)),
234 MK_FLOW_ACTION(SET_TP_DST,
235 sizeof(struct rte_flow_action_set_tp)),
236 MK_FLOW_ACTION(MAC_SWAP, 0),
237 MK_FLOW_ACTION(DEC_TTL, 0),
238 MK_FLOW_ACTION(SET_TTL, sizeof(struct rte_flow_action_set_ttl)),
239 MK_FLOW_ACTION(SET_MAC_SRC, sizeof(struct rte_flow_action_set_mac)),
240 MK_FLOW_ACTION(SET_MAC_DST, sizeof(struct rte_flow_action_set_mac)),
241 MK_FLOW_ACTION(INC_TCP_SEQ, sizeof(rte_be32_t)),
242 MK_FLOW_ACTION(DEC_TCP_SEQ, sizeof(rte_be32_t)),
243 MK_FLOW_ACTION(INC_TCP_ACK, sizeof(rte_be32_t)),
244 MK_FLOW_ACTION(DEC_TCP_ACK, sizeof(rte_be32_t)),
245 MK_FLOW_ACTION(SET_TAG, sizeof(struct rte_flow_action_set_tag)),
246 MK_FLOW_ACTION(SET_META, sizeof(struct rte_flow_action_set_meta)),
247 MK_FLOW_ACTION(SET_IPV4_DSCP, sizeof(struct rte_flow_action_set_dscp)),
248 MK_FLOW_ACTION(SET_IPV6_DSCP, sizeof(struct rte_flow_action_set_dscp)),
249 MK_FLOW_ACTION(AGE, sizeof(struct rte_flow_action_age)),
250 MK_FLOW_ACTION(SAMPLE, sizeof(struct rte_flow_action_sample)),
251 MK_FLOW_ACTION(MODIFY_FIELD,
252 sizeof(struct rte_flow_action_modify_field)),
254 * Indirect action represented as handle of type
255 * (struct rte_flow_action_handle *) stored in conf field (see
256 * struct rte_flow_action); no need for additional structure to * store
257 * indirect action handle.
259 MK_FLOW_ACTION(INDIRECT, 0),
260 MK_FLOW_ACTION(CONNTRACK, sizeof(struct rte_flow_action_conntrack)),
261 MK_FLOW_ACTION(PORT_REPRESENTOR, sizeof(struct rte_flow_action_ethdev)),
262 MK_FLOW_ACTION(REPRESENTED_PORT, sizeof(struct rte_flow_action_ethdev)),
266 rte_flow_dynf_metadata_register(void)
271 static const struct rte_mbuf_dynfield desc_offs = {
272 .name = RTE_MBUF_DYNFIELD_METADATA_NAME,
273 .size = sizeof(uint32_t),
274 .align = __alignof__(uint32_t),
276 static const struct rte_mbuf_dynflag desc_flag = {
277 .name = RTE_MBUF_DYNFLAG_METADATA_NAME,
280 offset = rte_mbuf_dynfield_register(&desc_offs);
283 flag = rte_mbuf_dynflag_register(&desc_flag);
286 rte_flow_dynf_metadata_offs = offset;
287 rte_flow_dynf_metadata_mask = RTE_BIT64(flag);
291 rte_flow_dynf_metadata_offs = -1;
292 rte_flow_dynf_metadata_mask = UINT64_C(0);
297 fts_enter(struct rte_eth_dev *dev)
299 if (!(dev->data->dev_flags & RTE_ETH_DEV_FLOW_OPS_THREAD_SAFE))
300 pthread_mutex_lock(&dev->data->flow_ops_mutex);
304 fts_exit(struct rte_eth_dev *dev)
306 if (!(dev->data->dev_flags & RTE_ETH_DEV_FLOW_OPS_THREAD_SAFE))
307 pthread_mutex_unlock(&dev->data->flow_ops_mutex);
311 flow_err(uint16_t port_id, int ret, struct rte_flow_error *error)
315 if (rte_eth_dev_is_removed(port_id))
316 return rte_flow_error_set(error, EIO,
317 RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
318 NULL, rte_strerror(EIO));
322 /* Get generic flow operations structure from a port. */
323 const struct rte_flow_ops *
324 rte_flow_ops_get(uint16_t port_id, struct rte_flow_error *error)
326 struct rte_eth_dev *dev = &rte_eth_devices[port_id];
327 const struct rte_flow_ops *ops;
330 if (unlikely(!rte_eth_dev_is_valid_port(port_id)))
332 else if (unlikely(dev->dev_ops->flow_ops_get == NULL))
333 /* flow API not supported with this driver dev_ops */
336 code = dev->dev_ops->flow_ops_get(dev, &ops);
337 if (code == 0 && ops == NULL)
338 /* flow API not supported with this device */
342 rte_flow_error_set(error, code, RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
343 NULL, rte_strerror(code));
349 /* Check whether a flow rule can be created on a given port. */
351 rte_flow_validate(uint16_t port_id,
352 const struct rte_flow_attr *attr,
353 const struct rte_flow_item pattern[],
354 const struct rte_flow_action actions[],
355 struct rte_flow_error *error)
357 const struct rte_flow_ops *ops = rte_flow_ops_get(port_id, error);
358 struct rte_eth_dev *dev = &rte_eth_devices[port_id];
363 if (likely(!!ops->validate)) {
365 ret = ops->validate(dev, attr, pattern, actions, error);
367 return flow_err(port_id, ret, error);
369 return rte_flow_error_set(error, ENOSYS,
370 RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
371 NULL, rte_strerror(ENOSYS));
374 /* Create a flow rule on a given port. */
376 rte_flow_create(uint16_t port_id,
377 const struct rte_flow_attr *attr,
378 const struct rte_flow_item pattern[],
379 const struct rte_flow_action actions[],
380 struct rte_flow_error *error)
382 struct rte_eth_dev *dev = &rte_eth_devices[port_id];
383 struct rte_flow *flow;
384 const struct rte_flow_ops *ops = rte_flow_ops_get(port_id, error);
388 if (likely(!!ops->create)) {
390 flow = ops->create(dev, attr, pattern, actions, error);
393 flow_err(port_id, -rte_errno, error);
396 rte_flow_error_set(error, ENOSYS, RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
397 NULL, rte_strerror(ENOSYS));
401 /* Destroy a flow rule on a given port. */
403 rte_flow_destroy(uint16_t port_id,
404 struct rte_flow *flow,
405 struct rte_flow_error *error)
407 struct rte_eth_dev *dev = &rte_eth_devices[port_id];
408 const struct rte_flow_ops *ops = rte_flow_ops_get(port_id, error);
413 if (likely(!!ops->destroy)) {
415 ret = ops->destroy(dev, flow, error);
417 return flow_err(port_id, ret, error);
419 return rte_flow_error_set(error, ENOSYS,
420 RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
421 NULL, rte_strerror(ENOSYS));
424 /* Destroy all flow rules associated with a port. */
426 rte_flow_flush(uint16_t port_id,
427 struct rte_flow_error *error)
429 struct rte_eth_dev *dev = &rte_eth_devices[port_id];
430 const struct rte_flow_ops *ops = rte_flow_ops_get(port_id, error);
435 if (likely(!!ops->flush)) {
437 ret = ops->flush(dev, error);
439 return flow_err(port_id, ret, error);
441 return rte_flow_error_set(error, ENOSYS,
442 RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
443 NULL, rte_strerror(ENOSYS));
446 /* Query an existing flow rule. */
448 rte_flow_query(uint16_t port_id,
449 struct rte_flow *flow,
450 const struct rte_flow_action *action,
452 struct rte_flow_error *error)
454 struct rte_eth_dev *dev = &rte_eth_devices[port_id];
455 const struct rte_flow_ops *ops = rte_flow_ops_get(port_id, error);
460 if (likely(!!ops->query)) {
462 ret = ops->query(dev, flow, action, data, error);
464 return flow_err(port_id, ret, error);
466 return rte_flow_error_set(error, ENOSYS,
467 RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
468 NULL, rte_strerror(ENOSYS));
471 /* Restrict ingress traffic to the defined flow rules. */
473 rte_flow_isolate(uint16_t port_id,
475 struct rte_flow_error *error)
477 struct rte_eth_dev *dev = &rte_eth_devices[port_id];
478 const struct rte_flow_ops *ops = rte_flow_ops_get(port_id, error);
483 if (likely(!!ops->isolate)) {
485 ret = ops->isolate(dev, set, error);
487 return flow_err(port_id, ret, error);
489 return rte_flow_error_set(error, ENOSYS,
490 RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
491 NULL, rte_strerror(ENOSYS));
494 /* Initialize flow error structure. */
496 rte_flow_error_set(struct rte_flow_error *error,
498 enum rte_flow_error_type type,
503 *error = (struct rte_flow_error){
513 /** Pattern item specification types. */
514 enum rte_flow_conv_item_spec_type {
515 RTE_FLOW_CONV_ITEM_SPEC,
516 RTE_FLOW_CONV_ITEM_LAST,
517 RTE_FLOW_CONV_ITEM_MASK,
521 * Copy pattern item specification.
524 * Output buffer. Can be NULL if @p size is zero.
526 * Size of @p buf in bytes.
528 * Pattern item to copy specification from.
530 * Specification selector for either @p spec, @p last or @p mask.
533 * Number of bytes needed to store pattern item specification regardless
534 * of @p size. @p buf contents are truncated to @p size if not large
538 rte_flow_conv_item_spec(void *buf, const size_t size,
539 const struct rte_flow_item *item,
540 enum rte_flow_conv_item_spec_type type)
544 type == RTE_FLOW_CONV_ITEM_SPEC ? item->spec :
545 type == RTE_FLOW_CONV_ITEM_LAST ? item->last :
546 type == RTE_FLOW_CONV_ITEM_MASK ? item->mask :
549 switch (item->type) {
551 const struct rte_flow_item_raw *raw;
554 const struct rte_flow_item_raw *raw;
557 const struct rte_flow_item_raw *raw;
560 const struct rte_flow_item_raw *raw;
563 struct rte_flow_item_raw *raw;
567 case RTE_FLOW_ITEM_TYPE_RAW:
568 spec.raw = item->spec;
569 last.raw = item->last ? item->last : item->spec;
570 mask.raw = item->mask ? item->mask : &rte_flow_item_raw_mask;
574 (&(struct rte_flow_item_raw){
575 .relative = src.raw->relative,
576 .search = src.raw->search,
577 .reserved = src.raw->reserved,
578 .offset = src.raw->offset,
579 .limit = src.raw->limit,
580 .length = src.raw->length,
582 size > sizeof(*dst.raw) ? sizeof(*dst.raw) : size);
583 off = sizeof(*dst.raw);
584 if (type == RTE_FLOW_CONV_ITEM_SPEC ||
585 (type == RTE_FLOW_CONV_ITEM_MASK &&
586 ((spec.raw->length & mask.raw->length) >=
587 (last.raw->length & mask.raw->length))))
588 tmp = spec.raw->length & mask.raw->length;
590 tmp = last.raw->length & mask.raw->length;
592 off = RTE_ALIGN_CEIL(off, sizeof(*dst.raw->pattern));
593 if (size >= off + tmp)
594 dst.raw->pattern = rte_memcpy
595 ((void *)((uintptr_t)dst.raw + off),
596 src.raw->pattern, tmp);
601 off = rte_flow_conv_copy(buf, data, size,
602 rte_flow_desc_item, item->type);
609 * Copy action configuration.
612 * Output buffer. Can be NULL if @p size is zero.
614 * Size of @p buf in bytes.
616 * Action to copy configuration from.
619 * Number of bytes needed to store pattern item specification regardless
620 * of @p size. @p buf contents are truncated to @p size if not large
624 rte_flow_conv_action_conf(void *buf, const size_t size,
625 const struct rte_flow_action *action)
629 switch (action->type) {
631 const struct rte_flow_action_rss *rss;
632 const struct rte_flow_action_vxlan_encap *vxlan_encap;
633 const struct rte_flow_action_nvgre_encap *nvgre_encap;
636 struct rte_flow_action_rss *rss;
637 struct rte_flow_action_vxlan_encap *vxlan_encap;
638 struct rte_flow_action_nvgre_encap *nvgre_encap;
643 case RTE_FLOW_ACTION_TYPE_RSS:
644 src.rss = action->conf;
647 (&(struct rte_flow_action_rss){
648 .func = src.rss->func,
649 .level = src.rss->level,
650 .types = src.rss->types,
651 .key_len = src.rss->key_len,
652 .queue_num = src.rss->queue_num,
654 size > sizeof(*dst.rss) ? sizeof(*dst.rss) : size);
655 off = sizeof(*dst.rss);
656 if (src.rss->key_len && src.rss->key) {
657 off = RTE_ALIGN_CEIL(off, sizeof(*dst.rss->key));
658 tmp = sizeof(*src.rss->key) * src.rss->key_len;
659 if (size >= off + tmp)
660 dst.rss->key = rte_memcpy
661 ((void *)((uintptr_t)dst.rss + off),
665 if (src.rss->queue_num) {
666 off = RTE_ALIGN_CEIL(off, sizeof(*dst.rss->queue));
667 tmp = sizeof(*src.rss->queue) * src.rss->queue_num;
668 if (size >= off + tmp)
669 dst.rss->queue = rte_memcpy
670 ((void *)((uintptr_t)dst.rss + off),
671 src.rss->queue, tmp);
675 case RTE_FLOW_ACTION_TYPE_VXLAN_ENCAP:
676 case RTE_FLOW_ACTION_TYPE_NVGRE_ENCAP:
677 src.vxlan_encap = action->conf;
678 dst.vxlan_encap = buf;
679 RTE_BUILD_BUG_ON(sizeof(*src.vxlan_encap) !=
680 sizeof(*src.nvgre_encap) ||
681 offsetof(struct rte_flow_action_vxlan_encap,
683 offsetof(struct rte_flow_action_nvgre_encap,
685 off = sizeof(*dst.vxlan_encap);
686 if (src.vxlan_encap->definition) {
688 (off, sizeof(*dst.vxlan_encap->definition));
690 (RTE_FLOW_CONV_OP_PATTERN,
691 (void *)((uintptr_t)dst.vxlan_encap + off),
692 size > off ? size - off : 0,
693 src.vxlan_encap->definition, NULL);
696 if (size >= off + ret)
697 dst.vxlan_encap->definition =
698 (void *)((uintptr_t)dst.vxlan_encap +
704 off = rte_flow_conv_copy(buf, action->conf, size,
705 rte_flow_desc_action, action->type);
712 * Copy a list of pattern items.
715 * Destination buffer. Can be NULL if @p size is zero.
717 * Size of @p dst in bytes.
719 * Source pattern items.
721 * Maximum number of pattern items to process from @p src or 0 to process
722 * the entire list. In both cases, processing stops after
723 * RTE_FLOW_ITEM_TYPE_END is encountered.
725 * Perform verbose error reporting if not NULL.
728 * A positive value representing the number of bytes needed to store
729 * pattern items regardless of @p size on success (@p buf contents are
730 * truncated to @p size if not large enough), a negative errno value
731 * otherwise and rte_errno is set.
734 rte_flow_conv_pattern(struct rte_flow_item *dst,
736 const struct rte_flow_item *src,
738 struct rte_flow_error *error)
740 uintptr_t data = (uintptr_t)dst;
745 for (i = 0, off = 0; !num || i != num; ++i, ++src, ++dst) {
747 * allow PMD private flow item
749 if (((int)src->type >= 0) &&
750 ((size_t)src->type >= RTE_DIM(rte_flow_desc_item) ||
751 !rte_flow_desc_item[src->type].name))
752 return rte_flow_error_set
753 (error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ITEM, src,
754 "cannot convert unknown item type");
755 if (size >= off + sizeof(*dst))
756 *dst = (struct rte_flow_item){
768 off = RTE_ALIGN_CEIL(off, sizeof(double));
769 ret = rte_flow_conv_item_spec
770 ((void *)(data + off),
771 size > off ? size - off : 0, src,
772 RTE_FLOW_CONV_ITEM_SPEC);
773 if (size && size >= off + ret)
774 dst->spec = (void *)(data + off);
779 off = RTE_ALIGN_CEIL(off, sizeof(double));
780 ret = rte_flow_conv_item_spec
781 ((void *)(data + off),
782 size > off ? size - off : 0, src,
783 RTE_FLOW_CONV_ITEM_LAST);
784 if (size && size >= off + ret)
785 dst->last = (void *)(data + off);
789 off = RTE_ALIGN_CEIL(off, sizeof(double));
790 ret = rte_flow_conv_item_spec
791 ((void *)(data + off),
792 size > off ? size - off : 0, src,
793 RTE_FLOW_CONV_ITEM_MASK);
794 if (size && size >= off + ret)
795 dst->mask = (void *)(data + off);
805 * Copy a list of actions.
808 * Destination buffer. Can be NULL if @p size is zero.
810 * Size of @p dst in bytes.
814 * Maximum number of actions to process from @p src or 0 to process the
815 * entire list. In both cases, processing stops after
816 * RTE_FLOW_ACTION_TYPE_END is encountered.
818 * Perform verbose error reporting if not NULL.
821 * A positive value representing the number of bytes needed to store
822 * actions regardless of @p size on success (@p buf contents are truncated
823 * to @p size if not large enough), a negative errno value otherwise and
827 rte_flow_conv_actions(struct rte_flow_action *dst,
829 const struct rte_flow_action *src,
831 struct rte_flow_error *error)
833 uintptr_t data = (uintptr_t)dst;
838 for (i = 0, off = 0; !num || i != num; ++i, ++src, ++dst) {
840 * allow PMD private flow action
842 if (((int)src->type >= 0) &&
843 ((size_t)src->type >= RTE_DIM(rte_flow_desc_action) ||
844 !rte_flow_desc_action[src->type].name))
845 return rte_flow_error_set
846 (error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ACTION,
847 src, "cannot convert unknown action type");
848 if (size >= off + sizeof(*dst))
849 *dst = (struct rte_flow_action){
861 off = RTE_ALIGN_CEIL(off, sizeof(double));
862 ret = rte_flow_conv_action_conf
863 ((void *)(data + off),
864 size > off ? size - off : 0, src);
865 if (size && size >= off + ret)
866 dst->conf = (void *)(data + off);
876 * Copy flow rule components.
878 * This comprises the flow rule descriptor itself, attributes, pattern and
879 * actions list. NULL components in @p src are skipped.
882 * Destination buffer. Can be NULL if @p size is zero.
884 * Size of @p dst in bytes.
886 * Source flow rule descriptor.
888 * Perform verbose error reporting if not NULL.
891 * A positive value representing the number of bytes needed to store all
892 * components including the descriptor regardless of @p size on success
893 * (@p buf contents are truncated to @p size if not large enough), a
894 * negative errno value otherwise and rte_errno is set.
897 rte_flow_conv_rule(struct rte_flow_conv_rule *dst,
899 const struct rte_flow_conv_rule *src,
900 struct rte_flow_error *error)
906 (&(struct rte_flow_conv_rule){
911 size > sizeof(*dst) ? sizeof(*dst) : size);
914 off = RTE_ALIGN_CEIL(off, sizeof(double));
915 if (size && size >= off + sizeof(*dst->attr))
916 dst->attr = rte_memcpy
917 ((void *)((uintptr_t)dst + off),
918 src->attr_ro, sizeof(*dst->attr));
919 off += sizeof(*dst->attr);
921 if (src->pattern_ro) {
922 off = RTE_ALIGN_CEIL(off, sizeof(double));
923 ret = rte_flow_conv_pattern((void *)((uintptr_t)dst + off),
924 size > off ? size - off : 0,
925 src->pattern_ro, 0, error);
928 if (size && size >= off + (size_t)ret)
929 dst->pattern = (void *)((uintptr_t)dst + off);
932 if (src->actions_ro) {
933 off = RTE_ALIGN_CEIL(off, sizeof(double));
934 ret = rte_flow_conv_actions((void *)((uintptr_t)dst + off),
935 size > off ? size - off : 0,
936 src->actions_ro, 0, error);
939 if (size >= off + (size_t)ret)
940 dst->actions = (void *)((uintptr_t)dst + off);
947 * Retrieve the name of a pattern item/action type.
950 * Nonzero when @p src represents an action type instead of a pattern item
953 * Nonzero to write string address instead of contents into @p dst.
955 * Destination buffer. Can be NULL if @p size is zero.
957 * Size of @p dst in bytes.
959 * Depending on @p is_action, source pattern item or action type cast as a
962 * Perform verbose error reporting if not NULL.
965 * A positive value representing the number of bytes needed to store the
966 * name or its address regardless of @p size on success (@p buf contents
967 * are truncated to @p size if not large enough), a negative errno value
968 * otherwise and rte_errno is set.
971 rte_flow_conv_name(int is_action,
976 struct rte_flow_error *error)
979 const struct rte_flow_desc_data *data;
982 static const struct desc_info info_rep[2] = {
983 { rte_flow_desc_item, RTE_DIM(rte_flow_desc_item), },
984 { rte_flow_desc_action, RTE_DIM(rte_flow_desc_action), },
986 const struct desc_info *const info = &info_rep[!!is_action];
987 unsigned int type = (uintptr_t)src;
989 if (type >= info->num)
990 return rte_flow_error_set
991 (error, EINVAL, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
992 "unknown object type to retrieve the name of");
994 return strlcpy(dst, info->data[type].name, size);
995 if (size >= sizeof(const char **))
996 *((const char **)dst) = info->data[type].name;
997 return sizeof(const char **);
1000 /** Helper function to convert flow API objects. */
1002 rte_flow_conv(enum rte_flow_conv_op op,
1006 struct rte_flow_error *error)
1009 const struct rte_flow_attr *attr;
1011 case RTE_FLOW_CONV_OP_NONE:
1013 case RTE_FLOW_CONV_OP_ATTR:
1015 if (size > sizeof(*attr))
1016 size = sizeof(*attr);
1017 rte_memcpy(dst, attr, size);
1018 return sizeof(*attr);
1019 case RTE_FLOW_CONV_OP_ITEM:
1020 return rte_flow_conv_pattern(dst, size, src, 1, error);
1021 case RTE_FLOW_CONV_OP_ACTION:
1022 return rte_flow_conv_actions(dst, size, src, 1, error);
1023 case RTE_FLOW_CONV_OP_PATTERN:
1024 return rte_flow_conv_pattern(dst, size, src, 0, error);
1025 case RTE_FLOW_CONV_OP_ACTIONS:
1026 return rte_flow_conv_actions(dst, size, src, 0, error);
1027 case RTE_FLOW_CONV_OP_RULE:
1028 return rte_flow_conv_rule(dst, size, src, error);
1029 case RTE_FLOW_CONV_OP_ITEM_NAME:
1030 return rte_flow_conv_name(0, 0, dst, size, src, error);
1031 case RTE_FLOW_CONV_OP_ACTION_NAME:
1032 return rte_flow_conv_name(1, 0, dst, size, src, error);
1033 case RTE_FLOW_CONV_OP_ITEM_NAME_PTR:
1034 return rte_flow_conv_name(0, 1, dst, size, src, error);
1035 case RTE_FLOW_CONV_OP_ACTION_NAME_PTR:
1036 return rte_flow_conv_name(1, 1, dst, size, src, error);
1038 return rte_flow_error_set
1039 (error, ENOTSUP, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
1040 "unknown object conversion operation");
1043 /** Store a full rte_flow description. */
1045 rte_flow_copy(struct rte_flow_desc *desc, size_t len,
1046 const struct rte_flow_attr *attr,
1047 const struct rte_flow_item *items,
1048 const struct rte_flow_action *actions)
1051 * Overlap struct rte_flow_conv with struct rte_flow_desc in order
1052 * to convert the former to the latter without wasting space.
1054 struct rte_flow_conv_rule *dst =
1056 (void *)((uintptr_t)desc +
1057 (offsetof(struct rte_flow_desc, actions) -
1058 offsetof(struct rte_flow_conv_rule, actions))) :
1061 len > sizeof(*desc) - sizeof(*dst) ?
1062 len - (sizeof(*desc) - sizeof(*dst)) :
1064 struct rte_flow_conv_rule src = {
1066 .pattern_ro = items,
1067 .actions_ro = actions,
1071 RTE_BUILD_BUG_ON(sizeof(struct rte_flow_desc) <
1072 sizeof(struct rte_flow_conv_rule));
1074 (&dst->pattern != &desc->items ||
1075 &dst->actions != &desc->actions ||
1076 (uintptr_t)(dst + 1) != (uintptr_t)(desc + 1))) {
1080 ret = rte_flow_conv(RTE_FLOW_CONV_OP_RULE, dst, dst_size, &src, NULL);
1083 ret += sizeof(*desc) - sizeof(*dst);
1085 (&(struct rte_flow_desc){
1088 .items = dst_size ? dst->pattern : NULL,
1089 .actions = dst_size ? dst->actions : NULL,
1091 len > sizeof(*desc) ? sizeof(*desc) : len);
1096 rte_flow_dev_dump(uint16_t port_id, struct rte_flow *flow,
1097 FILE *file, struct rte_flow_error *error)
1099 struct rte_eth_dev *dev = &rte_eth_devices[port_id];
1100 const struct rte_flow_ops *ops = rte_flow_ops_get(port_id, error);
1105 if (likely(!!ops->dev_dump)) {
1107 ret = ops->dev_dump(dev, flow, file, error);
1109 return flow_err(port_id, ret, error);
1111 return rte_flow_error_set(error, ENOSYS,
1112 RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
1113 NULL, rte_strerror(ENOSYS));
1117 rte_flow_get_aged_flows(uint16_t port_id, void **contexts,
1118 uint32_t nb_contexts, struct rte_flow_error *error)
1120 struct rte_eth_dev *dev = &rte_eth_devices[port_id];
1121 const struct rte_flow_ops *ops = rte_flow_ops_get(port_id, error);
1126 if (likely(!!ops->get_aged_flows)) {
1128 ret = ops->get_aged_flows(dev, contexts, nb_contexts, error);
1130 return flow_err(port_id, ret, error);
1132 return rte_flow_error_set(error, ENOTSUP,
1133 RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
1134 NULL, rte_strerror(ENOTSUP));
1137 struct rte_flow_action_handle *
1138 rte_flow_action_handle_create(uint16_t port_id,
1139 const struct rte_flow_indir_action_conf *conf,
1140 const struct rte_flow_action *action,
1141 struct rte_flow_error *error)
1143 struct rte_flow_action_handle *handle;
1144 const struct rte_flow_ops *ops = rte_flow_ops_get(port_id, error);
1148 if (unlikely(!ops->action_handle_create)) {
1149 rte_flow_error_set(error, ENOSYS,
1150 RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
1151 rte_strerror(ENOSYS));
1154 handle = ops->action_handle_create(&rte_eth_devices[port_id],
1155 conf, action, error);
1157 flow_err(port_id, -rte_errno, error);
1162 rte_flow_action_handle_destroy(uint16_t port_id,
1163 struct rte_flow_action_handle *handle,
1164 struct rte_flow_error *error)
1167 const struct rte_flow_ops *ops = rte_flow_ops_get(port_id, error);
1171 if (unlikely(!ops->action_handle_destroy))
1172 return rte_flow_error_set(error, ENOSYS,
1173 RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
1174 NULL, rte_strerror(ENOSYS));
1175 ret = ops->action_handle_destroy(&rte_eth_devices[port_id],
1177 return flow_err(port_id, ret, error);
1181 rte_flow_action_handle_update(uint16_t port_id,
1182 struct rte_flow_action_handle *handle,
1184 struct rte_flow_error *error)
1187 const struct rte_flow_ops *ops = rte_flow_ops_get(port_id, error);
1191 if (unlikely(!ops->action_handle_update))
1192 return rte_flow_error_set(error, ENOSYS,
1193 RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
1194 NULL, rte_strerror(ENOSYS));
1195 ret = ops->action_handle_update(&rte_eth_devices[port_id], handle,
1197 return flow_err(port_id, ret, error);
1201 rte_flow_action_handle_query(uint16_t port_id,
1202 const struct rte_flow_action_handle *handle,
1204 struct rte_flow_error *error)
1207 const struct rte_flow_ops *ops = rte_flow_ops_get(port_id, error);
1211 if (unlikely(!ops->action_handle_query))
1212 return rte_flow_error_set(error, ENOSYS,
1213 RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
1214 NULL, rte_strerror(ENOSYS));
1215 ret = ops->action_handle_query(&rte_eth_devices[port_id], handle,
1217 return flow_err(port_id, ret, error);
1221 rte_flow_tunnel_decap_set(uint16_t port_id,
1222 struct rte_flow_tunnel *tunnel,
1223 struct rte_flow_action **actions,
1224 uint32_t *num_of_actions,
1225 struct rte_flow_error *error)
1227 struct rte_eth_dev *dev = &rte_eth_devices[port_id];
1228 const struct rte_flow_ops *ops = rte_flow_ops_get(port_id, error);
1232 if (likely(!!ops->tunnel_decap_set)) {
1233 return flow_err(port_id,
1234 ops->tunnel_decap_set(dev, tunnel, actions,
1235 num_of_actions, error),
1238 return rte_flow_error_set(error, ENOTSUP,
1239 RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
1240 NULL, rte_strerror(ENOTSUP));
1244 rte_flow_tunnel_match(uint16_t port_id,
1245 struct rte_flow_tunnel *tunnel,
1246 struct rte_flow_item **items,
1247 uint32_t *num_of_items,
1248 struct rte_flow_error *error)
1250 struct rte_eth_dev *dev = &rte_eth_devices[port_id];
1251 const struct rte_flow_ops *ops = rte_flow_ops_get(port_id, error);
1255 if (likely(!!ops->tunnel_match)) {
1256 return flow_err(port_id,
1257 ops->tunnel_match(dev, tunnel, items,
1258 num_of_items, error),
1261 return rte_flow_error_set(error, ENOTSUP,
1262 RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
1263 NULL, rte_strerror(ENOTSUP));
1267 rte_flow_get_restore_info(uint16_t port_id,
1269 struct rte_flow_restore_info *restore_info,
1270 struct rte_flow_error *error)
1272 struct rte_eth_dev *dev = &rte_eth_devices[port_id];
1273 const struct rte_flow_ops *ops = rte_flow_ops_get(port_id, error);
1277 if (likely(!!ops->get_restore_info)) {
1278 return flow_err(port_id,
1279 ops->get_restore_info(dev, m, restore_info,
1283 return rte_flow_error_set(error, ENOTSUP,
1284 RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
1285 NULL, rte_strerror(ENOTSUP));
1289 rte_flow_tunnel_action_decap_release(uint16_t port_id,
1290 struct rte_flow_action *actions,
1291 uint32_t num_of_actions,
1292 struct rte_flow_error *error)
1294 struct rte_eth_dev *dev = &rte_eth_devices[port_id];
1295 const struct rte_flow_ops *ops = rte_flow_ops_get(port_id, error);
1299 if (likely(!!ops->tunnel_action_decap_release)) {
1300 return flow_err(port_id,
1301 ops->tunnel_action_decap_release(dev, actions,
1306 return rte_flow_error_set(error, ENOTSUP,
1307 RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
1308 NULL, rte_strerror(ENOTSUP));
1312 rte_flow_tunnel_item_release(uint16_t port_id,
1313 struct rte_flow_item *items,
1314 uint32_t num_of_items,
1315 struct rte_flow_error *error)
1317 struct rte_eth_dev *dev = &rte_eth_devices[port_id];
1318 const struct rte_flow_ops *ops = rte_flow_ops_get(port_id, error);
1322 if (likely(!!ops->tunnel_item_release)) {
1323 return flow_err(port_id,
1324 ops->tunnel_item_release(dev, items,
1325 num_of_items, error),
1328 return rte_flow_error_set(error, ENOTSUP,
1329 RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
1330 NULL, rte_strerror(ENOTSUP));
1334 rte_flow_pick_transfer_proxy(uint16_t port_id, uint16_t *proxy_port_id,
1335 struct rte_flow_error *error)
1337 const struct rte_flow_ops *ops = rte_flow_ops_get(port_id, error);
1338 struct rte_eth_dev *dev;
1340 if (unlikely(ops == NULL))
1343 if (ops->pick_transfer_proxy == NULL) {
1344 *proxy_port_id = port_id;
1348 dev = &rte_eth_devices[port_id];
1350 return flow_err(port_id,
1351 ops->pick_transfer_proxy(dev, proxy_port_id, error),
1355 struct rte_flow_item_flex_handle *
1356 rte_flow_flex_item_create(uint16_t port_id,
1357 const struct rte_flow_item_flex_conf *conf,
1358 struct rte_flow_error *error)
1360 struct rte_eth_dev *dev = &rte_eth_devices[port_id];
1361 const struct rte_flow_ops *ops = rte_flow_ops_get(port_id, error);
1362 struct rte_flow_item_flex_handle *handle;
1366 if (unlikely(!ops->flex_item_create)) {
1367 rte_flow_error_set(error, ENOTSUP,
1368 RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
1369 NULL, rte_strerror(ENOTSUP));
1372 handle = ops->flex_item_create(dev, conf, error);
1374 flow_err(port_id, -rte_errno, error);
1379 rte_flow_flex_item_release(uint16_t port_id,
1380 const struct rte_flow_item_flex_handle *handle,
1381 struct rte_flow_error *error)
1384 struct rte_eth_dev *dev = &rte_eth_devices[port_id];
1385 const struct rte_flow_ops *ops = rte_flow_ops_get(port_id, error);
1387 if (unlikely(!ops || !ops->flex_item_release))
1388 return rte_flow_error_set(error, ENOTSUP,
1389 RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
1390 NULL, rte_strerror(ENOTSUP));
1391 ret = ops->flex_item_release(dev, handle, error);
1392 return flow_err(port_id, ret, error);