X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;f=lib%2Fethdev%2Frte_flow.c;h=bcf0513b3c3ddc0299aa0660cf865c0f4a184dd3;hb=583f046dd40412c1b7045ed5e6e2b769b1bb1b8c;hp=542e40e4969dc9855be51130c60d4bc92fa845eb;hpb=88caad251c8de3a84e353b0b2a27014bc303df87;p=dpdk.git diff --git a/lib/ethdev/rte_flow.c b/lib/ethdev/rte_flow.c index 542e40e496..bcf0513b3c 100644 --- a/lib/ethdev/rte_flow.c +++ b/lib/ethdev/rte_flow.c @@ -30,13 +30,65 @@ uint64_t rte_flow_dynf_metadata_mask; struct rte_flow_desc_data { const char *name; size_t size; + size_t (*desc_fn)(void *dst, const void *src); }; +/** + * + * @param buf + * Destination memory. + * @param data + * Source memory + * @param size + * Requested copy size + * @param desc + * rte_flow_desc_item - for flow item conversion. + * rte_flow_desc_action - for flow action conversion. + * @param type + * Offset into the desc param or negative value for private flow elements. + */ +static inline size_t +rte_flow_conv_copy(void *buf, const void *data, const size_t size, + const struct rte_flow_desc_data *desc, int type) +{ + /** + * Allow PMD private flow item + */ + size_t sz = type >= 0 ? desc[type].size : sizeof(void *); + if (buf == NULL || data == NULL) + return 0; + rte_memcpy(buf, data, (size > sz ? sz : size)); + if (desc[type].desc_fn) + sz += desc[type].desc_fn(size > 0 ? buf : NULL, data); + return sz; +} + +static size_t +rte_flow_item_flex_conv(void *buf, const void *data) +{ + struct rte_flow_item_flex *dst = buf; + const struct rte_flow_item_flex *src = data; + if (buf) { + dst->pattern = rte_memcpy + ((void *)((uintptr_t)(dst + 1)), src->pattern, + src->length); + } + return src->length; +} + /** Generate flow_item[] entry. */ #define MK_FLOW_ITEM(t, s) \ [RTE_FLOW_ITEM_TYPE_ ## t] = { \ .name = # t, \ - .size = s, \ + .size = s, \ + .desc_fn = NULL,\ + } + +#define MK_FLOW_ITEM_FN(t, s, fn) \ + [RTE_FLOW_ITEM_TYPE_ ## t] = {\ + .name = # t, \ + .size = s, \ + .desc_fn = fn, \ } /** Information about known flow pattern items. */ @@ -102,6 +154,8 @@ static const struct rte_flow_desc_data rte_flow_desc_item[] = { MK_FLOW_ITEM(CONNTRACK, sizeof(uint32_t)), MK_FLOW_ITEM(PORT_REPRESENTOR, sizeof(struct rte_flow_item_ethdev)), MK_FLOW_ITEM(REPRESENTED_PORT, sizeof(struct rte_flow_item_ethdev)), + MK_FLOW_ITEM_FN(FLEX, sizeof(struct rte_flow_item_flex), + rte_flow_item_flex_conv), }; /** Generate flow_action[] entry. */ @@ -109,8 +163,17 @@ static const struct rte_flow_desc_data rte_flow_desc_item[] = { [RTE_FLOW_ACTION_TYPE_ ## t] = { \ .name = # t, \ .size = s, \ + .desc_fn = NULL,\ } +#define MK_FLOW_ACTION_FN(t, fn) \ + [RTE_FLOW_ACTION_TYPE_ ## t] = { \ + .name = # t, \ + .size = 0, \ + .desc_fn = fn,\ + } + + /** Information about known flow actions. */ static const struct rte_flow_desc_data rte_flow_desc_action[] = { MK_FLOW_ACTION(END, 0), @@ -217,12 +280,12 @@ rte_flow_dynf_metadata_register(void) if (flag < 0) goto error; rte_flow_dynf_metadata_offs = offset; - rte_flow_dynf_metadata_mask = (1ULL << flag); + rte_flow_dynf_metadata_mask = RTE_BIT64(flag); return 0; error: rte_flow_dynf_metadata_offs = -1; - rte_flow_dynf_metadata_mask = 0ULL; + rte_flow_dynf_metadata_mask = UINT64_C(0); return -rte_errno; } @@ -531,12 +594,8 @@ rte_flow_conv_item_spec(void *buf, const size_t size, } break; default: - /** - * allow PMD private flow item - */ - off = (int)item->type >= 0 ? - rte_flow_desc_item[item->type].size : sizeof(void *); - rte_memcpy(buf, data, (size > off ? off : size)); + off = rte_flow_conv_copy(buf, data, size, + rte_flow_desc_item, item->type); break; } return off; @@ -638,12 +697,8 @@ rte_flow_conv_action_conf(void *buf, const size_t size, } break; default: - /** - * allow PMD private flow action - */ - off = (int)action->type >= 0 ? - rte_flow_desc_action[action->type].size : sizeof(void *); - rte_memcpy(buf, action->conf, (size > off ? off : size)); + off = rte_flow_conv_copy(buf, action->conf, size, + rte_flow_desc_action, action->type); break; } return off; @@ -1270,3 +1325,65 @@ rte_flow_tunnel_item_release(uint16_t port_id, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL, rte_strerror(ENOTSUP)); } + +int +rte_flow_pick_transfer_proxy(uint16_t port_id, uint16_t *proxy_port_id, + struct rte_flow_error *error) +{ + const struct rte_flow_ops *ops = rte_flow_ops_get(port_id, error); + struct rte_eth_dev *dev; + + if (unlikely(ops == NULL)) + return -rte_errno; + + if (ops->pick_transfer_proxy == NULL) { + *proxy_port_id = port_id; + return 0; + } + + dev = &rte_eth_devices[port_id]; + + return flow_err(port_id, + ops->pick_transfer_proxy(dev, proxy_port_id, error), + error); +} + +struct rte_flow_item_flex_handle * +rte_flow_flex_item_create(uint16_t port_id, + const struct rte_flow_item_flex_conf *conf, + struct rte_flow_error *error) +{ + struct rte_eth_dev *dev = &rte_eth_devices[port_id]; + const struct rte_flow_ops *ops = rte_flow_ops_get(port_id, error); + struct rte_flow_item_flex_handle *handle; + + if (unlikely(!ops)) + return NULL; + if (unlikely(!ops->flex_item_create)) { + rte_flow_error_set(error, ENOTSUP, + RTE_FLOW_ERROR_TYPE_UNSPECIFIED, + NULL, rte_strerror(ENOTSUP)); + return NULL; + } + handle = ops->flex_item_create(dev, conf, error); + if (handle == NULL) + flow_err(port_id, -rte_errno, error); + return handle; +} + +int +rte_flow_flex_item_release(uint16_t port_id, + const struct rte_flow_item_flex_handle *handle, + struct rte_flow_error *error) +{ + int ret; + struct rte_eth_dev *dev = &rte_eth_devices[port_id]; + const struct rte_flow_ops *ops = rte_flow_ops_get(port_id, error); + + if (unlikely(!ops || !ops->flex_item_release)) + return rte_flow_error_set(error, ENOTSUP, + RTE_FLOW_ERROR_TYPE_UNSPECIFIED, + NULL, rte_strerror(ENOTSUP)); + ret = ops->flex_item_release(dev, handle, error); + return flow_err(port_id, ret, error); +}