From patchwork Fri Aug 3 13:36:32 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Adrien Mazarguil X-Patchwork-Id: 43562 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 5BE221B575; Fri, 3 Aug 2018 15:36:52 +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 9A8CE1B567 for ; Fri, 3 Aug 2018 15:36:50 +0200 (CEST) Received: by mail-wr1-f68.google.com with SMTP id g1-v6so1965838wru.2 for ; Fri, 03 Aug 2018 06:36:50 -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=Dfm+moNvBfj4tDgOJFK+3fnkWF2GhJT71NWE1n21khQ=; b=KkWGk03AaGw8CCsx2zwkfX9k/wh5MkvIvi6XvzGwCo3MN+jWw/y8YPB+RZ1oRMk2lC Xn//9TBjFVLXHHGUScftKPCUb+varymiMk5BKskJHoXYsRJSO+2NXO+6mRPeWP4hxIgH 7tYtvkRdWTdLIVBjA0Mgy+F2y79glvjI0ICTdpkfNRZeRwkx597zvUKJeUqcIS3pLpgl axoBbhCBfbzSnChkbM6TERAZU/fPmaw53Rt5NEctD+ACp7BGoiHCPWAGgNOyLyS9Zv6l OJhtipGYVb5o2FreBWGHPpJYcAwFHkdARY2/6XvBvDMzMUJeNz8jpzvxBcaYFf5Qf0Z/ RVFQ== 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=Dfm+moNvBfj4tDgOJFK+3fnkWF2GhJT71NWE1n21khQ=; b=sj1oiP8IoxWsS9oG7xkLfbmd2/86vEZBgLbaj69d8HctJpQ7opuQVvKj3GMi3WPZlc DhMBgtI9yFN2Z4F0hrXV3/jgD8yL++9a3byaFKgSPRbhkq8YaA+N03kWzMOibpjIgcbt OOAuceFes/G9bFGHngm2aOxqrf2/S3JdtBaXAO2IKyoG7ArLYNFuNfemPA/CsV/T4BT6 kWh1OlTK4WEV5/wx2ygo2gPKHfzeASJR/e+pzJaOpx6eoqOQi0HfsjZYjV72c8+R1yK5 ITk36yjTs/064SkFBQXp68fSdWhy+hpBC7tlZOqb44FhAM98wuQbdMOf5rJHaP4tuV+j Y/eA== X-Gm-Message-State: AOUpUlF40n3G4Dg1JmEfrr5ehrAloUl780Wv7nK/l/iTUca679Qp3lZ1 rlWFbFAgLQ8aRDquh/PkIQxrJQ== X-Google-Smtp-Source: AAOMgpdGGgmpLEv6lWy0zDfgVQtqR+22dBJ5hjM26FRCVeWmZ+s3lThudr+HfEcnWAji2DyBVl+CjA== X-Received: by 2002:adf:9d46:: with SMTP id o6-v6mr2601225wre.51.1533303410285; Fri, 03 Aug 2018 06:36:50 -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 q1-v6sm3987123wrw.42.2018.08.03.06.36.49 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 03 Aug 2018 06:36:49 -0700 (PDT) Date: Fri, 3 Aug 2018 15:36:32 +0200 From: Adrien Mazarguil To: Ferruh Yigit Cc: dev@dpdk.org, Thomas Monjalon , Andrew Rybchenko , Gaetan Rivet Message-ID: <20180803132032.29038-2-adrien.mazarguil@6wind.com> References: <20180803132032.29038-1-adrien.mazarguil@6wind.com> MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: <20180803132032.29038-1-adrien.mazarguil@6wind.com> X-Mailer: git-send-email 2.11.0 Subject: [dpdk-dev] [PATCH v2 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 --- 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 | 169 +++++++- 4 files changed, 581 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..2345f3002 100644 --- a/lib/librte_ethdev/rte_ethdev_version.map +++ b/lib/librte_ethdev/rte_ethdev_version.map @@ -217,6 +217,7 @@ DPDK_18.08 { global: rte_eth_dev_logtype; + rte_flow_conv; } DPDK_18.05; diff --git a/lib/librte_ethdev/rte_flow.c b/lib/librte_ethdev/rte_flow.c index cff4b5209..930fe09c8 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..71dc30e4c 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,53 @@ 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 + */ +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 3 13:36:34 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Adrien Mazarguil X-Patchwork-Id: 43563 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 1B4FD1B584; Fri, 3 Aug 2018 15:36:55 +0200 (CEST) Received: from mail-wr1-f51.google.com (mail-wr1-f51.google.com [209.85.221.51]) by dpdk.org (Postfix) with ESMTP id CBB2B1B57A for ; Fri, 3 Aug 2018 15:36:52 +0200 (CEST) Received: by mail-wr1-f51.google.com with SMTP id e7-v6so5433979wrs.9 for ; Fri, 03 Aug 2018 06:36:52 -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=S6rV3tMI0FLqVOqherKocL4VRIZ/qnW7GgipmNuodTE=; b=GtLaQAve8Xr1UgTV/40+kim9hF/sh9Qbn16EqHBTQdQQmFfoJKJvUSMfi4ifLY7+Nw uTpUXf7FfXWwijDBYLQ4PQhktF9qOb4e65Ae9tLwwqQ7vcB7Tbjs8uQAahQtiDTs5Lbq VBWaZsWxmk9GZXy3iuWvreDd6RruGYNI/pQZHg1wskiOO+7RKHujhhrpXt2tVlNtvnnA JJ3mnZNoNpXgGosAncVQX0ZowcN/Gp6wcWNMUmGtI6T3K7XA/0IWd1x4UB+m2TLEKP7k nfl/LWZdJ7SgdI9pb/cTDTAJY5LfRsWaGAuESWD0eqi2g597IgdOVbq3RC9BvpgsvMyd YpRA== 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=S6rV3tMI0FLqVOqherKocL4VRIZ/qnW7GgipmNuodTE=; b=YsEOxy/+8PRC81hS6u2iEUMG+QCuecBgSpEHf/5Dz9PTI7z2hdKcVDBXx4i5HCMcaW oixACh8f8OweyoE8U+XaGmX9DPFrYlJ6jvSjj0fplKUWCKFgb3bpdsL8M8l9mtXMA6GI id5XTTa9v5GSwRj4UaPmCOs8sy49ntJoz3O+YCkV5i7ahkFsuS/EEQ9uktTgW/9WCYlw Y7XRq5dIxjjnSzYa+6veOy2vrdYNoal8PTKu/nZiwXhjcMk3bI+w4b8hDogTtTMSH55S Q0T/WU6O/WYVVhGcFGkXN2d+S9mbkvpc43ykISfCRmWkCLrdpsRn6G3KFkM2zv5jGWAU 7wrQ== X-Gm-Message-State: AOUpUlGnfNfIj3uPciBGPO9AkNMrJRv0GgnI7TvpUG3sRUmKMIvG4AbW VVVcKtLHmiyEueKmx4QN0L8KXA== X-Google-Smtp-Source: AAOMgpe7UztSRRVYxXprJx5/hoV+rA9c5vw3NuNLeOHjcMvP5WsgwR35uVZYhn6EaGTphFF0p40yqQ== X-Received: by 2002:adf:e190:: with SMTP id k16-v6mr2690423wri.36.1533303412465; Fri, 03 Aug 2018 06:36:52 -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 o14-v6sm7342079wmd.35.2018.08.03.06.36.51 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 03 Aug 2018 06:36:51 -0700 (PDT) Date: Fri, 3 Aug 2018 15:36:34 +0200 From: Adrien Mazarguil To: Ferruh Yigit Cc: dev@dpdk.org, Thomas Monjalon , Andrew Rybchenko Message-ID: <20180803132032.29038-3-adrien.mazarguil@6wind.com> References: <20180803132032.29038-1-adrien.mazarguil@6wind.com> MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: <20180803132032.29038-1-adrien.mazarguil@6wind.com> X-Mailer: git-send-email 2.11.0 Subject: [dpdk-dev] [PATCH v2 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 930fe09c8..5d487c108 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 71dc30e4c..c48ea8a51 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 3 13:36:37 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Adrien Mazarguil X-Patchwork-Id: 43564 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 83F171B590; Fri, 3 Aug 2018 15:36:56 +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 E36BB1B582 for ; Fri, 3 Aug 2018 15:36:54 +0200 (CEST) Received: by mail-wr1-f68.google.com with SMTP id f12-v6so5425034wrv.12 for ; Fri, 03 Aug 2018 06:36:54 -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=NcrSZjtmAMca6mIiC/Q9wseH7QivaKdJc3dSa8aHWiR/hkPBvNm5TF3Z4R2bU6xLGr MnaQXQIAZW2oxnt5cC+HwT6VuqU9ey8qi0UAEPVj0Wvgtq+YpsxkOO+ta3HfZ4vLkzrx GcGZQd4TvRTZQkO2kc9GEfZjM7MZ7G2HsP9gJ/P14rBIIYcGt3KvCukyThbum+GiPJ4r 0null5Fy5wDd72S+MS7hz/5xVTZwpNcz5ba5Ka/tcHZEINQ6eQ725PIDzyeVhvP4Eo7c CQdbCVnMIGrRDAJqysbF92mk8HLTeIa+tFoN8QoxSFPDedjsaCwZcqrKD7Q6Rwd4zY2j ectA== 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=qFcd7+tUugh4UO31n8RL+svYmbe7UrPDUHMK5t7sow10FxZXbi1KI8cAR42atZ2+KQ bvCt9gGoG+9Lfo+IPh9eYFl55RsKUyEqfBD2Bm3X3A+MnjMgxssYxisypretEpzJltCa pOKW18uPG3lyh6+0uKeCazdJkse9evA5oVxJH9dQxBHQAjyaY840lhvVexmFP+cPo8Op MyB5VNBmywgX3GBldDdWwTI0bfj92rTg2vxzOBJQ3L6pmsXetUQ15fxTIRqodog6AZib p9KJi5JxTHQCTNdaUvfhrZiQyBIb1uQsy5eVzvTLSEXXdMG07ICwyuK4/pKL0sQ3jOS8 C32A== X-Gm-Message-State: AOUpUlFpz91uUwuMQohj1xllkN3HEeQF8bgCU48uV2eCnlzzkXlVudhF EsrM6JhEY6bnIzSCZiMy+gJr/Q== X-Google-Smtp-Source: AAOMgpfdvU2uHMS2JT6JsUP/X9DwNVfvVqxA3HSoPUPf+rq7SO00R1LxP+GvM1CM0+zsSGIxjr0yGg== X-Received: by 2002:adf:f790:: with SMTP id q16-v6mr2599913wrp.86.1533303414657; Fri, 03 Aug 2018 06:36:54 -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 s2-v6sm2175249wrw.52.2018.08.03.06.36.53 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 03 Aug 2018 06:36:53 -0700 (PDT) Date: Fri, 3 Aug 2018 15:36:37 +0200 From: Adrien Mazarguil To: Ferruh Yigit Cc: dev@dpdk.org, Wenzhuo Lu , Jingjing Wu , Bernard Iremonger Message-ID: <20180803132032.29038-4-adrien.mazarguil@6wind.com> References: <20180803132032.29038-1-adrien.mazarguil@6wind.com> MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: <20180803132032.29038-1-adrien.mazarguil@6wind.com> X-Mailer: git-send-email 2.11.0 Subject: [dpdk-dev] [PATCH v2 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 3 13:36:39 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Adrien Mazarguil X-Patchwork-Id: 43565 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 19AAF1B594; Fri, 3 Aug 2018 15:36:59 +0200 (CEST) Received: from mail-wr1-f42.google.com (mail-wr1-f42.google.com [209.85.221.42]) by dpdk.org (Postfix) with ESMTP id 02CFC1B567 for ; Fri, 3 Aug 2018 15:36:56 +0200 (CEST) Received: by mail-wr1-f42.google.com with SMTP id h9-v6so5462923wro.3 for ; Fri, 03 Aug 2018 06:36:56 -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=bPs4IzjkymuhHnKuZ9/vpMtxvs7xhiXQWEx7G9sCdR9Q8gWcXn+GdB953D+Q4mu2fz MM6P1Ss0gl09XQQzhHc4IV+7xNn3rX4/NAhuUklWsChKXI6/RoM3fa/E5vkCgPGfYwgo 6ibGwYMwQSAbYK9KuR5v3UBpuEsK1fy9V3LVPNXUWAtgccce0+sumcdE7LAvYIsdYZTk 9Qp1Dy82B5cASf0eqtogjtxvJNlFwaTsAy8S0tOj8zdLbP6Zbayt8IOfPbmFZxUFccQv +VxpMT40fNc7ssGJubvcc/Hek98bA29dB8HWGBVHzcpm868HSa/0UoEkLw5YCVXAhBmT Tzpg== 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=VzTmtEL95dMoaJXkUjqSmA2t648lKaM22AmcPSxb/+g7n0bzYJ/EKkfLmjJNu3cfsZ XT+/UkdR+PzdsafZ2FsjC3J6TSqdYdnXNVIrybE1SgI4IWiakefM4T9wUFyI2NluiLxt x3Vc2aiH0H5cvDB+JNkdX9KNlG53R138ZJDLC5B0N0Wk7WNdpl+gbHhKmyBsjrYTWfXt oqOZ4crcp2w/sQpIKi9e4dWw+KK0thfFPtiBtHv3Apfqj5dQRzKIy/YmZkKaZRoR3dfH 9SaZQViKPa/Z7uNceRwoohk7e/Nk2B1ge2nqwpMAuWlDHWcAwXUGIEA2aNLG5lszsFol 3JZA== X-Gm-Message-State: AOUpUlF3NRSBTv0bxbc6PZJ+SkqxYdeV5nAuysK7ojMKSIfAMVeUUrfu IMVA6nDfcbs0Bt65jrvyWuxNqg== X-Google-Smtp-Source: AAOMgpdJenSYkeZVJwlxbOd4Qf40Skj4OwB/Hm7NuNQS6QhxyoBfAZQda/FYcfq2CCfwWUY45CG2NA== X-Received: by 2002:adf:9e84:: with SMTP id a4-v6mr2598435wrf.70.1533303416798; Fri, 03 Aug 2018 06:36:56 -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 b202-v6sm7294864wme.22.2018.08.03.06.36.55 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 03 Aug 2018 06:36:56 -0700 (PDT) Date: Fri, 3 Aug 2018 15:36:39 +0200 From: Adrien Mazarguil To: Ferruh Yigit Cc: dev@dpdk.org, Gaetan Rivet Message-ID: <20180803132032.29038-5-adrien.mazarguil@6wind.com> References: <20180803132032.29038-1-adrien.mazarguil@6wind.com> MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: <20180803132032.29038-1-adrien.mazarguil@6wind.com> X-Mailer: git-send-email 2.11.0 Subject: [dpdk-dev] [PATCH v2 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 3 13:36:41 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Adrien Mazarguil X-Patchwork-Id: 43566 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 3CF541B59E; Fri, 3 Aug 2018 15:37:01 +0200 (CEST) Received: from mail-wr1-f65.google.com (mail-wr1-f65.google.com [209.85.221.65]) by dpdk.org (Postfix) with ESMTP id 1CF211B595 for ; Fri, 3 Aug 2018 15:36:59 +0200 (CEST) Received: by mail-wr1-f65.google.com with SMTP id f12-v6so5425254wrv.12 for ; Fri, 03 Aug 2018 06:36:59 -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=rZTlv8/S5UVprjogu8YheU4Mt0j+9W4zrSgtK/ZgQJ4=; b=VdfTzKWqOvegdzjA8Plouc89c6WLqC8jzMyh/7aZyQND4EestRR7nPkKaAQ/5uhT85 393tnox7baKhTOQbOpQVYk6z5vEhvWWPsF3m0ADu8prSvG3mMqQ2TvUXt4UONz3GOOYu mfFkU/Lp4VLU9AdWM4GBoKvKNiO3/fJ0oHr8PxfdScTKRPEYlublowKRXvFebO5qr8Rz AjnbHBnhXL9gbfd7QBPcDB1sjQQ0piZJkArUloIiOZ1c7YMf9Dy1vNPLXVmgcK5dNZSb wSn0kM12s9vF2q9kmQpjRTXBnO0uvtL7CSLv7bOydAgGTjuK2pRbM0Bn4rvdpxzFrmBC d0AA== 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=rZTlv8/S5UVprjogu8YheU4Mt0j+9W4zrSgtK/ZgQJ4=; b=FZO/dde0ewOW+oAvgAzWk+5LCrSPbL6mxScEHaMIZOkl3Gt/AyCejhby9smbSa4gn2 qiBzVh9S/CdiRcnSRNtRsUlyyL7G3nMAwKAjZYE2Py/3bVOM2y0hOTcczYoiJ65wn2qT 9ETGFjfi37b1Aqr4mS7476ulDoxhcdCO58pZDVGSdAZaZZFix+d9HUGM01Ju8x7IXCJs c+Gprbk/4CuCgfHrxCCURIYvQt5LGQLLznF6G/qDaIZ2RXM9Vvbj6BDH5dg1rUdeuniM 8pdRvePot7ZAgaqMtfN9yc2hkjtRNsdOpy35KmOAjQ2/qzl83TLcNQXL9mX8GwKwfRBJ SVjQ== X-Gm-Message-State: AOUpUlH7i1wnxLSp4O4xYGGo6Khfm9rTRkg35on3BPVi4oCnrXRAKlhD aGVgVpi7peb2/BedJSFFL4Vzc+6DkRk36A== X-Google-Smtp-Source: AAOMgpfiBt6hYcuiT6hhovL7bxuEdNkL0OLEV+6GqllNcvKulR/9zrOLm1HwvyDT5xW4tIDkQnGYHA== X-Received: by 2002:adf:b202:: with SMTP id u2-v6mr2607273wra.19.1533303418845; Fri, 03 Aug 2018 06:36:58 -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 i1-v6sm3603956wrq.69.2018.08.03.06.36.57 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 03 Aug 2018 06:36:58 -0700 (PDT) Date: Fri, 3 Aug 2018 15:36:41 +0200 From: Adrien Mazarguil To: Ferruh Yigit Cc: dev@dpdk.org, Declan Doherty , Chas Williams Message-ID: <20180803132032.29038-6-adrien.mazarguil@6wind.com> References: <20180803132032.29038-1-adrien.mazarguil@6wind.com> MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: <20180803132032.29038-1-adrien.mazarguil@6wind.com> X-Mailer: git-send-email 2.11.0 Subject: [dpdk-dev] [PATCH v2 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 --- v2 changes: - Patch was not present in original series. --- 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 +++- 3 files changed, 31 insertions(+), 11 deletions(-) diff --git a/drivers/net/bonding/rte_eth_bond_api.c b/drivers/net/bonding/rte_eth_bond_api.c index 49fa2d78d..045c907cf 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 3 13:36:43 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Adrien Mazarguil X-Patchwork-Id: 43567 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 1DC5B1B5A5; Fri, 3 Aug 2018 15:37:03 +0200 (CEST) Received: from mail-wr1-f65.google.com (mail-wr1-f65.google.com [209.85.221.65]) by dpdk.org (Postfix) with ESMTP id 1CFE51B59B for ; Fri, 3 Aug 2018 15:37:01 +0200 (CEST) Received: by mail-wr1-f65.google.com with SMTP id j5-v6so5439422wrr.8 for ; Fri, 03 Aug 2018 06:37:01 -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=FoxA7ECL9wOPjGs1GFaZZM4lZSj7ftFVgATNr2cWHgo=; b=ptBqk+h1KlGxutcyrySvjmgVoXCKkuFrSLg/9EJdVJpyK9JMyXl7Ye9qiJRZGrQtwo vinI2tpJRbZyC9mHXdK1m86SLYwTAJboyh7+HXXcqERP4kzEeHl2ti9ic4pVgLbKtpxP orekvybN4Kk34cxjIzXR49+cRQcDtG8OihL9UCLiHB3utGor0ZpAIuozO3EKCX26zGmA 42tCcrUrn9UurEucf400F8cgdae2HSGNK6CyYrcQKCbvifddSA/WmE5sWS+9FugjOoC+ gkCCGEIln3ubblX5KpeqocIHA5pYMaBzRuDxBMgDSSL4pDYQ6HjJFhJnn2vvIWMd769i nk0w== 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=FoxA7ECL9wOPjGs1GFaZZM4lZSj7ftFVgATNr2cWHgo=; b=s/5/XNPHtE8tkbs2qm4wTSwIhZf7OLn8zsuu/xIlK4gUOUBsN79dNskyMPs706qa57 3fFdqWZruy+Bmcbv6BhJ8mcqpx8O6H5dnml3Ic8cb6eKIbnCVBndWuOTUQMzXqe+mWpG ha13TNfRkiSiIanS299BafMfmGNDgRrnVHHhatl7jnWYMMvlfzBaHRszWmLgvGaCAeM5 Ui310Ux5Ssh4cLZJ4ft5zj+0lhJPC1wG62j7JRwoX2Gq7B6SM/2fzJbhFHFEWahLZcU/ bp5J/In/umIblc3s9HiFdbH2tXnYiWik/Y6n3DRTf8mbMJoGbIuzp/lnW8Zh4ejuW47h yYCw== X-Gm-Message-State: AOUpUlFqeaJ9xC2nt0CWE28Soli8fYAUiU308FBWBb6i17/siEaT0nC3 SfWsHTsd0gr+BGi4ceAaTxm0QQ== X-Google-Smtp-Source: AAOMgpfNxdNr3ADnLUDkRDDwCvfZeCagNxGrZ7Fqp5XYEKWRx0LPFHyzoADZa5gR8ZOqbqwjdtXdhg== X-Received: by 2002:adf:ff11:: with SMTP id k17-v6mr2539876wrr.255.1533303420953; Fri, 03 Aug 2018 06:37:00 -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 i14-v6sm8325261wmd.13.2018.08.03.06.37.00 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 03 Aug 2018 06:37:00 -0700 (PDT) Date: Fri, 3 Aug 2018 15:36:43 +0200 From: Adrien Mazarguil To: Ferruh Yigit Cc: dev@dpdk.org, Thomas Monjalon , Andrew Rybchenko , Gaetan Rivet Message-ID: <20180803132032.29038-7-adrien.mazarguil@6wind.com> References: <20180803132032.29038-1-adrien.mazarguil@6wind.com> MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: <20180803132032.29038-1-adrien.mazarguil@6wind.com> X-Mailer: git-send-email 2.11.0 Subject: [dpdk-dev] [PATCH v2 6/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 --- v2 changes: - Patch was not present in original series. --- lib/librte_ethdev/rte_flow.h | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/lib/librte_ethdev/rte_flow.h b/lib/librte_ethdev/rte_flow.h index c48ea8a51..891be1557 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, From patchwork Fri Aug 3 13:36:45 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Adrien Mazarguil X-Patchwork-Id: 43568 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 936501B598; Fri, 3 Aug 2018 15:37:05 +0200 (CEST) Received: from mail-wr1-f66.google.com (mail-wr1-f66.google.com [209.85.221.66]) by dpdk.org (Postfix) with ESMTP id 49E361B5A8 for ; Fri, 3 Aug 2018 15:37:03 +0200 (CEST) Received: by mail-wr1-f66.google.com with SMTP id u12-v6so5462048wrr.4 for ; Fri, 03 Aug 2018 06:37:03 -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=GJTj7KKAE7e+e0BGZSX7tflsEixv/wEScqoxuW/fnzQ=; b=ETvueLcyoZ74c5pihLaomN3Wja04NfrbtPdHQJZZJMOwSKNDTV1+wZ8QvivBUd4tNc NKehlTU0HoK2aJaZO7i4WrxKoU4umkWBBFzW6B4fYE7Gdsix7jw8/tDflfKhg8Q01KfR N+GwuiCnfwz4gOyYkjhAvYPgyIwBgJ5LfOsdCiudEtCCGgH28XkOmiE76vJZgjJPwVn5 R9rOuWaO9A4dTV6AI6qEaFHF1iFbN2GTzddJOWE9laDkUeMScfbvWqOc+rT2WCSFj/Jl i0SleCg0qdCimTZvdVXOMz++g0gKeP/cpYL+NvCtuzjNuZ0qbHNNbjYDLTPF5HiUwKYA eJ2Q== 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=GJTj7KKAE7e+e0BGZSX7tflsEixv/wEScqoxuW/fnzQ=; b=dGf77EFDHi5zo+lp09YiJoWYnnWLErXNRh5U5u4sR7zyTNWKft8IzrNUBNN+MBQeIu UtQPwSU+ogow3roDgRbk5mix6xjZdt6IDBHsA9QGiBfqc1hbNqLirI/HNpyRsu5Vmg46 JkE6b8hebBL2ljRs5yq47KJF3AAKhJHJL2rABtwFovnprmDkSez+KCnxnM9vOdVzd8KM PJy+ViLLuNfVkFQ3K28bRDjlWRz2feoUh9l6AdUizKF19upHB6Bn2nsJRFrbemq7AtoU Px0S5U3WJ1eTl1YdI+SE1qfKAGb24qHLkDShxsXSUxxfxL0x276DCIYI+NtZH87JUmLH 6ItA== X-Gm-Message-State: AOUpUlGRK24v4DBrAV/jWwz7wv407AhOp0Hg3EGPEWvoXWNOxA6apSfe +TndTzEJlk5AxBnlcDUtlHZthg== X-Google-Smtp-Source: AAOMgpfPllgnkO08tMC5oC4XFQRxgrI9dL7v16xWDF6CIkH69wiC6HWYhIGF/wr8FQpErRxpcoZlGg== X-Received: by 2002:a5d:4210:: with SMTP id n16-v6mr2485279wrq.55.1533303423052; Fri, 03 Aug 2018 06:37:03 -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 s24-v6sm4103398wmc.7.2018.08.03.06.37.02 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 03 Aug 2018 06:37:02 -0700 (PDT) Date: Fri, 3 Aug 2018 15:36:45 +0200 From: Adrien Mazarguil To: Ferruh Yigit Cc: dev@dpdk.org, Declan Doherty , Nelio Laranjeiro Message-ID: <20180803132032.29038-8-adrien.mazarguil@6wind.com> References: <20180803132032.29038-1-adrien.mazarguil@6wind.com> MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: <20180803132032.29038-1-adrien.mazarguil@6wind.com> X-Mailer: git-send-email 2.11.0 Subject: [dpdk-dev] [PATCH v2 7/7] ethdev: add missing item/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 5d487c108..0c84defdb 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));