From patchwork Fri Aug 31 09:01:00 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Adrien Mazarguil X-Patchwork-Id: 44068 X-Patchwork-Delegate: ferruh.yigit@amd.com Return-Path: X-Original-To: patchwork@dpdk.org Delivered-To: patchwork@dpdk.org Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id BAD874C9D; Fri, 31 Aug 2018 11:01:19 +0200 (CEST) Received: from mail-wm0-f65.google.com (mail-wm0-f65.google.com [74.125.82.65]) by dpdk.org (Postfix) with ESMTP id B87B94C90 for ; Fri, 31 Aug 2018 11:01:17 +0200 (CEST) Received: by mail-wm0-f65.google.com with SMTP id t25-v6so4568239wmi.3 for ; Fri, 31 Aug 2018 02:01:17 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=6wind-com.20150623.gappssmtp.com; s=20150623; h=date:from:to:cc:subject:message-id:references:mime-version :content-disposition:in-reply-to; bh=g7sdEZQUr7esOW41/mfdEuP/I0JW2i7OXw6w4kCWNtE=; b=ZjyjC2+Iw1cw5R/nLYC0DvYUwrF6Ywb9uxtjd5VeRxcVlEE9ySdZSuBwXJqMg4Tn3X 6IEtwDx8bQjpMRejhzK+34wI4F7GiIxJbzYppMihxCxmWjBhNIPfRvbSF/3WoLt+4lnx aVbg8Oi7Di6D2MGra9Yv6jOaAUqpvgvF3oat3mTM9o98kL34pP/0zYR3Vngvaxlz9yKf VBjK5h5hX1H7GNWmdgU4VZnU2V6XwIA/d7j/DCpdNglFJ+zreybQHdbFEZOlCkaCcmk1 gzrqZJQ7v72kjZZlvbPTo7EROO076i4IXBfM1yGGcAAHTwi5QaURRZnDr2B8S/ZC3xy3 Bipg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:from:to:cc:subject:message-id:references :mime-version:content-disposition:in-reply-to; bh=g7sdEZQUr7esOW41/mfdEuP/I0JW2i7OXw6w4kCWNtE=; b=pyqqXUr4Ic4aTlvxEnqpPHd19svVbI2Ns12bQtwthD7m33HK1kydRFvoJ+O726tt2J zuxcnHj5hN6bmeS8EtJI/YupjmBkyhZS3TNWJZ/M/nz/nfAkoaeahAUVPlDAbFg/1BWK C2ZGUYdGKoK4MhryERHgJSi22pcMjop8+f3ZFopMnoYy7Y527EWUV9il4HFwmzXBFETy VXxhx+VWM+HXUcTv02UtBMCu53NhUt+u4bHNggXSkMwmoyzNku1aEOF8e/brJGUoTieM EaLOhRIZ3fCAHUu7VsFow+W4CBy0GsnwnLbO15lxKCOdZNb/6y0P176UpHmwAwAOUAcv Kgbw== X-Gm-Message-State: APzg51BUl8IPoXZYQvCTF2B2D2Kro7SHLiWqVisJd2qx54+fLSgv6TaM ZsyMiY3UpyoLBxR2FBf6QjxBLQ== X-Google-Smtp-Source: ANB0VdaEmyORj5Wtv0/nWzb+zcVm7n6pLReldnX9N6G+Qq4VYoSGgKEUuO3oFLFsy8gFk7YgchvGYQ== X-Received: by 2002:a1c:c642:: with SMTP id w63-v6mr2146567wmf.3.1535706077149; Fri, 31 Aug 2018 02:01:17 -0700 (PDT) Received: from 6wind.com (host.78.145.23.62.rev.coltfrance.com. [62.23.145.78]) by smtp.gmail.com with ESMTPSA id h82-v6sm3198390wme.11.2018.08.31.02.01.16 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 31 Aug 2018 02:01:16 -0700 (PDT) Date: Fri, 31 Aug 2018 11:01:00 +0200 From: Adrien Mazarguil To: Ferruh Yigit Cc: dev@dpdk.org, Thomas Monjalon , Andrew Rybchenko , Gaetan Rivet Message-ID: <20180831085337.21419-2-adrien.mazarguil@6wind.com> References: <20180803132032.29038-1-adrien.mazarguil@6wind.com> <20180831085337.21419-1-adrien.mazarguil@6wind.com> MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: <20180831085337.21419-1-adrien.mazarguil@6wind.com> X-Mailer: git-send-email 2.11.0 Subject: [dpdk-dev] [PATCH v3 1/7] ethdev: add flow API object converter X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" rte_flow_copy() is bound to duplicate flow rule descriptions (attributes, pattern and list of actions, all at once), however applications sometimes need more flexibility, for instance the ability to duplicate only one of the underlying objects (a single pattern item or action) or retrieve other properties such as their names. Instead of adding dedicated functions to handle each possible use case, this patch introduces rte_flow_conv(), which supports any number of object conversion operations in an extensible manner. This patch re-implements rte_flow_copy() as a wrapper to rte_flow_conv(). Signed-off-by: Adrien Mazarguil Cc: Thomas Monjalon Cc: Ferruh Yigit Cc: Andrew Rybchenko Cc: Gaetan Rivet --- v3 changes: - Worked around compilation issue on ARM where rte_memcpy() is a macro that chokes on commas. - Marked rte_flow_conv() as experimental. v2 changes: - Modified patch to keep rte_flow_copy() around instead of removing it entirely. Reworded commit log accordingly. - Moved failsafe PMD changes to a subsequent patch. - Re-implemented rte_flow_copy() as a wrapper to rte_flow_conv() to reduce code duplication. - Tweaked semantics of rte_flow_conv() to return the required number of bytes regardless of the size parameter; a buffer not large enough is not considered to be an error anymore. This change removes the need for a "store" pass in underlying helper functions. - Renamed and properly documented internal helper functions. --- doc/guides/prog_guide/rte_flow.rst | 19 + lib/librte_ethdev/rte_ethdev_version.map | 1 + lib/librte_ethdev/rte_flow.c | 553 ++++++++++++++++++-------- lib/librte_ethdev/rte_flow.h | 170 +++++++- 4 files changed, 582 insertions(+), 161 deletions(-) diff --git a/doc/guides/prog_guide/rte_flow.rst b/doc/guides/prog_guide/rte_flow.rst index b305a72a5..964cf9ceb 100644 --- a/doc/guides/prog_guide/rte_flow.rst +++ b/doc/guides/prog_guide/rte_flow.rst @@ -2419,6 +2419,25 @@ This function initializes ``error`` (if non-NULL) with the provided parameters and sets ``rte_errno`` to ``code``. A negative error ``code`` is then returned. +Object conversion +~~~~~~~~~~~~~~~~~ + +.. code-block:: c + + int + rte_flow_conv(enum rte_flow_conv_op op, + void *dst, + size_t size, + const void *src, + struct rte_flow_error *error); + +Convert ``src`` to ``dst`` according to operation ``op``. Possible +operations include: + +- Attributes, pattern item or action duplication. +- Duplication of an entire pattern or list of actions. +- Duplication of a complete flow rule description. + Caveats ------- diff --git a/lib/librte_ethdev/rte_ethdev_version.map b/lib/librte_ethdev/rte_ethdev_version.map index 38f117f01..2ee9173a1 100644 --- a/lib/librte_ethdev/rte_ethdev_version.map +++ b/lib/librte_ethdev/rte_ethdev_version.map @@ -239,6 +239,7 @@ EXPERIMENTAL { rte_eth_dev_tx_offload_name; rte_eth_switch_domain_alloc; rte_eth_switch_domain_free; + rte_flow_conv; rte_flow_expand_rss; rte_mtr_capabilities_get; rte_mtr_create; diff --git a/lib/librte_ethdev/rte_flow.c b/lib/librte_ethdev/rte_flow.c index cff4b5209..4fd6cfa76 100644 --- a/lib/librte_ethdev/rte_flow.c +++ b/lib/librte_ethdev/rte_flow.c @@ -288,26 +288,41 @@ rte_flow_error_set(struct rte_flow_error *error, } /** Pattern item specification types. */ -enum item_spec_type { - ITEM_SPEC, - ITEM_LAST, - ITEM_MASK, +enum rte_flow_conv_item_spec_type { + RTE_FLOW_CONV_ITEM_SPEC, + RTE_FLOW_CONV_ITEM_LAST, + RTE_FLOW_CONV_ITEM_MASK, }; -/** Compute storage space needed by item specification and copy it. */ +/** + * Copy pattern item specification. + * + * @param[out] buf + * Output buffer. Can be NULL if @p size is zero. + * @param size + * Size of @p buf in bytes. + * @param[in] item + * Pattern item to copy specification from. + * @param type + * Specification selector for either @p spec, @p last or @p mask. + * + * @return + * Number of bytes needed to store pattern item specification regardless + * of @p size. @p buf contents are truncated to @p size if not large + * enough. + */ static size_t -flow_item_spec_copy(void *buf, const struct rte_flow_item *item, - enum item_spec_type type) +rte_flow_conv_item_spec(void *buf, const size_t size, + const struct rte_flow_item *item, + enum rte_flow_conv_item_spec_type type) { - size_t size = 0; + size_t off; const void *data = - type == ITEM_SPEC ? item->spec : - type == ITEM_LAST ? item->last : - type == ITEM_MASK ? item->mask : + type == RTE_FLOW_CONV_ITEM_SPEC ? item->spec : + type == RTE_FLOW_CONV_ITEM_LAST ? item->last : + type == RTE_FLOW_CONV_ITEM_MASK ? item->mask : NULL; - if (!item->spec || !data) - goto empty; switch (item->type) { union { const struct rte_flow_item_raw *raw; @@ -324,7 +339,7 @@ flow_item_spec_copy(void *buf, const struct rte_flow_item *item, union { struct rte_flow_item_raw *raw; } dst; - size_t off; + size_t tmp; case RTE_FLOW_ITEM_TYPE_RAW: spec.raw = item->spec; @@ -332,41 +347,62 @@ flow_item_spec_copy(void *buf, const struct rte_flow_item *item, mask.raw = item->mask ? item->mask : &rte_flow_item_raw_mask; src.raw = data; dst.raw = buf; - off = RTE_ALIGN_CEIL(sizeof(struct rte_flow_item_raw), - sizeof(*src.raw->pattern)); - if (type == ITEM_SPEC || - (type == ITEM_MASK && + rte_memcpy(dst.raw, + (&(struct rte_flow_item_raw){ + .relative = src.raw->relative, + .search = src.raw->search, + .reserved = src.raw->reserved, + .offset = src.raw->offset, + .limit = src.raw->limit, + .length = src.raw->length, + }), + size > sizeof(*dst.raw) ? sizeof(*dst.raw) : size); + off = sizeof(*dst.raw); + if (type == RTE_FLOW_CONV_ITEM_SPEC || + (type == RTE_FLOW_CONV_ITEM_MASK && ((spec.raw->length & mask.raw->length) >= (last.raw->length & mask.raw->length)))) - size = spec.raw->length & mask.raw->length; + tmp = spec.raw->length & mask.raw->length; else - size = last.raw->length & mask.raw->length; - size = off + size * sizeof(*src.raw->pattern); - if (dst.raw) { - memcpy(dst.raw, src.raw, sizeof(*src.raw)); - dst.raw->pattern = memcpy((uint8_t *)dst.raw + off, - src.raw->pattern, - size - off); + tmp = last.raw->length & mask.raw->length; + if (tmp) { + off = RTE_ALIGN_CEIL(off, sizeof(*dst.raw->pattern)); + if (size >= off + tmp) + dst.raw->pattern = rte_memcpy + ((void *)((uintptr_t)dst.raw + off), + src.raw->pattern, tmp); + off += tmp; } break; default: - size = rte_flow_desc_item[item->type].size; - if (buf) - memcpy(buf, data, size); + off = rte_flow_desc_item[item->type].size; + rte_memcpy(buf, data, (size > off ? off : size)); break; } -empty: - return RTE_ALIGN_CEIL(size, sizeof(double)); + return off; } -/** Compute storage space needed by action configuration and copy it. */ +/** + * Copy action configuration. + * + * @param[out] buf + * Output buffer. Can be NULL if @p size is zero. + * @param size + * Size of @p buf in bytes. + * @param[in] action + * Action to copy configuration from. + * + * @return + * Number of bytes needed to store pattern item specification regardless + * of @p size. @p buf contents are truncated to @p size if not large + * enough. + */ static size_t -flow_action_conf_copy(void *buf, const struct rte_flow_action *action) +rte_flow_conv_action_conf(void *buf, const size_t size, + const struct rte_flow_action *action) { - size_t size = 0; + size_t off; - if (!action->conf) - goto empty; switch (action->type) { union { const struct rte_flow_action_rss *rss; @@ -374,49 +410,308 @@ flow_action_conf_copy(void *buf, const struct rte_flow_action *action) union { struct rte_flow_action_rss *rss; } dst; - size_t off; + size_t tmp; case RTE_FLOW_ACTION_TYPE_RSS: src.rss = action->conf; dst.rss = buf; - off = 0; - if (dst.rss) - *dst.rss = (struct rte_flow_action_rss){ + rte_memcpy(dst.rss, + (&(struct rte_flow_action_rss){ .func = src.rss->func, .level = src.rss->level, .types = src.rss->types, .key_len = src.rss->key_len, .queue_num = src.rss->queue_num, - }; - off += sizeof(*src.rss); + }), + size > sizeof(*dst.rss) ? sizeof(*dst.rss) : size); + off = sizeof(*dst.rss); if (src.rss->key_len) { - off = RTE_ALIGN_CEIL(off, sizeof(double)); - size = sizeof(*src.rss->key) * src.rss->key_len; - if (dst.rss) - dst.rss->key = memcpy + off = RTE_ALIGN_CEIL(off, sizeof(*dst.rss->key)); + tmp = sizeof(*src.rss->key) * src.rss->key_len; + if (size >= off + tmp) + dst.rss->key = rte_memcpy ((void *)((uintptr_t)dst.rss + off), - src.rss->key, size); - off += size; + src.rss->key, tmp); + off += tmp; } if (src.rss->queue_num) { - off = RTE_ALIGN_CEIL(off, sizeof(double)); - size = sizeof(*src.rss->queue) * src.rss->queue_num; - if (dst.rss) - dst.rss->queue = memcpy + off = RTE_ALIGN_CEIL(off, sizeof(*dst.rss->queue)); + tmp = sizeof(*src.rss->queue) * src.rss->queue_num; + if (size >= off + tmp) + dst.rss->queue = rte_memcpy ((void *)((uintptr_t)dst.rss + off), - src.rss->queue, size); - off += size; + src.rss->queue, tmp); + off += tmp; } - size = off; break; default: - size = rte_flow_desc_action[action->type].size; - if (buf) - memcpy(buf, action->conf, size); + off = rte_flow_desc_action[action->type].size; + rte_memcpy(buf, action->conf, (size > off ? off : size)); break; } -empty: - return RTE_ALIGN_CEIL(size, sizeof(double)); + return off; +} + +/** + * Copy a list of pattern items. + * + * @param[out] dst + * Destination buffer. Can be NULL if @p size is zero. + * @param size + * Size of @p dst in bytes. + * @param[in] src + * Source pattern items. + * @param num + * Maximum number of pattern items to process from @p src or 0 to process + * the entire list. In both cases, processing stops after + * RTE_FLOW_ITEM_TYPE_END is encountered. + * @param[out] error + * Perform verbose error reporting if not NULL. + * + * @return + * A positive value representing the number of bytes needed to store + * pattern items regardless of @p size on success (@p buf contents are + * truncated to @p size if not large enough), a negative errno value + * otherwise and rte_errno is set. + */ +static int +rte_flow_conv_pattern(struct rte_flow_item *dst, + const size_t size, + const struct rte_flow_item *src, + unsigned int num, + struct rte_flow_error *error) +{ + uintptr_t data = (uintptr_t)dst; + size_t off; + size_t ret; + unsigned int i; + + for (i = 0, off = 0; !num || i != num; ++i, ++src, ++dst) { + if ((size_t)src->type >= RTE_DIM(rte_flow_desc_item) || + !rte_flow_desc_item[src->type].name) + return rte_flow_error_set + (error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ITEM, src, + "cannot convert unknown item type"); + if (size >= off + sizeof(*dst)) + *dst = (struct rte_flow_item){ + .type = src->type, + }; + off += sizeof(*dst); + if (!src->type) + num = i + 1; + } + num = i; + src -= num; + dst -= num; + do { + if (src->spec) { + off = RTE_ALIGN_CEIL(off, sizeof(double)); + ret = rte_flow_conv_item_spec + ((void *)(data + off), + size > off ? size - off : 0, src, + RTE_FLOW_CONV_ITEM_SPEC); + if (size && size >= off + ret) + dst->spec = (void *)(data + off); + off += ret; + + } + if (src->last) { + off = RTE_ALIGN_CEIL(off, sizeof(double)); + ret = rte_flow_conv_item_spec + ((void *)(data + off), + size > off ? size - off : 0, src, + RTE_FLOW_CONV_ITEM_LAST); + if (size && size >= off + ret) + dst->last = (void *)(data + off); + off += ret; + } + if (src->mask) { + off = RTE_ALIGN_CEIL(off, sizeof(double)); + ret = rte_flow_conv_item_spec + ((void *)(data + off), + size > off ? size - off : 0, src, + RTE_FLOW_CONV_ITEM_MASK); + if (size && size >= off + ret) + dst->mask = (void *)(data + off); + off += ret; + } + ++src; + ++dst; + } while (--num); + return off; +} + +/** + * Copy a list of actions. + * + * @param[out] dst + * Destination buffer. Can be NULL if @p size is zero. + * @param size + * Size of @p dst in bytes. + * @param[in] src + * Source actions. + * @param num + * Maximum number of actions to process from @p src or 0 to process the + * entire list. In both cases, processing stops after + * RTE_FLOW_ACTION_TYPE_END is encountered. + * @param[out] error + * Perform verbose error reporting if not NULL. + * + * @return + * A positive value representing the number of bytes needed to store + * actions regardless of @p size on success (@p buf contents are truncated + * to @p size if not large enough), a negative errno value otherwise and + * rte_errno is set. + */ +static int +rte_flow_conv_actions(struct rte_flow_action *dst, + const size_t size, + const struct rte_flow_action *src, + unsigned int num, + struct rte_flow_error *error) +{ + uintptr_t data = (uintptr_t)dst; + size_t off; + size_t ret; + unsigned int i; + + for (i = 0, off = 0; !num || i != num; ++i, ++src, ++dst) { + if ((size_t)src->type >= RTE_DIM(rte_flow_desc_action) || + !rte_flow_desc_action[src->type].name) + return rte_flow_error_set + (error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ACTION, + src, "cannot convert unknown action type"); + if (size >= off + sizeof(*dst)) + *dst = (struct rte_flow_action){ + .type = src->type, + }; + off += sizeof(*dst); + if (!src->type) + num = i + 1; + } + num = i; + src -= num; + dst -= num; + do { + if (src->conf) { + off = RTE_ALIGN_CEIL(off, sizeof(double)); + ret = rte_flow_conv_action_conf + ((void *)(data + off), + size > off ? size - off : 0, src); + if (size && size >= off + ret) + dst->conf = (void *)(data + off); + off += ret; + } + ++src; + ++dst; + } while (--num); + return off; +} + +/** + * Copy flow rule components. + * + * This comprises the flow rule descriptor itself, attributes, pattern and + * actions list. NULL components in @p src are skipped. + * + * @param[out] dst + * Destination buffer. Can be NULL if @p size is zero. + * @param size + * Size of @p dst in bytes. + * @param[in] src + * Source flow rule descriptor. + * @param[out] error + * Perform verbose error reporting if not NULL. + * + * @return + * A positive value representing the number of bytes needed to store all + * components including the descriptor regardless of @p size on success + * (@p buf contents are truncated to @p size if not large enough), a + * negative errno value otherwise and rte_errno is set. + */ +static int +rte_flow_conv_rule(struct rte_flow_conv_rule *dst, + const size_t size, + const struct rte_flow_conv_rule *src, + struct rte_flow_error *error) +{ + size_t off; + int ret; + + rte_memcpy(dst, + (&(struct rte_flow_conv_rule){ + .attr = NULL, + .pattern = NULL, + .actions = NULL, + }), + size > sizeof(*dst) ? sizeof(*dst) : size); + off = sizeof(*dst); + if (src->attr_ro) { + off = RTE_ALIGN_CEIL(off, sizeof(double)); + if (size && size >= off + sizeof(*dst->attr)) + dst->attr = rte_memcpy + ((void *)((uintptr_t)dst + off), + src->attr_ro, sizeof(*dst->attr)); + off += sizeof(*dst->attr); + } + if (src->pattern_ro) { + off = RTE_ALIGN_CEIL(off, sizeof(double)); + ret = rte_flow_conv_pattern((void *)((uintptr_t)dst + off), + size > off ? size - off : 0, + src->pattern_ro, 0, error); + if (ret < 0) + return ret; + if (size && size >= off + (size_t)ret) + dst->pattern = (void *)((uintptr_t)dst + off); + off += ret; + } + if (src->actions_ro) { + off = RTE_ALIGN_CEIL(off, sizeof(double)); + ret = rte_flow_conv_actions((void *)((uintptr_t)dst + off), + size > off ? size - off : 0, + src->actions_ro, 0, error); + if (ret < 0) + return ret; + if (size >= off + (size_t)ret) + dst->actions = (void *)((uintptr_t)dst + off); + off += ret; + } + return off; +} + +/** Helper function to convert flow API objects. */ +int +rte_flow_conv(enum rte_flow_conv_op op, + void *dst, + size_t size, + const void *src, + struct rte_flow_error *error) +{ + switch (op) { + const struct rte_flow_attr *attr; + + case RTE_FLOW_CONV_OP_NONE: + return 0; + case RTE_FLOW_CONV_OP_ATTR: + attr = src; + if (size > sizeof(*attr)) + size = sizeof(*attr); + rte_memcpy(dst, attr, size); + return sizeof(*attr); + case RTE_FLOW_CONV_OP_ITEM: + return rte_flow_conv_pattern(dst, size, src, 1, error); + case RTE_FLOW_CONV_OP_ACTION: + return rte_flow_conv_actions(dst, size, src, 1, error); + case RTE_FLOW_CONV_OP_PATTERN: + return rte_flow_conv_pattern(dst, size, src, 0, error); + case RTE_FLOW_CONV_OP_ACTIONS: + return rte_flow_conv_actions(dst, size, src, 0, error); + case RTE_FLOW_CONV_OP_RULE: + return rte_flow_conv_rule(dst, size, src, error); + } + return rte_flow_error_set + (error, ENOTSUP, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL, + "unknown object conversion operation"); } /** Store a full rte_flow description. */ @@ -426,105 +721,49 @@ rte_flow_copy(struct rte_flow_desc *desc, size_t len, const struct rte_flow_item *items, const struct rte_flow_action *actions) { - struct rte_flow_desc *fd = NULL; - size_t tmp; - size_t off1 = 0; - size_t off2 = 0; - size_t size = 0; - -store: - if (items) { - const struct rte_flow_item *item; - - item = items; - if (fd) - fd->items = (void *)&fd->data[off1]; - do { - struct rte_flow_item *dst = NULL; - - if ((size_t)item->type >= - RTE_DIM(rte_flow_desc_item) || - !rte_flow_desc_item[item->type].name) { - rte_errno = ENOTSUP; - return 0; - } - if (fd) - dst = memcpy(fd->data + off1, item, - sizeof(*item)); - off1 += sizeof(*item); - if (item->spec) { - if (fd) - dst->spec = fd->data + off2; - off2 += flow_item_spec_copy - (fd ? fd->data + off2 : NULL, item, - ITEM_SPEC); - } - if (item->last) { - if (fd) - dst->last = fd->data + off2; - off2 += flow_item_spec_copy - (fd ? fd->data + off2 : NULL, item, - ITEM_LAST); - } - if (item->mask) { - if (fd) - dst->mask = fd->data + off2; - off2 += flow_item_spec_copy - (fd ? fd->data + off2 : NULL, item, - ITEM_MASK); - } - off2 = RTE_ALIGN_CEIL(off2, sizeof(double)); - } while ((item++)->type != RTE_FLOW_ITEM_TYPE_END); - off1 = RTE_ALIGN_CEIL(off1, sizeof(double)); - } - if (actions) { - const struct rte_flow_action *action; - - action = actions; - if (fd) - fd->actions = (void *)&fd->data[off1]; - do { - struct rte_flow_action *dst = NULL; - - if ((size_t)action->type >= - RTE_DIM(rte_flow_desc_action) || - !rte_flow_desc_action[action->type].name) { - rte_errno = ENOTSUP; - return 0; - } - if (fd) - dst = memcpy(fd->data + off1, action, - sizeof(*action)); - off1 += sizeof(*action); - if (action->conf) { - if (fd) - dst->conf = fd->data + off2; - off2 += flow_action_conf_copy - (fd ? fd->data + off2 : NULL, action); - } - off2 = RTE_ALIGN_CEIL(off2, sizeof(double)); - } while ((action++)->type != RTE_FLOW_ACTION_TYPE_END); + /* + * Overlap struct rte_flow_conv with struct rte_flow_desc in order + * to convert the former to the latter without wasting space. + */ + struct rte_flow_conv_rule *dst = + len ? + (void *)((uintptr_t)desc + + (offsetof(struct rte_flow_desc, actions) - + offsetof(struct rte_flow_conv_rule, actions))) : + NULL; + size_t dst_size = + len > sizeof(*desc) - sizeof(*dst) ? + len - (sizeof(*desc) - sizeof(*dst)) : + 0; + struct rte_flow_conv_rule src = { + .attr_ro = NULL, + .pattern_ro = items, + .actions_ro = actions, + }; + int ret; + + RTE_BUILD_BUG_ON(sizeof(struct rte_flow_desc) < + sizeof(struct rte_flow_conv_rule)); + if (dst_size && + (&dst->pattern != &desc->items || + &dst->actions != &desc->actions || + (uintptr_t)(dst + 1) != (uintptr_t)(desc + 1))) { + rte_errno = EINVAL; + return 0; } - if (fd != NULL) - return size; - off1 = RTE_ALIGN_CEIL(off1, sizeof(double)); - tmp = RTE_ALIGN_CEIL(offsetof(struct rte_flow_desc, data), - sizeof(double)); - size = tmp + off1 + off2; - if (size > len) - return size; - fd = desc; - if (fd != NULL) { - *fd = (const struct rte_flow_desc) { - .size = size, + ret = rte_flow_conv(RTE_FLOW_CONV_OP_RULE, dst, dst_size, &src, NULL); + if (ret < 0) + return 0; + ret += sizeof(*desc) - sizeof(*dst); + rte_memcpy(desc, + (&(struct rte_flow_desc){ + .size = ret, .attr = *attr, - }; - tmp -= offsetof(struct rte_flow_desc, data); - off2 = tmp + off1; - off1 = tmp; - goto store; - } - return 0; + .items = dst_size ? dst->pattern : NULL, + .actions = dst_size ? dst->actions : NULL, + }), + len > sizeof(*desc) ? sizeof(*desc) : len); + return ret; } /** diff --git a/lib/librte_ethdev/rte_flow.h b/lib/librte_ethdev/rte_flow.h index f8ba71cdb..1288e76ae 100644 --- a/lib/librte_ethdev/rte_flow.h +++ b/lib/librte_ethdev/rte_flow.h @@ -18,6 +18,7 @@ #include #include +#include #include #include #include @@ -1932,6 +1933,119 @@ struct rte_flow_error { }; /** + * Complete flow rule description. + * + * This object type is used when converting a flow rule description. + * + * @see RTE_FLOW_CONV_OP_RULE + * @see rte_flow_conv() + */ +RTE_STD_C11 +struct rte_flow_conv_rule { + union { + const struct rte_flow_attr *attr_ro; /**< RO attributes. */ + struct rte_flow_attr *attr; /**< Attributes. */ + }; + union { + const struct rte_flow_item *pattern_ro; /**< RO pattern. */ + struct rte_flow_item *pattern; /**< Pattern items. */ + }; + union { + const struct rte_flow_action *actions_ro; /**< RO actions. */ + struct rte_flow_action *actions; /**< List of actions. */ + }; +}; + +/** + * Conversion operations for flow API objects. + * + * @see rte_flow_conv() + */ +enum rte_flow_conv_op { + /** + * No operation to perform. + * + * rte_flow_conv() simply returns 0. + */ + RTE_FLOW_CONV_OP_NONE, + + /** + * Convert attributes structure. + * + * This is a basic copy of an attributes structure. + * + * - @p src type: + * @code const struct rte_flow_attr * @endcode + * - @p dst type: + * @code struct rte_flow_attr * @endcode + */ + RTE_FLOW_CONV_OP_ATTR, + + /** + * Convert a single item. + * + * Duplicates @p spec, @p last and @p mask but not outside objects. + * + * - @p src type: + * @code const struct rte_flow_item * @endcode + * - @p dst type: + * @code struct rte_flow_item * @endcode + */ + RTE_FLOW_CONV_OP_ITEM, + + /** + * Convert a single action. + * + * Duplicates @p conf but not outside objects. + * + * - @p src type: + * @code const struct rte_flow_action * @endcode + * - @p dst type: + * @code struct rte_flow_action * @endcode + */ + RTE_FLOW_CONV_OP_ACTION, + + /** + * Convert an entire pattern. + * + * Duplicates all pattern items at once with the same constraints as + * RTE_FLOW_CONV_OP_ITEM. + * + * - @p src type: + * @code const struct rte_flow_item * @endcode + * - @p dst type: + * @code struct rte_flow_item * @endcode + */ + RTE_FLOW_CONV_OP_PATTERN, + + /** + * Convert a list of actions. + * + * Duplicates the entire list of actions at once with the same + * constraints as RTE_FLOW_CONV_OP_ACTION. + * + * - @p src type: + * @code const struct rte_flow_action * @endcode + * - @p dst type: + * @code struct rte_flow_action * @endcode + */ + RTE_FLOW_CONV_OP_ACTIONS, + + /** + * Convert a complete flow rule description. + * + * Comprises attributes, pattern and actions together at once with + * the usual constraints. + * + * - @p src type: + * @code const struct rte_flow_conv_rule * @endcode + * - @p dst type: + * @code struct rte_flow_conv_rule * @endcode + */ + RTE_FLOW_CONV_OP_RULE, +}; + +/** * Check whether a flow rule can be created on a given port. * * The flow rule is validated for correctness and whether it could be accepted @@ -2162,10 +2276,7 @@ rte_flow_error_set(struct rte_flow_error *error, const char *message); /** - * Generic flow representation. - * - * This form is sufficient to describe an rte_flow independently from any - * PMD implementation and allows for replayability and identification. + * @see rte_flow_copy() */ struct rte_flow_desc { size_t size; /**< Allocated space including data[]. */ @@ -2178,6 +2289,9 @@ struct rte_flow_desc { /** * Copy an rte_flow rule description. * + * This interface is kept for compatibility with older applications but is + * implemented as a wrapper to rte_flow_conv(). + * * @param[in] fd * Flow rule description. * @param[in] len @@ -2201,6 +2315,54 @@ rte_flow_copy(struct rte_flow_desc *fd, size_t len, const struct rte_flow_item *items, const struct rte_flow_action *actions); +/** + * Flow object conversion helper. + * + * This function performs conversion of various flow API objects to a + * pre-allocated destination buffer. See enum rte_flow_conv_op for possible + * operations and details about each of them. + * + * Since destination buffer must be large enough, it works in a manner + * reminiscent of snprintf(): + * + * - If @p size is 0, @p dst may be a NULL pointer, otherwise @p dst must be + * non-NULL. + * - If positive, the returned value represents the number of bytes needed + * to store the conversion of @p src to @p dst according to @p op + * regardless of the @p size parameter. + * - Since no more than @p size bytes can be written to @p dst, output is + * truncated and may be inconsistent when the returned value is larger + * than that. + * - In case of conversion error, a negative error code is returned and + * @p dst contents are unspecified. + * + * @param op + * Operation to perform, related to the object type of @p dst. + * @param[out] dst + * Destination buffer address. Must be suitably aligned by the caller. + * @param size + * Destination buffer size in bytes. + * @param[in] src + * Source object to copy. Depending on @p op, its type may differ from + * that of @p dst. + * @param[out] error + * Perform verbose error reporting if not NULL. Initialized in case of + * error only. + * + * @return + * The number of bytes required to convert @p src to @p dst on success, a + * negative errno value otherwise and rte_errno is set. + * + * @see rte_flow_conv_op + */ +__rte_experimental +int +rte_flow_conv(enum rte_flow_conv_op op, + void *dst, + size_t size, + const void *src, + struct rte_flow_error *error); + #ifdef __cplusplus } #endif From patchwork Fri Aug 31 09:01:02 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Adrien Mazarguil X-Patchwork-Id: 44069 X-Patchwork-Delegate: ferruh.yigit@amd.com Return-Path: X-Original-To: patchwork@dpdk.org Delivered-To: patchwork@dpdk.org Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id 60ACF4CB5; Fri, 31 Aug 2018 11:01:23 +0200 (CEST) Received: from mail-wm0-f50.google.com (mail-wm0-f50.google.com [74.125.82.50]) by dpdk.org (Postfix) with ESMTP id 108134CAB for ; Fri, 31 Aug 2018 11:01:21 +0200 (CEST) Received: by mail-wm0-f50.google.com with SMTP id j25-v6so2842609wmc.1 for ; Fri, 31 Aug 2018 02:01:21 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=6wind-com.20150623.gappssmtp.com; s=20150623; h=date:from:to:cc:subject:message-id:references:mime-version :content-disposition:in-reply-to; bh=cg7wPrCBOR0XWnMPnT8WQUETRScquCCH7BEk6idb1tk=; b=cTYTBWYL0pk7Xso0eW0Hzc4nkJ4oipwKPEqniJzDLmaZJaqWxdKkBQqjwnzXYlEIGD kXUTaPlOIPHgNLwVwwHFx9/Um7DmsGcPoYmskwkmg7Y8Ox6Hotc1I8j6sLJizk3G3/I4 AvQnFdZzKNov6hJfnU4PzJVoN5qUDpaVfnLFlLclBdnZtORXqFaDz6i8kZjasCk/WWE4 uuAQiMG8Jn6bCWsFgLIROoBjbeMAjoi8IjPm0VYKLnaz3R+NA7zbLwE3/7RQ7V6pRX1S ARtRADZCGrjgQLUsINtHZFcYY+lFfJofEJIMWdoidkx+YkHIBpqtaZxdeQa3d5oRrJBa cRtQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:from:to:cc:subject:message-id:references :mime-version:content-disposition:in-reply-to; bh=cg7wPrCBOR0XWnMPnT8WQUETRScquCCH7BEk6idb1tk=; b=Eees3gRjm9KGmln9dgVR5EwXutxBT+7r1iKgFZCKVKuhDsETip+zEbuU2WFVuIbfZk +/UdmLKyqHUZTj+wm6ILsAE5/f2S8U0bVAyXP20yvvkQXRdCru/XvfpDwejQ7uuabOT9 2EOcLSNhb6GqYXyzq4FYcIXoxJxseFGk2qEHAAW1my0OFAsUhl+PyIyk13Cp2JCMaHnL L7bprdEd7FpNo01dez2TxkhzLolS/Ze7clCYOvdg1Aha/1e6SWXpbl/uH9peJhNIqybG baP3xS56299EaMRZo6bgTahiaTQuR3cR9gKpQ1aLz/prtboT6K9ktnNcfqDAgJWnFLki d5cw== X-Gm-Message-State: APzg51CzB7hzX6fpQld7IGSFMSeUNpOQnYMp8VrU35X7EVw5V9Wq7q8e Q+AkzJfUN1Lq5W+d47xU5kfysQ== X-Google-Smtp-Source: ANB0VdZor3ngWMpkDs1WG3fvJRUk0FSUQTMNDi9dQScM1Rm4U3za6Tpc8aB4QqU7+YB3T4l5PAvN5w== X-Received: by 2002:a1c:9b91:: with SMTP id d139-v6mr4395888wme.50.1535706079322; Fri, 31 Aug 2018 02:01:19 -0700 (PDT) Received: from 6wind.com (host.78.145.23.62.rev.coltfrance.com. [62.23.145.78]) by smtp.gmail.com with ESMTPSA id t9-v6sm891994wmf.1.2018.08.31.02.01.18 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 31 Aug 2018 02:01:18 -0700 (PDT) Date: Fri, 31 Aug 2018 11:01:02 +0200 From: Adrien Mazarguil To: Ferruh Yigit Cc: dev@dpdk.org, Thomas Monjalon , Andrew Rybchenko Message-ID: <20180831085337.21419-3-adrien.mazarguil@6wind.com> References: <20180803132032.29038-1-adrien.mazarguil@6wind.com> <20180831085337.21419-1-adrien.mazarguil@6wind.com> MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: <20180831085337.21419-1-adrien.mazarguil@6wind.com> X-Mailer: git-send-email 2.11.0 Subject: [dpdk-dev] [PATCH v3 2/7] ethdev: add flow API item/action name conversion X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" This provides a means for applications to retrieve the name of flow pattern items and actions. Signed-off-by: Adrien Mazarguil Cc: Thomas Monjalon Cc: Ferruh Yigit Cc: Andrew Rybchenko --- v2 changes: - Replaced rte_flow_conv_name_ptr() with extra is_ptr argument to rte_flow_conv_name() since both functions were almost identical. - Properly documented internal helper functions. --- doc/guides/prog_guide/rte_flow.rst | 1 + lib/librte_ethdev/rte_flow.c | 63 +++++++++++++++++++++++++++++++++ lib/librte_ethdev/rte_flow.h | 56 +++++++++++++++++++++++++++++ 3 files changed, 120 insertions(+) diff --git a/doc/guides/prog_guide/rte_flow.rst b/doc/guides/prog_guide/rte_flow.rst index 964cf9ceb..1b17f6e01 100644 --- a/doc/guides/prog_guide/rte_flow.rst +++ b/doc/guides/prog_guide/rte_flow.rst @@ -2437,6 +2437,7 @@ operations include: - Attributes, pattern item or action duplication. - Duplication of an entire pattern or list of actions. - Duplication of a complete flow rule description. +- Pattern item or action name retrieval. Caveats ------- diff --git a/lib/librte_ethdev/rte_flow.c b/lib/librte_ethdev/rte_flow.c index 4fd6cfa76..c3ff7e713 100644 --- a/lib/librte_ethdev/rte_flow.c +++ b/lib/librte_ethdev/rte_flow.c @@ -11,6 +11,7 @@ #include #include #include +#include #include "rte_ethdev.h" #include "rte_flow_driver.h" #include "rte_flow.h" @@ -679,6 +680,60 @@ rte_flow_conv_rule(struct rte_flow_conv_rule *dst, return off; } +/** + * Retrieve the name of a pattern item/action type. + * + * @param is_action + * Nonzero when @p src represents an action type instead of a pattern item + * type. + * @param is_ptr + * Nonzero to write string address instead of contents into @p dst. + * @param[out] dst + * Destination buffer. Can be NULL if @p size is zero. + * @param size + * Size of @p dst in bytes. + * @param[in] src + * Depending on @p is_action, source pattern item or action type cast as a + * pointer. + * @param[out] error + * Perform verbose error reporting if not NULL. + * + * @return + * A positive value representing the number of bytes needed to store the + * name or its address regardless of @p size on success (@p buf contents + * are truncated to @p size if not large enough), a negative errno value + * otherwise and rte_errno is set. + */ +static int +rte_flow_conv_name(int is_action, + int is_ptr, + char *dst, + const size_t size, + const void *src, + struct rte_flow_error *error) +{ + struct desc_info { + const struct rte_flow_desc_data *data; + size_t num; + }; + static const struct desc_info info_rep[2] = { + { rte_flow_desc_item, RTE_DIM(rte_flow_desc_item), }, + { rte_flow_desc_action, RTE_DIM(rte_flow_desc_action), }, + }; + const struct desc_info *const info = &info_rep[!!is_action]; + unsigned int type = (uintptr_t)src; + + if (type >= info->num) + return rte_flow_error_set + (error, EINVAL, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL, + "unknown object type to retrieve the name of"); + if (!is_ptr) + return strlcpy(dst, info->data[type].name, size); + if (size >= sizeof(const char **)) + *((const char **)dst) = info->data[type].name; + return sizeof(const char **); +} + /** Helper function to convert flow API objects. */ int rte_flow_conv(enum rte_flow_conv_op op, @@ -708,6 +763,14 @@ rte_flow_conv(enum rte_flow_conv_op op, return rte_flow_conv_actions(dst, size, src, 0, error); case RTE_FLOW_CONV_OP_RULE: return rte_flow_conv_rule(dst, size, src, error); + case RTE_FLOW_CONV_OP_ITEM_NAME: + return rte_flow_conv_name(0, 0, dst, size, src, error); + case RTE_FLOW_CONV_OP_ACTION_NAME: + return rte_flow_conv_name(1, 0, dst, size, src, error); + case RTE_FLOW_CONV_OP_ITEM_NAME_PTR: + return rte_flow_conv_name(0, 1, dst, size, src, error); + case RTE_FLOW_CONV_OP_ACTION_NAME_PTR: + return rte_flow_conv_name(1, 1, dst, size, src, error); } return rte_flow_error_set (error, ENOTSUP, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL, diff --git a/lib/librte_ethdev/rte_flow.h b/lib/librte_ethdev/rte_flow.h index 1288e76ae..052ceefb6 100644 --- a/lib/librte_ethdev/rte_flow.h +++ b/lib/librte_ethdev/rte_flow.h @@ -2043,6 +2043,62 @@ enum rte_flow_conv_op { * @code struct rte_flow_conv_rule * @endcode */ RTE_FLOW_CONV_OP_RULE, + + /** + * Convert item type to its name string. + * + * Writes a NUL-terminated string to @p dst. Like snprintf(), the + * returned value excludes the terminator which is always written + * nonetheless. + * + * - @p src type: + * @code (const void *)enum rte_flow_item_type @endcode + * - @p dst type: + * @code char * @endcode + **/ + RTE_FLOW_CONV_OP_ITEM_NAME, + + /** + * Convert action type to its name string. + * + * Writes a NUL-terminated string to @p dst. Like snprintf(), the + * returned value excludes the terminator which is always written + * nonetheless. + * + * - @p src type: + * @code (const void *)enum rte_flow_action_type @endcode + * - @p dst type: + * @code char * @endcode + **/ + RTE_FLOW_CONV_OP_ACTION_NAME, + + /** + * Convert item type to pointer to item name. + * + * Retrieves item name pointer from its type. The string itself is + * not copied; instead, a unique pointer to an internal static + * constant storage is written to @p dst. + * + * - @p src type: + * @code (const void *)enum rte_flow_item_type @endcode + * - @p dst type: + * @code const char ** @endcode + */ + RTE_FLOW_CONV_OP_ITEM_NAME_PTR, + + /** + * Convert action type to pointer to action name. + * + * Retrieves action name pointer from its type. The string itself is + * not copied; instead, a unique pointer to an internal static + * constant storage is written to @p dst. + * + * - @p src type: + * @code (const void *)enum rte_flow_action_type @endcode + * - @p dst type: + * @code const char ** @endcode + */ + RTE_FLOW_CONV_OP_ACTION_NAME_PTR, }; /** From patchwork Fri Aug 31 09:01:05 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Adrien Mazarguil X-Patchwork-Id: 44070 X-Patchwork-Delegate: ferruh.yigit@amd.com Return-Path: X-Original-To: patchwork@dpdk.org Delivered-To: patchwork@dpdk.org Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id 5D3ED4CAD; Fri, 31 Aug 2018 11:01:27 +0200 (CEST) Received: from mail-wm0-f66.google.com (mail-wm0-f66.google.com [74.125.82.66]) by dpdk.org (Postfix) with ESMTP id 3763D4CB5 for ; Fri, 31 Aug 2018 11:01:23 +0200 (CEST) Received: by mail-wm0-f66.google.com with SMTP id 207-v6so4555493wme.5 for ; Fri, 31 Aug 2018 02:01:23 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=6wind-com.20150623.gappssmtp.com; s=20150623; h=date:from:to:cc:subject:message-id:references:mime-version :content-disposition:in-reply-to; bh=uZWaJBCF8DXwsgM3fA8vgZOFwnIey6nXwDh+v4XMXKw=; b=pGyzWQzVGlm8+rU+p4GKVv9Lx2xMSd4iINaMy7iV8z8wQP7+wKemTj+ishqNNsuE+b GDUG2whFuKSkSnuw1PdvyR3rvvlOyJ81DlG/9tJ/cP9Yo/hvWwPBGos6kRK6dRvKjqhP e9U/EkLRVTEtFAeM9/oMCcNcOi3Smvt5jh/oMNOXiuBAOjBuCK6ZM2Zg7r9KyonaoKIC oa2I4Nj93R07vcbB+D8BdTsnVsbB7NNvVAzipEaQYH3yDz/8w2VeY9fUfxHWq83cch8l J+B5IOliVG0PDPfQ3xgZ/mWKnplKCnirjPU9RKZLmI+L6A2wjQAW9uphDfHuO3syVeBn H1ow== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:from:to:cc:subject:message-id:references :mime-version:content-disposition:in-reply-to; bh=uZWaJBCF8DXwsgM3fA8vgZOFwnIey6nXwDh+v4XMXKw=; b=RvT79YRZwDJ3QDpZTusrEJgHsYUf7rXDvV6kEIhsyY9ZZLUs1X2zqGhtdgYHTAL2un e9uBuiKIsnQn1GOkmYLvcweWlk5NIw94MV+R761OXxNanrN0/hVwEzNyyBeVNg2rS8Tc DPpB9sezpzImPqyoge4jaOwJPUUYIVfsHvP9e/I/TFLZGoYMtMFVJhYJfGNMRuaZmfYO uHmq8B7Z5DighMA0O8E9vXP+v7nD7jCSRSfcVcN9gI0m/jsBbha4C7LSMxfm8Znz1OWw j4M98OlqMRpw8+EnVQFkOdBdfoMIGZXuFwbA0XG7fy3yWhL7fCFZMORUkkKPwhmGk0Vb QdrA== X-Gm-Message-State: APzg51C6TL7TbPrlqb7aPMM5FQEm4zS2DZdYuEHjcElvV2vAetWEFtH9 HKe1SRavRxwPhnYrRBYeWRJ3NINS3JlD9w== X-Google-Smtp-Source: ANB0VdYOKtUD0eZZPaNujSiInj3UDasxxxCtxgjiR2YCWGlx/Zc7YNIMJZzkV+Y7zLFaRgS/PCOvvQ== X-Received: by 2002:a1c:be06:: with SMTP id o6-v6mr4090404wmf.65.1535706081383; Fri, 31 Aug 2018 02:01:21 -0700 (PDT) Received: from 6wind.com (host.78.145.23.62.rev.coltfrance.com. [62.23.145.78]) by smtp.gmail.com with ESMTPSA id x16-v6sm13699325wrm.69.2018.08.31.02.01.20 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 31 Aug 2018 02:01:20 -0700 (PDT) Date: Fri, 31 Aug 2018 11:01:05 +0200 From: Adrien Mazarguil To: Ferruh Yigit Cc: dev@dpdk.org, Wenzhuo Lu , Jingjing Wu , Bernard Iremonger Message-ID: <20180831085337.21419-4-adrien.mazarguil@6wind.com> References: <20180803132032.29038-1-adrien.mazarguil@6wind.com> <20180831085337.21419-1-adrien.mazarguil@6wind.com> MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: <20180831085337.21419-1-adrien.mazarguil@6wind.com> X-Mailer: git-send-email 2.11.0 Subject: [dpdk-dev] [PATCH v3 3/7] app/testpmd: rely on flow API conversion function X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" This commit replaces all local information about pattern items and actions as well as flow rule duplication code with calls to rte_flow_conv(). Signed-off-by: Adrien Mazarguil Cc: Wenzhuo Lu Cc: Jingjing Wu Cc: Bernard Iremonger --- app/test-pmd/config.c | 407 +++++++------------------------------------- app/test-pmd/testpmd.h | 7 +- 2 files changed, 67 insertions(+), 347 deletions(-) diff --git a/app/test-pmd/config.c b/app/test-pmd/config.c index 14ccd6864..669be168b 100644 --- a/app/test-pmd/config.c +++ b/app/test-pmd/config.c @@ -984,324 +984,35 @@ port_mtu_set(portid_t port_id, uint16_t mtu) /* Generic flow management functions. */ -/** Generate flow_item[] entry. */ -#define MK_FLOW_ITEM(t, s) \ - [RTE_FLOW_ITEM_TYPE_ ## t] = { \ - .name = # t, \ - .size = s, \ - } - -/** Information about known flow pattern items. */ -static const struct { - const char *name; - size_t size; -} flow_item[] = { - MK_FLOW_ITEM(END, 0), - MK_FLOW_ITEM(VOID, 0), - MK_FLOW_ITEM(INVERT, 0), - MK_FLOW_ITEM(ANY, sizeof(struct rte_flow_item_any)), - MK_FLOW_ITEM(PF, 0), - MK_FLOW_ITEM(VF, sizeof(struct rte_flow_item_vf)), - MK_FLOW_ITEM(PHY_PORT, sizeof(struct rte_flow_item_phy_port)), - MK_FLOW_ITEM(PORT_ID, sizeof(struct rte_flow_item_port_id)), - MK_FLOW_ITEM(RAW, sizeof(struct rte_flow_item_raw)), - MK_FLOW_ITEM(ETH, sizeof(struct rte_flow_item_eth)), - MK_FLOW_ITEM(VLAN, sizeof(struct rte_flow_item_vlan)), - MK_FLOW_ITEM(IPV4, sizeof(struct rte_flow_item_ipv4)), - MK_FLOW_ITEM(IPV6, sizeof(struct rte_flow_item_ipv6)), - MK_FLOW_ITEM(ICMP, sizeof(struct rte_flow_item_icmp)), - MK_FLOW_ITEM(UDP, sizeof(struct rte_flow_item_udp)), - MK_FLOW_ITEM(TCP, sizeof(struct rte_flow_item_tcp)), - MK_FLOW_ITEM(SCTP, sizeof(struct rte_flow_item_sctp)), - MK_FLOW_ITEM(VXLAN, sizeof(struct rte_flow_item_vxlan)), - MK_FLOW_ITEM(E_TAG, sizeof(struct rte_flow_item_e_tag)), - MK_FLOW_ITEM(NVGRE, sizeof(struct rte_flow_item_nvgre)), - MK_FLOW_ITEM(MPLS, sizeof(struct rte_flow_item_mpls)), - MK_FLOW_ITEM(GRE, sizeof(struct rte_flow_item_gre)), - MK_FLOW_ITEM(FUZZY, sizeof(struct rte_flow_item_fuzzy)), - MK_FLOW_ITEM(GTP, sizeof(struct rte_flow_item_gtp)), - MK_FLOW_ITEM(GTPC, sizeof(struct rte_flow_item_gtp)), - MK_FLOW_ITEM(GTPU, sizeof(struct rte_flow_item_gtp)), - MK_FLOW_ITEM(GENEVE, sizeof(struct rte_flow_item_geneve)), - MK_FLOW_ITEM(VXLAN_GPE, sizeof(struct rte_flow_item_vxlan_gpe)), - MK_FLOW_ITEM(ARP_ETH_IPV4, sizeof(struct rte_flow_item_arp_eth_ipv4)), - MK_FLOW_ITEM(IPV6_EXT, sizeof(struct rte_flow_item_ipv6_ext)), - MK_FLOW_ITEM(ICMP6, sizeof(struct rte_flow_item_icmp6)), - MK_FLOW_ITEM(ICMP6_ND_NS, sizeof(struct rte_flow_item_icmp6_nd_ns)), - MK_FLOW_ITEM(ICMP6_ND_NA, sizeof(struct rte_flow_item_icmp6_nd_na)), - MK_FLOW_ITEM(ICMP6_ND_OPT, sizeof(struct rte_flow_item_icmp6_nd_opt)), - MK_FLOW_ITEM(ICMP6_ND_OPT_SLA_ETH, - sizeof(struct rte_flow_item_icmp6_nd_opt_sla_eth)), - MK_FLOW_ITEM(ICMP6_ND_OPT_TLA_ETH, - sizeof(struct rte_flow_item_icmp6_nd_opt_tla_eth)), -}; - -/** Pattern item specification types. */ -enum item_spec_type { - ITEM_SPEC, - ITEM_LAST, - ITEM_MASK, -}; - -/** Compute storage space needed by item specification and copy it. */ -static size_t -flow_item_spec_copy(void *buf, const struct rte_flow_item *item, - enum item_spec_type type) -{ - size_t size = 0; - const void *data = - type == ITEM_SPEC ? item->spec : - type == ITEM_LAST ? item->last : - type == ITEM_MASK ? item->mask : - NULL; - - if (!item->spec || !data) - goto empty; - switch (item->type) { - union { - const struct rte_flow_item_raw *raw; - } spec; - union { - const struct rte_flow_item_raw *raw; - } last; - union { - const struct rte_flow_item_raw *raw; - } mask; - union { - const struct rte_flow_item_raw *raw; - } src; - union { - struct rte_flow_item_raw *raw; - } dst; - size_t off; - - case RTE_FLOW_ITEM_TYPE_RAW: - spec.raw = item->spec; - last.raw = item->last ? item->last : item->spec; - mask.raw = item->mask ? item->mask : &rte_flow_item_raw_mask; - src.raw = data; - dst.raw = buf; - off = RTE_ALIGN_CEIL(sizeof(struct rte_flow_item_raw), - sizeof(*src.raw->pattern)); - if (type == ITEM_SPEC || - (type == ITEM_MASK && - ((spec.raw->length & mask.raw->length) >= - (last.raw->length & mask.raw->length)))) - size = spec.raw->length & mask.raw->length; - else - size = last.raw->length & mask.raw->length; - size = off + size * sizeof(*src.raw->pattern); - if (dst.raw) { - memcpy(dst.raw, src.raw, sizeof(*src.raw)); - dst.raw->pattern = memcpy((uint8_t *)dst.raw + off, - src.raw->pattern, - size - off); - } - break; - default: - size = flow_item[item->type].size; - if (buf) - memcpy(buf, data, size); - break; - } -empty: - return RTE_ALIGN_CEIL(size, sizeof(double)); -} - -/** Generate flow_action[] entry. */ -#define MK_FLOW_ACTION(t, s) \ - [RTE_FLOW_ACTION_TYPE_ ## t] = { \ - .name = # t, \ - .size = s, \ - } - -/** Information about known flow actions. */ -static const struct { - const char *name; - size_t size; -} flow_action[] = { - MK_FLOW_ACTION(END, 0), - MK_FLOW_ACTION(VOID, 0), - MK_FLOW_ACTION(PASSTHRU, 0), - MK_FLOW_ACTION(MARK, sizeof(struct rte_flow_action_mark)), - MK_FLOW_ACTION(FLAG, 0), - MK_FLOW_ACTION(QUEUE, sizeof(struct rte_flow_action_queue)), - MK_FLOW_ACTION(DROP, 0), - MK_FLOW_ACTION(COUNT, sizeof(struct rte_flow_action_count)), - MK_FLOW_ACTION(RSS, sizeof(struct rte_flow_action_rss)), - MK_FLOW_ACTION(PF, 0), - MK_FLOW_ACTION(VF, sizeof(struct rte_flow_action_vf)), - MK_FLOW_ACTION(PHY_PORT, sizeof(struct rte_flow_action_phy_port)), - MK_FLOW_ACTION(PORT_ID, sizeof(struct rte_flow_action_port_id)), - MK_FLOW_ACTION(METER, sizeof(struct rte_flow_action_meter)), - MK_FLOW_ACTION(OF_SET_MPLS_TTL, - sizeof(struct rte_flow_action_of_set_mpls_ttl)), - MK_FLOW_ACTION(OF_DEC_MPLS_TTL, 0), - MK_FLOW_ACTION(OF_SET_NW_TTL, - sizeof(struct rte_flow_action_of_set_nw_ttl)), - MK_FLOW_ACTION(OF_DEC_NW_TTL, 0), - MK_FLOW_ACTION(OF_COPY_TTL_OUT, 0), - MK_FLOW_ACTION(OF_COPY_TTL_IN, 0), - MK_FLOW_ACTION(OF_POP_VLAN, 0), - MK_FLOW_ACTION(OF_PUSH_VLAN, - sizeof(struct rte_flow_action_of_push_vlan)), - MK_FLOW_ACTION(OF_SET_VLAN_VID, - sizeof(struct rte_flow_action_of_set_vlan_vid)), - MK_FLOW_ACTION(OF_SET_VLAN_PCP, - sizeof(struct rte_flow_action_of_set_vlan_pcp)), - MK_FLOW_ACTION(OF_POP_MPLS, - sizeof(struct rte_flow_action_of_pop_mpls)), - MK_FLOW_ACTION(OF_PUSH_MPLS, - sizeof(struct rte_flow_action_of_push_mpls)), -}; - -/** Compute storage space needed by action configuration and copy it. */ -static size_t -flow_action_conf_copy(void *buf, const struct rte_flow_action *action) -{ - size_t size = 0; - - if (!action->conf) - goto empty; - switch (action->type) { - union { - const struct rte_flow_action_rss *rss; - } src; - union { - struct rte_flow_action_rss *rss; - } dst; - size_t off; - - case RTE_FLOW_ACTION_TYPE_RSS: - src.rss = action->conf; - dst.rss = buf; - off = 0; - if (dst.rss) - *dst.rss = (struct rte_flow_action_rss){ - .func = src.rss->func, - .level = src.rss->level, - .types = src.rss->types, - .key_len = src.rss->key_len, - .queue_num = src.rss->queue_num, - }; - off += sizeof(*src.rss); - if (src.rss->key_len) { - off = RTE_ALIGN_CEIL(off, sizeof(double)); - size = sizeof(*src.rss->key) * src.rss->key_len; - if (dst.rss) - dst.rss->key = memcpy - ((void *)((uintptr_t)dst.rss + off), - src.rss->key, size); - off += size; - } - if (src.rss->queue_num) { - off = RTE_ALIGN_CEIL(off, sizeof(double)); - size = sizeof(*src.rss->queue) * src.rss->queue_num; - if (dst.rss) - dst.rss->queue = memcpy - ((void *)((uintptr_t)dst.rss + off), - src.rss->queue, size); - off += size; - } - size = off; - break; - default: - size = flow_action[action->type].size; - if (buf) - memcpy(buf, action->conf, size); - break; - } -empty: - return RTE_ALIGN_CEIL(size, sizeof(double)); -} - /** Generate a port_flow entry from attributes/pattern/actions. */ static struct port_flow * port_flow_new(const struct rte_flow_attr *attr, const struct rte_flow_item *pattern, - const struct rte_flow_action *actions) -{ - const struct rte_flow_item *item; - const struct rte_flow_action *action; - struct port_flow *pf = NULL; - size_t tmp; - size_t off1 = 0; - size_t off2 = 0; - int err = ENOTSUP; - -store: - item = pattern; - if (pf) - pf->pattern = (void *)&pf->data[off1]; - do { - struct rte_flow_item *dst = NULL; - - if ((unsigned int)item->type >= RTE_DIM(flow_item) || - !flow_item[item->type].name) - goto notsup; - if (pf) - dst = memcpy(pf->data + off1, item, sizeof(*item)); - off1 += sizeof(*item); - if (item->spec) { - if (pf) - dst->spec = pf->data + off2; - off2 += flow_item_spec_copy - (pf ? pf->data + off2 : NULL, item, ITEM_SPEC); - } - if (item->last) { - if (pf) - dst->last = pf->data + off2; - off2 += flow_item_spec_copy - (pf ? pf->data + off2 : NULL, item, ITEM_LAST); - } - if (item->mask) { - if (pf) - dst->mask = pf->data + off2; - off2 += flow_item_spec_copy - (pf ? pf->data + off2 : NULL, item, ITEM_MASK); - } - off2 = RTE_ALIGN_CEIL(off2, sizeof(double)); - } while ((item++)->type != RTE_FLOW_ITEM_TYPE_END); - off1 = RTE_ALIGN_CEIL(off1, sizeof(double)); - action = actions; - if (pf) - pf->actions = (void *)&pf->data[off1]; - do { - struct rte_flow_action *dst = NULL; - - if ((unsigned int)action->type >= RTE_DIM(flow_action) || - !flow_action[action->type].name) - goto notsup; - if (pf) - dst = memcpy(pf->data + off1, action, sizeof(*action)); - off1 += sizeof(*action); - if (action->conf) { - if (pf) - dst->conf = pf->data + off2; - off2 += flow_action_conf_copy - (pf ? pf->data + off2 : NULL, action); - } - off2 = RTE_ALIGN_CEIL(off2, sizeof(double)); - } while ((action++)->type != RTE_FLOW_ACTION_TYPE_END); - if (pf != NULL) + const struct rte_flow_action *actions, + struct rte_flow_error *error) +{ + const struct rte_flow_conv_rule rule = { + .attr_ro = attr, + .pattern_ro = pattern, + .actions_ro = actions, + }; + struct port_flow *pf; + int ret; + + ret = rte_flow_conv(RTE_FLOW_CONV_OP_RULE, NULL, 0, &rule, error); + if (ret < 0) + return NULL; + pf = calloc(1, offsetof(struct port_flow, rule) + ret); + if (!pf) { + rte_flow_error_set + (error, errno, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL, + "calloc() failed"); + return NULL; + } + if (rte_flow_conv(RTE_FLOW_CONV_OP_RULE, &pf->rule, ret, &rule, + error) >= 0) return pf; - off1 = RTE_ALIGN_CEIL(off1, sizeof(double)); - tmp = RTE_ALIGN_CEIL(offsetof(struct port_flow, data), sizeof(double)); - pf = calloc(1, tmp + off1 + off2); - if (pf == NULL) - err = errno; - else { - *pf = (const struct port_flow){ - .size = tmp + off1 + off2, - .attr = *attr, - }; - tmp -= offsetof(struct port_flow, data); - off2 = tmp + off1; - off1 = tmp; - goto store; - } -notsup: - rte_errno = err; + free(pf); return NULL; } @@ -1391,13 +1102,10 @@ port_flow_create(portid_t port_id, id = port->flow_list->id + 1; } else id = 0; - pf = port_flow_new(attr, pattern, actions); + pf = port_flow_new(attr, pattern, actions, &error); if (!pf) { - int err = rte_errno; - - printf("Cannot allocate flow: %s\n", rte_strerror(err)); rte_flow_destroy(port_id, flow, NULL); - return -err; + return port_flow_complain(&error); } pf->next = port->flow_list; pf->id = id; @@ -1489,6 +1197,7 @@ port_flow_query(portid_t port_id, uint32_t rule, union { struct rte_flow_query_count count; } query; + int ret; if (port_id_is_invalid(port_id, ENABLED_WARN) || port_id == (portid_t)RTE_PORT_ALL) @@ -1501,11 +1210,10 @@ port_flow_query(portid_t port_id, uint32_t rule, printf("Flow rule #%u not found\n", rule); return -ENOENT; } - if ((unsigned int)action->type >= RTE_DIM(flow_action) || - !flow_action[action->type].name) - name = "unknown"; - else - name = flow_action[action->type].name; + ret = rte_flow_conv(RTE_FLOW_CONV_OP_ACTION_NAME_PTR, + &name, sizeof(name), action, &error); + if (ret < 0) + return port_flow_complain(&error); switch (action->type) { case RTE_FLOW_ACTION_TYPE_COUNT: break; @@ -1558,48 +1266,63 @@ port_flow_list(portid_t port_id, uint32_t n, const uint32_t group[n]) /* Sort flows by group, priority and ID. */ for (pf = port->flow_list; pf != NULL; pf = pf->next) { struct port_flow **tmp; + const struct rte_flow_attr *curr = pf->rule.attr; if (n) { /* Filter out unwanted groups. */ for (i = 0; i != n; ++i) - if (pf->attr.group == group[i]) + if (curr->group == group[i]) break; if (i == n) continue; } - tmp = &list; - while (*tmp && - (pf->attr.group > (*tmp)->attr.group || - (pf->attr.group == (*tmp)->attr.group && - pf->attr.priority > (*tmp)->attr.priority) || - (pf->attr.group == (*tmp)->attr.group && - pf->attr.priority == (*tmp)->attr.priority && - pf->id > (*tmp)->id))) - tmp = &(*tmp)->tmp; + for (tmp = &list; *tmp; tmp = &(*tmp)->tmp) { + const struct rte_flow_attr *comp = (*tmp)->rule.attr; + + if (curr->group > comp->group || + (curr->group == comp->group && + curr->priority > comp->priority) || + (curr->group == comp->group && + curr->priority == comp->priority && + pf->id > (*tmp)->id)) + continue; + break; + } pf->tmp = *tmp; *tmp = pf; } printf("ID\tGroup\tPrio\tAttr\tRule\n"); for (pf = list; pf != NULL; pf = pf->tmp) { - const struct rte_flow_item *item = pf->pattern; - const struct rte_flow_action *action = pf->actions; + const struct rte_flow_item *item = pf->rule.pattern; + const struct rte_flow_action *action = pf->rule.actions; + const char *name; printf("%" PRIu32 "\t%" PRIu32 "\t%" PRIu32 "\t%c%c%c\t", pf->id, - pf->attr.group, - pf->attr.priority, - pf->attr.ingress ? 'i' : '-', - pf->attr.egress ? 'e' : '-', - pf->attr.transfer ? 't' : '-'); + pf->rule.attr->group, + pf->rule.attr->priority, + pf->rule.attr->ingress ? 'i' : '-', + pf->rule.attr->egress ? 'e' : '-', + pf->rule.attr->transfer ? 't' : '-'); while (item->type != RTE_FLOW_ITEM_TYPE_END) { + if (rte_flow_conv(RTE_FLOW_CONV_OP_ITEM_NAME_PTR, + &name, sizeof(name), + (void *)(uintptr_t)item->type, + NULL) <= 0) + name = "[UNKNOWN]"; if (item->type != RTE_FLOW_ITEM_TYPE_VOID) - printf("%s ", flow_item[item->type].name); + printf("%s ", name); ++item; } printf("=>"); while (action->type != RTE_FLOW_ACTION_TYPE_END) { + if (rte_flow_conv(RTE_FLOW_CONV_OP_ACTION_NAME_PTR, + &name, sizeof(name), + (void *)(uintptr_t)action->type, + NULL) <= 0) + name = "[UNKNOWN]"; if (action->type != RTE_FLOW_ACTION_TYPE_VOID) - printf(" %s", flow_action[action->type].name); + printf(" %s", name); ++action; } printf("\n"); diff --git a/app/test-pmd/testpmd.h b/app/test-pmd/testpmd.h index a1f661472..11afb487f 100644 --- a/app/test-pmd/testpmd.h +++ b/app/test-pmd/testpmd.h @@ -124,15 +124,12 @@ struct fwd_stream { /** Descriptor for a single flow. */ struct port_flow { - size_t size; /**< Allocated space including data[]. */ struct port_flow *next; /**< Next flow in list. */ struct port_flow *tmp; /**< Temporary linking. */ uint32_t id; /**< Flow rule ID. */ struct rte_flow *flow; /**< Opaque flow object returned by PMD. */ - struct rte_flow_attr attr; /**< Attributes. */ - struct rte_flow_item *pattern; /**< Pattern. */ - struct rte_flow_action *actions; /**< Actions. */ - uint8_t data[]; /**< Storage for pattern/actions. */ + struct rte_flow_conv_rule rule; /* Saved flow rule description. */ + uint8_t data[]; /**< Storage for flow rule description */ }; #ifdef SOFTNIC From patchwork Fri Aug 31 09:01:07 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Adrien Mazarguil X-Patchwork-Id: 44071 X-Patchwork-Delegate: ferruh.yigit@amd.com Return-Path: X-Original-To: patchwork@dpdk.org Delivered-To: patchwork@dpdk.org Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id C249A4F94; Fri, 31 Aug 2018 11:01:30 +0200 (CEST) Received: from mail-wm0-f46.google.com (mail-wm0-f46.google.com [74.125.82.46]) by dpdk.org (Postfix) with ESMTP id EFEB34C88 for ; Fri, 31 Aug 2018 11:01:23 +0200 (CEST) Received: by mail-wm0-f46.google.com with SMTP id b19-v6so4475406wme.3 for ; Fri, 31 Aug 2018 02:01:23 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=6wind-com.20150623.gappssmtp.com; s=20150623; h=date:from:to:cc:subject:message-id:references:mime-version :content-disposition:in-reply-to; bh=PtvSO8AnfduGqjsbwqMjjOWkPQJnQbptU1MYVAkL/8g=; b=QXGp5c9e2vNk7V3sdgDfynfT9yvLPdaqEy/12/Zk6ju+U7kJSRbRq/tgFkzAcHQtUS dGf7nVKWJXjTsWp7m7ChlPjyeaVpr+WZqEfVpIiM45eHbif5/H4rVV4QkIPPNZAFnwrP /iBTna04Byp1QIYJXHcybI/rcl1p/Yh2x5rX3MOOk/l4Wko1sSn4yBtiAvhJR2mAU1s3 BB5uqaVVs7hZQIGb57d7KsFx7MViNrg7sM/raNbHLM+Kdn+SS0qfY3+lTYYzxCx5bF6W ZDVtZxC4F5y1cefUjareBObszLfYIVjjmF47EA4Y6h9ijOAmGJfrSte+RaWAXyFCJNYv hAow== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:from:to:cc:subject:message-id:references :mime-version:content-disposition:in-reply-to; bh=PtvSO8AnfduGqjsbwqMjjOWkPQJnQbptU1MYVAkL/8g=; b=Zt2C4PbHOUAFOLplkQ0XWuXHq316ly9q58hhdAJaN2N5SE50kvGZbq6pqR8mhyAhOw +Vv6+cfxNm319GgduGcITH9P/TpZ47+bYdBloa0S+Hu18M8MS7jpKURq+TlzjsV0SQrC IKDgHHxulRO4elsLqERMoMuQsgmP/V1fhs/GSaE5UTg79Kg5oLLUmDav+toYCyCH+rUu iWUutY4dtyHvVZCNsThA/tCSej5+hFxEEeeA9TBUcK8FDuzq7cwI54R4aRHLXkoyzgQt ZQa6AGWSLUaOijl2QdunmwMfkDBJHEKDha0PZnBNCCAPsgyN6S+IONZwlBp9GhZNyjfM Hv8Q== X-Gm-Message-State: APzg51BkS7LwqFUNSyHDvtVbtrrtOuAPCbu4wk5R0MSOouKzcjVBZFGX dzI7KMtjT5eJ1xXt9nEwZKIaQw== X-Google-Smtp-Source: ANB0Vdb1tpe3cleUo2Sbvg71Mjqn9JhzppTWUFh0xSndrSRpyfIR3i6hHKBFs8r4ssSyfERSPI2Waw== X-Received: by 2002:a1c:5f82:: with SMTP id t124-v6mr4212903wmb.14.1535706083688; Fri, 31 Aug 2018 02:01:23 -0700 (PDT) Received: from 6wind.com (host.78.145.23.62.rev.coltfrance.com. [62.23.145.78]) by smtp.gmail.com with ESMTPSA id b124-v6sm3385141wmh.17.2018.08.31.02.01.22 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 31 Aug 2018 02:01:22 -0700 (PDT) Date: Fri, 31 Aug 2018 11:01:07 +0200 From: Adrien Mazarguil To: Ferruh Yigit Cc: dev@dpdk.org, Gaetan Rivet Message-ID: <20180831085337.21419-5-adrien.mazarguil@6wind.com> References: <20180803132032.29038-1-adrien.mazarguil@6wind.com> <20180831085337.21419-1-adrien.mazarguil@6wind.com> MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: <20180831085337.21419-1-adrien.mazarguil@6wind.com> X-Mailer: git-send-email 2.11.0 Subject: [dpdk-dev] [PATCH v3 4/7] net/failsafe: switch to flow API object conversion function X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" This patch replaces rte_flow_copy() with rte_flow_conv(). Signed-off-by: Adrien Mazarguil Cc: Gaetan Rivet --- v2 changes: - Patch was split from "ethdev: add flow API object converter". --- drivers/net/failsafe/failsafe_ether.c | 6 +++--- drivers/net/failsafe/failsafe_flow.c | 31 +++++++++++++++++++++------- drivers/net/failsafe/failsafe_private.h | 5 ++++- 3 files changed, 31 insertions(+), 11 deletions(-) diff --git a/drivers/net/failsafe/failsafe_ether.c b/drivers/net/failsafe/failsafe_ether.c index 5b5cb3b49..8bce368f3 100644 --- a/drivers/net/failsafe/failsafe_ether.c +++ b/drivers/net/failsafe/failsafe_ether.c @@ -230,9 +230,9 @@ fs_eth_dev_conf_apply(struct rte_eth_dev *dev, DEBUG("Creating flow #%" PRIu32, i++); flow->flows[SUB_ID(sdev)] = rte_flow_create(PORT_ID(sdev), - &flow->fd->attr, - flow->fd->items, - flow->fd->actions, + flow->rule.attr, + flow->rule.pattern, + flow->rule.actions, &ferror); ret = rte_errno; if (ret) diff --git a/drivers/net/failsafe/failsafe_flow.c b/drivers/net/failsafe/failsafe_flow.c index bfe42fcee..5e2b5f7c6 100644 --- a/drivers/net/failsafe/failsafe_flow.c +++ b/drivers/net/failsafe/failsafe_flow.c @@ -3,8 +3,11 @@ * Copyright 2017 Mellanox Technologies, Ltd */ +#include +#include #include +#include #include #include #include @@ -18,19 +21,33 @@ fs_flow_allocate(const struct rte_flow_attr *attr, const struct rte_flow_action *actions) { struct rte_flow *flow; - size_t fdsz; + const struct rte_flow_conv_rule rule = { + .attr_ro = attr, + .pattern_ro = items, + .actions_ro = actions, + }; + struct rte_flow_error error; + int ret; - fdsz = rte_flow_copy(NULL, 0, attr, items, actions); - flow = rte_zmalloc(NULL, - sizeof(struct rte_flow) + fdsz, + ret = rte_flow_conv(RTE_FLOW_CONV_OP_RULE, NULL, 0, &rule, &error); + if (ret < 0) { + ERROR("Unable to process flow rule (%s): %s", + error.message ? error.message : "unspecified", + strerror(rte_errno)); + return NULL; + } + flow = rte_zmalloc(NULL, offsetof(struct rte_flow, rule) + ret, RTE_CACHE_LINE_SIZE); if (flow == NULL) { ERROR("Could not allocate new flow"); return NULL; } - flow->fd = (void *)((uintptr_t)flow + sizeof(*flow)); - if (rte_flow_copy(flow->fd, fdsz, attr, items, actions) != fdsz) { - ERROR("Failed to copy flow description"); + ret = rte_flow_conv(RTE_FLOW_CONV_OP_RULE, &flow->rule, ret, &rule, + &error); + if (ret < 0) { + ERROR("Failed to copy flow rule (%s): %s", + error.message ? error.message : "unspecified", + strerror(rte_errno)); rte_free(flow); return NULL; } diff --git a/drivers/net/failsafe/failsafe_private.h b/drivers/net/failsafe/failsafe_private.h index 886af8616..cc1f0343d 100644 --- a/drivers/net/failsafe/failsafe_private.h +++ b/drivers/net/failsafe/failsafe_private.h @@ -6,6 +6,7 @@ #ifndef _RTE_ETH_FAILSAFE_PRIVATE_H_ #define _RTE_ETH_FAILSAFE_PRIVATE_H_ +#include #include #include @@ -13,6 +14,7 @@ #include #include #include +#include #include #define FAILSAFE_DRIVER_NAME "Fail-safe PMD" @@ -81,7 +83,8 @@ struct rte_flow { /* sub_flows */ struct rte_flow *flows[FAILSAFE_MAX_ETHPORTS]; /* flow description for synchronization */ - struct rte_flow_desc *fd; + struct rte_flow_conv_rule rule; + uint8_t rule_data[]; }; enum dev_state { From patchwork Fri Aug 31 09:01:09 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Adrien Mazarguil X-Patchwork-Id: 44073 X-Patchwork-Delegate: ferruh.yigit@amd.com Return-Path: X-Original-To: patchwork@dpdk.org Delivered-To: patchwork@dpdk.org Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id C14FB5592; Fri, 31 Aug 2018 11:01:45 +0200 (CEST) Received: from mail-wm0-f68.google.com (mail-wm0-f68.google.com [74.125.82.68]) by dpdk.org (Postfix) with ESMTP id F2FAD4CC3 for ; Fri, 31 Aug 2018 11:01:28 +0200 (CEST) Received: by mail-wm0-f68.google.com with SMTP id j192-v6so4604372wmj.1 for ; Fri, 31 Aug 2018 02:01:28 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=6wind-com.20150623.gappssmtp.com; s=20150623; h=date:from:to:cc:subject:message-id:references:mime-version :content-disposition:in-reply-to; bh=WL1ZCGXmmmOi1dEv8prvXA3nQwRxNiW26HZHh7kqZKI=; b=xnnDmbQYhDMRv8SZiZhrdSnACRRucdjp6eJF389xwQF1CuVOwmw9uL9i5cgbQyvLy2 4x5+5+zxfCTPsEhHEHwclcd2kNlNDEsYg4SZQsYEMlfID49x+yCHABcr+naJqZc6pE5n LJ8iQzDTAlfzvo+F8SYvb5pUjc3piKyDsvQTnMeSSXQARZ3Izd4AigDnRPV6ypV94/Jy tyIQpwDp9mRxeDJYJ2eODuFalKdAcZ8ybj4Otkui9nIQvLikeccqvX3Oc3BkqN4nw4U4 97Uax1E1QuIwBer7V+QTuz+DDePWvPHqa6eqLYM47d76EWGcbCFuXhkaFsSdh0xqsOSE XkmA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:from:to:cc:subject:message-id:references :mime-version:content-disposition:in-reply-to; bh=WL1ZCGXmmmOi1dEv8prvXA3nQwRxNiW26HZHh7kqZKI=; b=r198qaVg2ox8/qWbzrUVu4KQurNEH3i2Qyi8BoosY3XHQTbrHTEw6Ye6Hvf+XtxA0p eEeRD0OChBqIVLTgY+cZqsVedV1tjTRwxDz1G6XSlU7CdCgSIoIdFiIHB7obv1Y71KuH ccfEf3NxqvcEkmC8MHECODF96HHb6FErYpoWgbmGutwG2YI7m81Ohsv/MeM748X8iLCB Z00XhZ+gWuQ9xBmCOHFi36JFHYiQ7ppRKKwAKLeR+YFjbyOix//gTmXItz1QlweUq6zk hhkkL/I2wbXyf2N+28GVYdirrQSTQvDCDbD/VBtcY2pF1Kf5ZuNwzeQpG0pXmYBsOY9d EK4g== X-Gm-Message-State: APzg51AzmfGLbP3FsBz4MIGThT23r+3Eo0rUXUfZOYqhq86B4umbMGH3 jtuO4GjXyyhXsdBZ//h0sor6zA== X-Google-Smtp-Source: ANB0VdbZX+Z8q6LAtTHwX6ljAU78kKotvwhEYakPXlxl/qGCD+xJhb7f9Q3PwyuK8eu05381N5dJhg== X-Received: by 2002:a1c:3e8f:: with SMTP id l137-v6mr3951783wma.132.1535706085720; Fri, 31 Aug 2018 02:01:25 -0700 (PDT) Received: from 6wind.com (host.78.145.23.62.rev.coltfrance.com. [62.23.145.78]) by smtp.gmail.com with ESMTPSA id e5-v6sm3021656wmh.29.2018.08.31.02.01.24 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 31 Aug 2018 02:01:24 -0700 (PDT) Date: Fri, 31 Aug 2018 11:01:09 +0200 From: Adrien Mazarguil To: Ferruh Yigit Cc: dev@dpdk.org, Declan Doherty , Chas Williams Message-ID: <20180831085337.21419-6-adrien.mazarguil@6wind.com> References: <20180803132032.29038-1-adrien.mazarguil@6wind.com> <20180831085337.21419-1-adrien.mazarguil@6wind.com> MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: <20180831085337.21419-1-adrien.mazarguil@6wind.com> X-Mailer: git-send-email 2.11.0 Subject: [dpdk-dev] [PATCH v3 5/7] net/bonding: switch to flow API object conversion function X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" This patch replaces rte_flow_copy() with rte_flow_conv(). Signed-off-by: Adrien Mazarguil Cc: Declan Doherty Cc: Chas Williams --- v3 changes: - Added build directives to allow experimental APIs, now needed for rte_flow_conv(). v2 changes: - Patch was not present in original series. --- drivers/net/bonding/Makefile | 1 + drivers/net/bonding/meson.build | 1 + drivers/net/bonding/rte_eth_bond_api.c | 6 ++--- drivers/net/bonding/rte_eth_bond_flow.c | 31 +++++++++++++++++++------ drivers/net/bonding/rte_eth_bond_private.h | 5 +++- 5 files changed, 33 insertions(+), 11 deletions(-) diff --git a/drivers/net/bonding/Makefile b/drivers/net/bonding/Makefile index acad16a1a..1893e3cad 100644 --- a/drivers/net/bonding/Makefile +++ b/drivers/net/bonding/Makefile @@ -8,6 +8,7 @@ include $(RTE_SDK)/mk/rte.vars.mk # LIB = librte_pmd_bond.a +CFLAGS += -DALLOW_EXPERIMENTAL_API CFLAGS += -O3 CFLAGS += $(WERROR_FLAGS) LDLIBS += -lrte_eal -lrte_mbuf -lrte_mempool -lrte_ring diff --git a/drivers/net/bonding/meson.build b/drivers/net/bonding/meson.build index 602d28803..00374edb2 100644 --- a/drivers/net/bonding/meson.build +++ b/drivers/net/bonding/meson.build @@ -3,6 +3,7 @@ name = 'bond' #, james bond :-) version = 2 +allow_experimental_apis = true sources = files('rte_eth_bond_api.c', 'rte_eth_bond_pmd.c', 'rte_eth_bond_flow.c', 'rte_eth_bond_args.c', 'rte_eth_bond_8023ad.c', 'rte_eth_bond_alb.c') diff --git a/drivers/net/bonding/rte_eth_bond_api.c b/drivers/net/bonding/rte_eth_bond_api.c index 8bc04cfd1..a438fc509 100644 --- a/drivers/net/bonding/rte_eth_bond_api.c +++ b/drivers/net/bonding/rte_eth_bond_api.c @@ -245,9 +245,9 @@ slave_rte_flow_prepare(uint16_t slave_id, struct bond_dev_private *internals) } TAILQ_FOREACH(flow, &internals->flow_list, next) { flow->flows[slave_id] = rte_flow_create(slave_port_id, - &flow->fd->attr, - flow->fd->items, - flow->fd->actions, + flow->rule.attr, + flow->rule.pattern, + flow->rule.actions, &ferror); if (flow->flows[slave_id] == NULL) { RTE_BOND_LOG(ERR, "Cannot create flow for slave" diff --git a/drivers/net/bonding/rte_eth_bond_flow.c b/drivers/net/bonding/rte_eth_bond_flow.c index 31e4bcaeb..f94d46ca4 100644 --- a/drivers/net/bonding/rte_eth_bond_flow.c +++ b/drivers/net/bonding/rte_eth_bond_flow.c @@ -2,8 +2,11 @@ * Copyright 2018 Mellanox Technologies, Ltd */ +#include +#include #include +#include #include #include #include @@ -16,19 +19,33 @@ bond_flow_alloc(int numa_node, const struct rte_flow_attr *attr, const struct rte_flow_action *actions) { struct rte_flow *flow; - size_t fdsz; + const struct rte_flow_conv_rule rule = { + .attr_ro = attr, + .pattern_ro = items, + .actions_ro = actions, + }; + struct rte_flow_error error; + int ret; - fdsz = rte_flow_copy(NULL, 0, attr, items, actions); - flow = rte_zmalloc_socket(NULL, sizeof(struct rte_flow) + fdsz, + ret = rte_flow_conv(RTE_FLOW_CONV_OP_RULE, NULL, 0, &rule, &error); + if (ret < 0) { + RTE_BOND_LOG(ERR, "Unable to process flow rule (%s): %s", + error.message ? error.message : "unspecified", + strerror(rte_errno)); + return NULL; + } + flow = rte_zmalloc_socket(NULL, offsetof(struct rte_flow, rule) + ret, RTE_CACHE_LINE_SIZE, numa_node); if (unlikely(flow == NULL)) { RTE_BOND_LOG(ERR, "Could not allocate new flow"); return NULL; } - flow->fd = (void *)((uintptr_t)flow + sizeof(*flow)); - if (unlikely(rte_flow_copy(flow->fd, fdsz, attr, items, actions) != - fdsz)) { - RTE_BOND_LOG(ERR, "Failed to copy flow description"); + ret = rte_flow_conv(RTE_FLOW_CONV_OP_RULE, &flow->rule, ret, &rule, + &error); + if (ret < 0) { + RTE_BOND_LOG(ERR, "Failed to copy flow rule (%s): %s", + error.message ? error.message : "unspecified", + strerror(rte_errno)); rte_free(flow); return NULL; } diff --git a/drivers/net/bonding/rte_eth_bond_private.h b/drivers/net/bonding/rte_eth_bond_private.h index 43e0e448d..61202845e 100644 --- a/drivers/net/bonding/rte_eth_bond_private.h +++ b/drivers/net/bonding/rte_eth_bond_private.h @@ -5,9 +5,11 @@ #ifndef _RTE_ETH_BOND_PRIVATE_H_ #define _RTE_ETH_BOND_PRIVATE_H_ +#include #include #include +#include #include #include #include @@ -93,7 +95,8 @@ struct rte_flow { /* Slaves flows */ struct rte_flow *flows[RTE_MAX_ETHPORTS]; /* Flow description for synchronization */ - struct rte_flow_desc *fd; + struct rte_flow_conv_rule rule; + uint8_t rule_data[]; }; typedef void (*burst_xmit_hash_t)(struct rte_mbuf **buf, uint16_t nb_pkts, From patchwork Fri Aug 31 09:01:11 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Adrien Mazarguil X-Patchwork-Id: 44072 X-Patchwork-Delegate: ferruh.yigit@amd.com Return-Path: X-Original-To: patchwork@dpdk.org Delivered-To: patchwork@dpdk.org Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id 052A64CAB; Fri, 31 Aug 2018 11:01:44 +0200 (CEST) Received: from mail-wr1-f68.google.com (mail-wr1-f68.google.com [209.85.221.68]) by dpdk.org (Postfix) with ESMTP id F1A2F4CC3 for ; Fri, 31 Aug 2018 11:01:27 +0200 (CEST) Received: by mail-wr1-f68.google.com with SMTP id v16-v6so10493969wro.11 for ; Fri, 31 Aug 2018 02:01:27 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=6wind-com.20150623.gappssmtp.com; s=20150623; h=date:from:to:cc:subject:message-id:references:mime-version :content-disposition:in-reply-to; bh=YR0XOxi3xkElhTJG6YAqZX+uxOzEhP+5zkrZ5Gc67Oc=; b=OaY0CO6s1xrGp6RteyiU2VbUVxk0URLWlu3Hsxdx9zIF19rIS8iZtJRR4FnctYLyQF AbFyK+zy/y2c4p+x7KTMyWMNyzLuy+bh5e+YJKamT+iWpi36FooxIhpioxNW50mtjMNZ wZ1xcL8LxqVDed/Pm7NcINS1c9dJifXQdJkz4H+OklpID4Rk1NAFiiLfMozSRgLifkFd AludEtuPPUm1Q4SOffrLc4wiKdwkLywwmDz3cwip03E7dKHLwCkZDjltt3174Cjylwlh Dq45MkhbwcHLrKjIRUuIRcT1CiuCH8hPruxpt/1KpmVGiiODUCfuyeHm4IdrwG3Yolzq uTrw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:from:to:cc:subject:message-id:references :mime-version:content-disposition:in-reply-to; bh=YR0XOxi3xkElhTJG6YAqZX+uxOzEhP+5zkrZ5Gc67Oc=; b=hs8/EyYqgVeu/spg5Ird5p3sqXHD7LU75MKimtGPGILoUff2OAO3IJgbdH5iQcG0rx rUwyzZUORvUF26sm2DmbF6RHp2fNoi/aXWo6xj/UU2MPsz5g9cpivVW1ZaTdB9aQJCA5 gYtCv8NeEToFCPVm6uGCX92oH6SGiKidSwyMU3eVXz1upiYcik3yLppvgcf1rNXGU3ZO TodJowdNlp6iMbDw3SA0FMCkJLDlLXNrDr4mCsYDMe1nmMFYGvr83QJkgqZ/h/py4QIB jy3eGeNuSANNMYubEmA+rhvNPLgQEnpYgDL00FISDB66rNWG6HXmOuCpY+R7GzgOu54r Satw== X-Gm-Message-State: APzg51CDnr2vUV2NPTKEA+3e7yKYZDoo18tS2xmIi9EzWkUBEXYNig8q qbllA1I9NlavKrlkSQ+lVim/SA== X-Google-Smtp-Source: ANB0VdbX4EUqLWeUKEgA54CUfLIjwec3noL1TyyFKndvPAEomLUX8eTA+Z+tgHv3mjrmQhF6L1xafw== X-Received: by 2002:adf:c890:: with SMTP id k16-v6mr10442169wrh.6.1535706087753; Fri, 31 Aug 2018 02:01:27 -0700 (PDT) Received: from 6wind.com (host.78.145.23.62.rev.coltfrance.com. [62.23.145.78]) by smtp.gmail.com with ESMTPSA id d18-v6sm3268542wmb.33.2018.08.31.02.01.26 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 31 Aug 2018 02:01:27 -0700 (PDT) Date: Fri, 31 Aug 2018 11:01:11 +0200 From: Adrien Mazarguil To: Ferruh Yigit Cc: dev@dpdk.org, Declan Doherty , Nelio Laranjeiro Message-ID: <20180831085337.21419-7-adrien.mazarguil@6wind.com> References: <20180803132032.29038-1-adrien.mazarguil@6wind.com> <20180831085337.21419-1-adrien.mazarguil@6wind.com> MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: <20180831085337.21419-1-adrien.mazarguil@6wind.com> X-Mailer: git-send-email 2.11.0 Subject: [dpdk-dev] [PATCH v3 6/7] ethdev: add missing items/actions to flow object converter X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" Several pattern items and actions were never handled by rte_flow_copy() because their descriptions were missing. rte_flow_conv() inherited this deficiency. This patch adds them and reorders others to match rte_flow.h. It doesn't pose as a fix because so far no one has complained about it and rte_flow_conv() would have to be backported as well: this function is the only sane approach to handle VXLAN and NVGRE encap definitions. As a matter of fact, it's the last missing piece to finally allow testpmd users to request the creation of VXLAN/NVGRE encap/decap flow rules without getting rejected outright. Signed-off-by: Adrien Mazarguil Cc: Declan Doherty Cc: Nelio Laranjeiro --- v2 changes: - Patch was not present in original series. --- lib/librte_ethdev/rte_flow.c | 50 +++++++++++++++++++++++++++++++++++++-- 1 file changed, 48 insertions(+), 2 deletions(-) diff --git a/lib/librte_ethdev/rte_flow.c b/lib/librte_ethdev/rte_flow.c index c3ff7e713..9c56a9734 100644 --- a/lib/librte_ethdev/rte_flow.c +++ b/lib/librte_ethdev/rte_flow.c @@ -51,10 +51,15 @@ static const struct rte_flow_desc_data rte_flow_desc_item[] = { MK_FLOW_ITEM(TCP, sizeof(struct rte_flow_item_tcp)), MK_FLOW_ITEM(SCTP, sizeof(struct rte_flow_item_sctp)), MK_FLOW_ITEM(VXLAN, sizeof(struct rte_flow_item_vxlan)), - MK_FLOW_ITEM(MPLS, sizeof(struct rte_flow_item_mpls)), - MK_FLOW_ITEM(GRE, sizeof(struct rte_flow_item_gre)), MK_FLOW_ITEM(E_TAG, sizeof(struct rte_flow_item_e_tag)), MK_FLOW_ITEM(NVGRE, sizeof(struct rte_flow_item_nvgre)), + MK_FLOW_ITEM(MPLS, sizeof(struct rte_flow_item_mpls)), + MK_FLOW_ITEM(GRE, sizeof(struct rte_flow_item_gre)), + MK_FLOW_ITEM(FUZZY, sizeof(struct rte_flow_item_fuzzy)), + MK_FLOW_ITEM(GTP, sizeof(struct rte_flow_item_gtp)), + MK_FLOW_ITEM(GTPC, sizeof(struct rte_flow_item_gtp)), + MK_FLOW_ITEM(GTPU, sizeof(struct rte_flow_item_gtp)), + MK_FLOW_ITEM(ESP, sizeof(struct rte_flow_item_esp)), MK_FLOW_ITEM(GENEVE, sizeof(struct rte_flow_item_geneve)), MK_FLOW_ITEM(VXLAN_GPE, sizeof(struct rte_flow_item_vxlan_gpe)), MK_FLOW_ITEM(ARP_ETH_IPV4, sizeof(struct rte_flow_item_arp_eth_ipv4)), @@ -67,6 +72,7 @@ static const struct rte_flow_desc_data rte_flow_desc_item[] = { sizeof(struct rte_flow_item_icmp6_nd_opt_sla_eth)), MK_FLOW_ITEM(ICMP6_ND_OPT_TLA_ETH, sizeof(struct rte_flow_item_icmp6_nd_opt_tla_eth)), + MK_FLOW_ITEM(MARK, sizeof(struct rte_flow_item_mark)), }; /** Generate flow_action[] entry. */ @@ -81,6 +87,7 @@ static const struct rte_flow_desc_data rte_flow_desc_action[] = { MK_FLOW_ACTION(END, 0), MK_FLOW_ACTION(VOID, 0), MK_FLOW_ACTION(PASSTHRU, 0), + MK_FLOW_ACTION(JUMP, sizeof(struct rte_flow_action_jump)), MK_FLOW_ACTION(MARK, sizeof(struct rte_flow_action_mark)), MK_FLOW_ACTION(FLAG, 0), MK_FLOW_ACTION(QUEUE, sizeof(struct rte_flow_action_queue)), @@ -91,6 +98,8 @@ static const struct rte_flow_desc_data rte_flow_desc_action[] = { MK_FLOW_ACTION(VF, sizeof(struct rte_flow_action_vf)), MK_FLOW_ACTION(PHY_PORT, sizeof(struct rte_flow_action_phy_port)), MK_FLOW_ACTION(PORT_ID, sizeof(struct rte_flow_action_port_id)), + MK_FLOW_ACTION(METER, sizeof(struct rte_flow_action_meter)), + MK_FLOW_ACTION(SECURITY, sizeof(struct rte_flow_action_security)), MK_FLOW_ACTION(OF_SET_MPLS_TTL, sizeof(struct rte_flow_action_of_set_mpls_ttl)), MK_FLOW_ACTION(OF_DEC_MPLS_TTL, 0), @@ -110,6 +119,10 @@ static const struct rte_flow_desc_data rte_flow_desc_action[] = { sizeof(struct rte_flow_action_of_pop_mpls)), MK_FLOW_ACTION(OF_PUSH_MPLS, sizeof(struct rte_flow_action_of_push_mpls)), + MK_FLOW_ACTION(VXLAN_ENCAP, sizeof(struct rte_flow_action_vxlan_encap)), + MK_FLOW_ACTION(VXLAN_DECAP, 0), + MK_FLOW_ACTION(NVGRE_ENCAP, sizeof(struct rte_flow_action_vxlan_encap)), + MK_FLOW_ACTION(NVGRE_DECAP, 0), }; static int @@ -407,11 +420,16 @@ rte_flow_conv_action_conf(void *buf, const size_t size, switch (action->type) { union { const struct rte_flow_action_rss *rss; + const struct rte_flow_action_vxlan_encap *vxlan_encap; + const struct rte_flow_action_nvgre_encap *nvgre_encap; } src; union { struct rte_flow_action_rss *rss; + struct rte_flow_action_vxlan_encap *vxlan_encap; + struct rte_flow_action_nvgre_encap *nvgre_encap; } dst; size_t tmp; + int ret; case RTE_FLOW_ACTION_TYPE_RSS: src.rss = action->conf; @@ -445,6 +463,34 @@ rte_flow_conv_action_conf(void *buf, const size_t size, off += tmp; } break; + case RTE_FLOW_ACTION_TYPE_VXLAN_ENCAP: + case RTE_FLOW_ACTION_TYPE_NVGRE_ENCAP: + src.vxlan_encap = action->conf; + dst.vxlan_encap = buf; + RTE_BUILD_BUG_ON(sizeof(*src.vxlan_encap) != + sizeof(*src.nvgre_encap) || + offsetof(struct rte_flow_action_vxlan_encap, + definition) != + offsetof(struct rte_flow_action_nvgre_encap, + definition)); + off = sizeof(*dst.vxlan_encap); + if (src.vxlan_encap->definition) { + off = RTE_ALIGN_CEIL + (off, sizeof(*dst.vxlan_encap->definition)); + ret = rte_flow_conv + (RTE_FLOW_CONV_OP_PATTERN, + (void *)((uintptr_t)dst.vxlan_encap + off), + size > off ? size - off : 0, + src.vxlan_encap->definition, NULL); + if (ret < 0) + return 0; + if (size >= off + ret) + dst.vxlan_encap->definition = + (void *)((uintptr_t)dst.vxlan_encap + + off); + off += ret; + } + break; default: off = rte_flow_desc_action[action->type].size; rte_memcpy(buf, action->conf, (size > off ? off : size)); From patchwork Fri Aug 31 09:01:13 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Adrien Mazarguil X-Patchwork-Id: 44074 X-Patchwork-Delegate: ferruh.yigit@amd.com Return-Path: X-Original-To: patchwork@dpdk.org Delivered-To: patchwork@dpdk.org Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id 8696A56A3; Fri, 31 Aug 2018 11:01:47 +0200 (CEST) Received: from mail-wm0-f53.google.com (mail-wm0-f53.google.com [74.125.82.53]) by dpdk.org (Postfix) with ESMTP id 730994F91 for ; Fri, 31 Aug 2018 11:01:30 +0200 (CEST) Received: by mail-wm0-f53.google.com with SMTP id y2-v6so4483493wma.1 for ; Fri, 31 Aug 2018 02:01:30 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=6wind-com.20150623.gappssmtp.com; s=20150623; h=date:from:to:cc:subject:message-id:references:mime-version :content-disposition:in-reply-to; bh=IzPbNQ/8NnpkShHPveVJrOxLQ4CzraLvD61cufN3nAo=; b=hBuyLcZjXlPLvwFv0njmJSttlO3fGNbfL44UCo8IClmg3LEsT69WJXFzB9RV65Nltz FcL6FfosVF0gJ0oAXKxOI8L4tmDFRgDsOjKSHLUYXq9Qaf1t+VV1UOgnW+TT6P3Qdv01 MKQVnuIGpoMXesdlLPcuxs7lY1m7G/Dxh0ug35kV4OhnEWSV9fmyrupC5rMvEgOkIfLy z22oU8YbTu+WfABA+j7Dw8xhxi1ruUHjkPuLpDLg5f+RbhXCjbXW6f1byOmGohvfmBCK o7S+bpwujQIeGB37Y/3AAlOdaskDUSR68V0TC1Mre+0cmxohrCz1+VnxCamrLbv999bK 6V1w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:from:to:cc:subject:message-id:references :mime-version:content-disposition:in-reply-to; bh=IzPbNQ/8NnpkShHPveVJrOxLQ4CzraLvD61cufN3nAo=; b=Z4H0yt4/pGnsVUoZi/DAO7zfHR3a4fd0xJBwQ0hUKCNZvdB4HJgoKi3b3x4UOuju2e 2URk82uvf60EqGdR+6k4XDaRQrhrEs0zn6Ivot3d+ANFXfG/55g0t1PHXXqpsf/Bgs+C JvmTPYn4D4QL07li+CbvJ/Lf7b/PjfiNyauMkIhrEhAQf1JKNvF3bl/jN1AFksT9GELn KMQH2mDZ7nMIa072Rn6YfYQdhgn/jV7bomjHqPLCgV0yvga+59TZ9NN9AhHn7jymHPZ+ Nzg+BkOghhlHOYwUDCfn+tLAjc4MEc4ySmAjSnCAuT/yBN621S1NjF2LZEUGavff5qe4 gkLQ== X-Gm-Message-State: APzg51Cim3xh0Q1/2qOcEsVLkYh54EFNrXujQWJE8ZuHwXf6HJhVM6ow DAhYGUXtRorhQEdv8fhwctKJEA== X-Google-Smtp-Source: ANB0VdaKWdRCEB1IVmg6RfJUAMA40AM+Mw8Dh2Xd/2JDpA+MKtTq2r4g/jEC6Vp0g0ZxX3Sn6p+7kw== X-Received: by 2002:a1c:a94d:: with SMTP id s74-v6mr4334212wme.39.1535706090172; Fri, 31 Aug 2018 02:01:30 -0700 (PDT) Received: from 6wind.com (host.78.145.23.62.rev.coltfrance.com. [62.23.145.78]) by smtp.gmail.com with ESMTPSA id d10-v6sm14039839wrv.70.2018.08.31.02.01.28 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 31 Aug 2018 02:01:29 -0700 (PDT) Date: Fri, 31 Aug 2018 11:01:13 +0200 From: Adrien Mazarguil To: Ferruh Yigit Cc: dev@dpdk.org, Thomas Monjalon , Andrew Rybchenko , Gaetan Rivet Message-ID: <20180831085337.21419-8-adrien.mazarguil@6wind.com> References: <20180803132032.29038-1-adrien.mazarguil@6wind.com> <20180831085337.21419-1-adrien.mazarguil@6wind.com> MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: <20180831085337.21419-1-adrien.mazarguil@6wind.com> X-Mailer: git-send-email 2.11.0 Subject: [dpdk-dev] [PATCH v3 7/7] ethdev: deprecate rte_flow_copy function X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" No users left for this function, time to deprecate it. Signed-off-by: Adrien Mazarguil Cc: Thomas Monjalon Cc: Ferruh Yigit Cc: Andrew Rybchenko Cc: Gaetan Rivet --- v3 changes: - Removed deprecation notice (finally got Ferruh's point), made patch last in series. v2 changes: - Patch was not present in original series. --- doc/guides/rel_notes/deprecation.rst | 7 ------- lib/librte_ethdev/rte_flow.h | 7 ++++++- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/doc/guides/rel_notes/deprecation.rst b/doc/guides/rel_notes/deprecation.rst index e2dbee317..48cfb266b 100644 --- a/doc/guides/rel_notes/deprecation.rst +++ b/doc/guides/rel_notes/deprecation.rst @@ -88,10 +88,3 @@ Deprecation Notices - ``rte_pdump_set_socket_dir`` will be removed; - The parameter, ``path``, of ``rte_pdump_init`` will be removed; - The enum ``rte_pdump_socktype`` will be removed. - -* ethdev: flow API function ``rte_flow_copy()`` will be deprecated in v18.11 - in favor of ``rte_flow_conv()`` (which will appear in that version) and - subsequently removed for v19.02. - - This is due to a lack of flexibility and reliance on a type unusable with - C++ programs (struct rte_flow_desc). diff --git a/lib/librte_ethdev/rte_flow.h b/lib/librte_ethdev/rte_flow.h index 052ceefb6..f062ffead 100644 --- a/lib/librte_ethdev/rte_flow.h +++ b/lib/librte_ethdev/rte_flow.h @@ -2332,6 +2332,7 @@ rte_flow_error_set(struct rte_flow_error *error, const char *message); /** + * @deprecated * @see rte_flow_copy() */ struct rte_flow_desc { @@ -2343,10 +2344,13 @@ struct rte_flow_desc { }; /** + * @deprecated * Copy an rte_flow rule description. * * This interface is kept for compatibility with older applications but is - * implemented as a wrapper to rte_flow_conv(). + * implemented as a wrapper to rte_flow_conv(). It is deprecated due to its + * lack of flexibility and reliance on a type unusable with C++ programs + * (struct rte_flow_desc). * * @param[in] fd * Flow rule description. @@ -2365,6 +2369,7 @@ struct rte_flow_desc { * If len is lower than the size of the flow, the number of bytes that would * have been written to desc had it been sufficient. Nothing is written. */ +__rte_deprecated size_t rte_flow_copy(struct rte_flow_desc *fd, size_t len, const struct rte_flow_attr *attr,