From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-wr0-f194.google.com (mail-wr0-f194.google.com [209.85.128.194]) by dpdk.org (Postfix) with ESMTP id 108388E7F for ; Mon, 16 Apr 2018 18:22:55 +0200 (CEST) Received: by mail-wr0-f194.google.com with SMTP id h3so15079706wrh.5 for ; Mon, 16 Apr 2018 09:22:55 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=6wind-com.20150623.gappssmtp.com; s=20150623; h=date:from:to:subject:message-id:references:mime-version :content-disposition:in-reply-to; bh=EMcXLnmpSWL/gKJT4ZR6+soG6PVmRxqiTpdnKCJOu2A=; b=GEbapbq7IV8t+TRqVekiHscyQEGEP2E+RQsFfnUwFRpmt8V/fkRvJKK4Ulj/PaLIeI I2MSvx57ho6V11YbzQku9TK5WqaXU8l8RaDY6K0uF213Rrq6LJxAYogGcpOV0eerm7p+ PhcmANBYMEZqzDW1MRd68E1Fh6ehWLsiAr6L47ZX9QHa6sTpnkCuZT+pxv4Gb24sMzg4 HcduX5HRuR9MTBTfvofLE7YZY+VyhnxQx1iRjOdJ1G/9eDnm9Ig25TvCx1uXcIh6sdwu KTB1Gp3APC9xIVDw0FVXfdu1XOZkfRxO3tnXCWOiC1NvTOl4HhDrYSJ1VPgriHBXFWHS c06g== 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:subject:message-id:references :mime-version:content-disposition:in-reply-to; bh=EMcXLnmpSWL/gKJT4ZR6+soG6PVmRxqiTpdnKCJOu2A=; b=UzGXu+kQ3ocF7XUbtZo/DUTUa5lRVYor9WbWUXZIP1h5W/niQ6RVw6QQrnJyiwaZGu 9+0F3lXuMGjNDI6c9Upbg0evsMBISHRLMzer+DHBon4dm6XYgfjSWPNky+NM71lK2SA+ VXZXpxP+M9ylu61dSuff5cVEeg7YtR3/wd786nmWQgdcG+mZ7fJuXvxvyd5+pu0TCh15 aAJDCdaTj+UTbNyAx/2rLXrqZRPTL5XNMmy6MtgfuWQoutopsHGwhORA7ELXk4+DUkGY IdCbWEbcCchuHiKPOBMBzHCTND3S7lCroQwxiIemXbdTU8IqPblJnCjwmVfEkTuxvE0n SRtw== X-Gm-Message-State: ALQs6tAdzzKYzgE03lESaQdOQEhuBqiKkqCOsgJkCmQeivBp6yG7j58M 9L+V5oa4ejEsSWcTmTP1uO0oCQ== X-Google-Smtp-Source: AIpwx48NMbqD8hLcTaSts/TNwSRvHrK478oGwgNmtzEg5unVsLxiRJXzWQwPKlXDkdWCBrj8yMQgIA== X-Received: by 10.223.200.145 with SMTP id k17mr11449606wrh.6.1523895774228; Mon, 16 Apr 2018 09:22: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 m35sm16086481wrm.59.2018.04.16.09.22.53 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 16 Apr 2018 09:22:53 -0700 (PDT) Date: Mon, 16 Apr 2018 18:22:40 +0200 From: Adrien Mazarguil To: Thomas Monjalon , Ferruh Yigit , dev@dpdk.org Message-ID: <20180416150525.2817-7-adrien.mazarguil@6wind.com> References: <20180410162022.9101-1-adrien.mazarguil@6wind.com> <20180416150525.2817-1-adrien.mazarguil@6wind.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20180416150525.2817-1-adrien.mazarguil@6wind.com> X-Mailer: git-send-email 2.11.0 Subject: [dpdk-dev] [PATCH v4 06/16] ethdev: remove C99 flexible arrays from flow API 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: , X-List-Received-Date: Mon, 16 Apr 2018 16:22:55 -0000 This patch replaces C99-style flexible arrays in struct rte_flow_action_rss and struct rte_flow_item_raw with standard pointers to the same data. They proved difficult to use in the field (e.g. no possibility of static initialization) and unsuitable for C++ applications. Affected PMDs and examples are updated accordingly. This breaks ABI compatibility for the following public functions: - rte_flow_copy() - rte_flow_create() - rte_flow_query() - rte_flow_validate() Signed-off-by: Adrien Mazarguil --- app/test-pmd/cmdline_flow.c | 117 +++++++++++++++++--------------- app/test-pmd/config.c | 25 ++++--- doc/guides/prog_guide/rte_flow.rst | 18 ++--- drivers/net/mlx4/mlx4_flow.c | 22 +++--- drivers/net/mlx5/mlx5_flow.c | 20 +++--- examples/ipsec-secgw/ipsec.c | 17 ++--- lib/librte_ether/rte_flow.c | 25 ++++--- lib/librte_ether/rte_flow.h | 8 ++- 8 files changed, 135 insertions(+), 117 deletions(-) diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c index 2ddb08feb..798b7948d 100644 --- a/app/test-pmd/cmdline_flow.c +++ b/app/test-pmd/cmdline_flow.c @@ -179,25 +179,22 @@ enum index { ACTION_METER_ID, }; -/** Size of pattern[] field in struct rte_flow_item_raw. */ -#define ITEM_RAW_PATTERN_SIZE 36 +/** Maximum size for pattern in struct rte_flow_item_raw. */ +#define ITEM_RAW_PATTERN_SIZE 40 /** Storage size for struct rte_flow_item_raw including pattern. */ #define ITEM_RAW_SIZE \ - (offsetof(struct rte_flow_item_raw, pattern) + ITEM_RAW_PATTERN_SIZE) + (sizeof(struct rte_flow_item_raw) + ITEM_RAW_PATTERN_SIZE) /** Maximum number of queue indices in struct rte_flow_action_rss. */ #define ACTION_RSS_QUEUE_NUM 32 /** Storage for struct rte_flow_action_rss including external data. */ -union action_rss_data { +struct action_rss_data { struct rte_flow_action_rss conf; - struct { - uint8_t conf_data[offsetof(struct rte_flow_action_rss, queue)]; - uint16_t queue[ACTION_RSS_QUEUE_NUM]; - struct rte_eth_rss_conf rss_conf; - uint8_t rss_key[RSS_HASH_KEY_LENGTH]; - } s; + uint16_t queue[ACTION_RSS_QUEUE_NUM]; + struct rte_eth_rss_conf rss_conf; + uint8_t rss_key[RSS_HASH_KEY_LENGTH]; }; /** Maximum number of subsequent tokens and arguments on the stack. */ @@ -320,13 +317,6 @@ struct token { .size = sizeof(*((s *)0)->f), \ }) -/** Static initializer for ARGS() with arbitrary size. */ -#define ARGS_ENTRY_USZ(s, f, sz) \ - (&(const struct arg){ \ - .offset = offsetof(s, f), \ - .size = (sz), \ - }) - /** Static initializer for ARGS() with arbitrary offset and size. */ #define ARGS_ENTRY_ARB(o, s) \ (&(const struct arg){ \ @@ -1105,9 +1095,9 @@ static const struct token token_list[] = { NEXT_ENTRY(ITEM_PARAM_IS, ITEM_PARAM_SPEC, ITEM_PARAM_MASK)), - .args = ARGS(ARGS_ENTRY(struct rte_flow_item_raw, length), - ARGS_ENTRY_USZ(struct rte_flow_item_raw, - pattern, + .args = ARGS(ARGS_ENTRY(struct rte_flow_item_raw, pattern), + ARGS_ENTRY(struct rte_flow_item_raw, length), + ARGS_ENTRY_ARB(sizeof(struct rte_flow_item_raw), ITEM_RAW_PATTERN_SIZE)), }, [ITEM_ETH] = { @@ -1591,7 +1581,7 @@ static const struct token token_list[] = { [ACTION_RSS] = { .name = "rss", .help = "spread packets among several queues", - .priv = PRIV_ACTION(RSS, sizeof(union action_rss_data)), + .priv = PRIV_ACTION(RSS, sizeof(struct action_rss_data)), .next = NEXT(action_rss), .call = parse_vc_action_rss, }, @@ -1610,23 +1600,21 @@ static const struct token token_list[] = { .name = "key", .help = "RSS hash key", .next = NEXT(action_rss, NEXT_ENTRY(STRING)), - .args = ARGS(ARGS_ENTRY_ARB - (((uintptr_t)&((union action_rss_data *)0)-> - s.rss_conf.rss_key_len), + .args = ARGS(ARGS_ENTRY_ARB(0, 0), + ARGS_ENTRY_ARB + (offsetof(struct action_rss_data, rss_conf) + + offsetof(struct rte_eth_rss_conf, rss_key_len), sizeof(((struct rte_eth_rss_conf *)0)-> rss_key_len)), - ARGS_ENTRY_ARB - (((uintptr_t)((union action_rss_data *)0)-> - s.rss_key), - RSS_HASH_KEY_LENGTH)), + ARGS_ENTRY(struct action_rss_data, rss_key)), }, [ACTION_RSS_KEY_LEN] = { .name = "key_len", .help = "RSS hash key length in bytes", .next = NEXT(action_rss, NEXT_ENTRY(UNSIGNED)), .args = ARGS(ARGS_ENTRY_ARB_BOUNDED - (((uintptr_t)&((union action_rss_data *)0)-> - s.rss_conf.rss_key_len), + (offsetof(struct action_rss_data, rss_conf) + + offsetof(struct rte_eth_rss_conf, rss_key_len), sizeof(((struct rte_eth_rss_conf *)0)-> rss_key_len), 0, @@ -2067,7 +2055,7 @@ parse_vc_action_rss(struct context *ctx, const struct token *token, { struct buffer *out = buf; struct rte_flow_action *action; - union action_rss_data *action_rss_data; + struct action_rss_data *action_rss_data; unsigned int i; int ret; @@ -2085,29 +2073,29 @@ parse_vc_action_rss(struct context *ctx, const struct token *token, ctx->objmask = NULL; /* Set up default configuration. */ action_rss_data = ctx->object; - *action_rss_data = (union action_rss_data){ + *action_rss_data = (struct action_rss_data){ .conf = (struct rte_flow_action_rss){ - .rss_conf = &action_rss_data->s.rss_conf, + .rss_conf = &action_rss_data->rss_conf, .num = RTE_MIN(nb_rxq, ACTION_RSS_QUEUE_NUM), + .queue = action_rss_data->queue, }, + .queue = { 0 }, + .rss_conf = (struct rte_eth_rss_conf){ + .rss_key = action_rss_data->rss_key, + .rss_key_len = sizeof(action_rss_data->rss_key), + .rss_hf = rss_hf, + }, + .rss_key = "testpmd's default RSS hash key", }; - action_rss_data->s.rss_conf = (struct rte_eth_rss_conf){ - .rss_key = action_rss_data->s.rss_key, - .rss_key_len = sizeof(action_rss_data->s.rss_key), - .rss_hf = rss_hf, - }; - strncpy((void *)action_rss_data->s.rss_key, - "testpmd's default RSS hash key", - sizeof(action_rss_data->s.rss_key)); for (i = 0; i < action_rss_data->conf.num; ++i) - action_rss_data->conf.queue[i] = i; + action_rss_data->queue[i] = i; if (!port_id_is_invalid(ctx->port, DISABLED_WARN) && ctx->port != (portid_t)RTE_PORT_ALL) { struct rte_eth_dev_info info; rte_eth_dev_info_get(ctx->port, &info); - action_rss_data->s.rss_conf.rss_key_len = - RTE_MIN(sizeof(action_rss_data->s.rss_key), + action_rss_data->rss_conf.rss_key_len = + RTE_MIN(sizeof(action_rss_data->rss_key), info.hash_key_size); } action->conf = &action_rss_data->conf; @@ -2125,7 +2113,7 @@ parse_vc_action_rss_type(struct context *ctx, const struct token *token, void *buf, unsigned int size) { static const enum index next[] = NEXT_ENTRY(ACTION_RSS_TYPE); - union action_rss_data *action_rss_data; + struct action_rss_data *action_rss_data; unsigned int i; (void)token; @@ -2135,7 +2123,7 @@ parse_vc_action_rss_type(struct context *ctx, const struct token *token, return -1; if (!(ctx->objdata >> 16) && ctx->object) { action_rss_data = ctx->object; - action_rss_data->s.rss_conf.rss_hf = 0; + action_rss_data->rss_conf.rss_hf = 0; } if (!strcmp_partial("end", str, len)) { ctx->objdata &= 0xffff; @@ -2154,7 +2142,7 @@ parse_vc_action_rss_type(struct context *ctx, const struct token *token, if (!ctx->object) return len; action_rss_data = ctx->object; - action_rss_data->s.rss_conf.rss_hf |= rss_type_table[i].rss_type; + action_rss_data->rss_conf.rss_hf |= rss_type_table[i].rss_type; return len; } @@ -2169,7 +2157,7 @@ parse_vc_action_rss_queue(struct context *ctx, const struct token *token, void *buf, unsigned int size) { static const enum index next[] = NEXT_ENTRY(ACTION_RSS_QUEUE); - union action_rss_data *action_rss_data; + struct action_rss_data *action_rss_data; int ret; int i; @@ -2186,10 +2174,9 @@ parse_vc_action_rss_queue(struct context *ctx, const struct token *token, if (i >= ACTION_RSS_QUEUE_NUM) return -1; if (push_args(ctx, - ARGS_ENTRY_ARB(offsetof(struct rte_flow_action_rss, - queue) + - i * sizeof(action_rss_data->s.queue[i]), - sizeof(action_rss_data->s.queue[i])))) + ARGS_ENTRY_ARB(offsetof(struct action_rss_data, queue) + + i * sizeof(action_rss_data->queue[i]), + sizeof(action_rss_data->queue[i])))) return -1; ret = parse_int(ctx, token, str, len, NULL, 0); if (ret < 0) { @@ -2206,6 +2193,7 @@ parse_vc_action_rss_queue(struct context *ctx, const struct token *token, return len; action_rss_data = ctx->object; action_rss_data->conf.num = i; + action_rss_data->conf.queue = i ? action_rss_data->queue : NULL; return len; } @@ -2483,8 +2471,8 @@ parse_int(struct context *ctx, const struct token *token, /** * Parse a string. * - * Two arguments (ctx->args) are retrieved from the stack to store data and - * its length (in that order). + * Three arguments (ctx->args) are retrieved from the stack to store data, + * its actual length and address (in that order). */ static int parse_string(struct context *ctx, const struct token *token, @@ -2493,6 +2481,7 @@ parse_string(struct context *ctx, const struct token *token, { const struct arg *arg_data = pop_args(ctx); const struct arg *arg_len = pop_args(ctx); + const struct arg *arg_addr = pop_args(ctx); char tmp[16]; /* Ought to be enough. */ int ret; @@ -2503,6 +2492,11 @@ parse_string(struct context *ctx, const struct token *token, push_args(ctx, arg_data); return -1; } + if (!arg_addr) { + push_args(ctx, arg_len); + push_args(ctx, arg_data); + return -1; + } size = arg_data->size; /* Bit-mask fill is not supported. */ if (arg_data->mask || size < len) @@ -2525,8 +2519,23 @@ parse_string(struct context *ctx, const struct token *token, memset((uint8_t *)buf + len, 0x00, size - len); if (ctx->objmask) memset((uint8_t *)ctx->objmask + arg_data->offset, 0xff, len); + /* Save address if requested. */ + if (arg_addr->size) { + memcpy((uint8_t *)ctx->object + arg_addr->offset, + (void *[]){ + (uint8_t *)ctx->object + arg_data->offset + }, + arg_addr->size); + if (ctx->objmask) + memcpy((uint8_t *)ctx->objmask + arg_addr->offset, + (void *[]){ + (uint8_t *)ctx->objmask + arg_data->offset + }, + arg_addr->size); + } return len; error: + push_args(ctx, arg_addr); push_args(ctx, arg_len); push_args(ctx, arg_data); return -1; diff --git a/app/test-pmd/config.c b/app/test-pmd/config.c index d0d372797..95618e4eb 100644 --- a/app/test-pmd/config.c +++ b/app/test-pmd/config.c @@ -977,7 +977,7 @@ static const struct { MK_FLOW_ITEM(PF, 0), MK_FLOW_ITEM(VF, sizeof(struct rte_flow_item_vf)), MK_FLOW_ITEM(PORT, sizeof(struct rte_flow_item_port)), - MK_FLOW_ITEM(RAW, sizeof(struct rte_flow_item_raw)), /* +pattern[] */ + 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)), @@ -1026,14 +1026,20 @@ flow_item_spec_copy(void *buf, const struct rte_flow_item *item, union { struct rte_flow_item_raw *raw; } dst; + size_t off; case RTE_FLOW_ITEM_TYPE_RAW: src.raw = item_spec; dst.raw = buf; - size = offsetof(struct rte_flow_item_raw, pattern) + - src.raw->length * sizeof(*src.raw->pattern); - if (dst.raw) - memcpy(dst.raw, src.raw, size); + off = RTE_ALIGN_CEIL(sizeof(struct rte_flow_item_raw), + sizeof(*src.raw->pattern)); + size = off + src.raw->length * 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; @@ -1065,7 +1071,7 @@ static const struct { MK_FLOW_ACTION(QUEUE, sizeof(struct rte_flow_action_queue)), MK_FLOW_ACTION(DROP, 0), MK_FLOW_ACTION(COUNT, 0), - MK_FLOW_ACTION(RSS, sizeof(struct rte_flow_action_rss)), /* +queue[] */ + 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(METER, sizeof(struct rte_flow_action_meter)), @@ -1096,11 +1102,14 @@ flow_action_conf_copy(void *buf, const struct rte_flow_action *action) *dst.rss = (struct rte_flow_action_rss){ .num = src.rss->num, }; - off += offsetof(struct rte_flow_action_rss, queue); + off += sizeof(*src.rss); if (src.rss->num) { + off = RTE_ALIGN_CEIL(off, sizeof(double)); size = sizeof(*src.rss->queue) * src.rss->num; if (dst.rss) - memcpy(dst.rss->queue, src.rss->queue, size); + dst.rss->queue = memcpy + ((void *)((uintptr_t)dst.rss + off), + src.rss->queue, size); off += size; } off = RTE_ALIGN_CEIL(off, sizeof(double)); diff --git a/doc/guides/prog_guide/rte_flow.rst b/doc/guides/prog_guide/rte_flow.rst index 80360d068..acbeaacbd 100644 --- a/doc/guides/prog_guide/rte_flow.rst +++ b/doc/guides/prog_guide/rte_flow.rst @@ -1309,15 +1309,15 @@ field only, both can be requested simultaneously. .. table:: RSS - +--------------+------------------------------+ - | Field | Value | - +==============+==============================+ - | ``rss_conf`` | RSS parameters | - +--------------+------------------------------+ - | ``num`` | number of entries in queue[] | - +--------------+------------------------------+ - | ``queue[]`` | queue indices to use | - +--------------+------------------------------+ + +--------------+--------------------------------+ + | Field | Value | + +==============+================================+ + | ``rss_conf`` | RSS parameters | + +--------------+--------------------------------+ + | ``num`` | number of entries in ``queue`` | + +--------------+--------------------------------+ + | ``queue`` | queue indices to use | + +--------------+--------------------------------+ Action: ``PF`` ^^^^^^^^^^^^^^ diff --git a/drivers/net/mlx4/mlx4_flow.c b/drivers/net/mlx4/mlx4_flow.c index 15cdf07b7..8feb6ae31 100644 --- a/drivers/net/mlx4/mlx4_flow.c +++ b/drivers/net/mlx4/mlx4_flow.c @@ -1282,14 +1282,16 @@ mlx4_flow_internal(struct priv *priv, struct rte_flow_error *error) */ uint32_t queues = rte_align32pow2(priv->dev->data->nb_rx_queues + 1) >> 1; - alignas(struct rte_flow_action_rss) uint8_t rss_conf_data - [offsetof(struct rte_flow_action_rss, queue) + - sizeof(((struct rte_flow_action_rss *)0)->queue[0]) * queues]; - struct rte_flow_action_rss *rss_conf = (void *)rss_conf_data; + uint16_t queue[queues]; + struct rte_flow_action_rss action_rss = { + .rss_conf = NULL, /* Rely on default fallback settings. */ + .num = queues, + .queue = queue, + }; struct rte_flow_action actions[] = { { .type = RTE_FLOW_ACTION_TYPE_RSS, - .conf = rss_conf, + .conf = &action_rss, }, { .type = RTE_FLOW_ACTION_TYPE_END, @@ -1311,12 +1313,8 @@ mlx4_flow_internal(struct priv *priv, struct rte_flow_error *error) if (!queues) goto error; /* Prepare default RSS configuration. */ - *rss_conf = (struct rte_flow_action_rss){ - .rss_conf = NULL, /* Rely on default fallback settings. */ - .num = queues, - }; for (i = 0; i != queues; ++i) - rss_conf->queue[i] = i; + queue[i] = i; /* * Set up VLAN item if filtering is enabled and at least one VLAN * filter is configured. @@ -1375,7 +1373,7 @@ mlx4_flow_internal(struct priv *priv, struct rte_flow_error *error) if (j != sizeof(mac->addr_bytes)) continue; if (flow->rss->queues != queues || - memcmp(flow->rss->queue_id, rss_conf->queue, + memcmp(flow->rss->queue_id, action_rss.queue, queues * sizeof(flow->rss->queue_id[0]))) continue; break; @@ -1415,7 +1413,7 @@ mlx4_flow_internal(struct priv *priv, struct rte_flow_error *error) if (flow && flow->internal) { assert(flow->rss); if (flow->rss->queues != queues || - memcmp(flow->rss->queue_id, rss_conf->queue, + memcmp(flow->rss->queue_id, action_rss.queue, queues * sizeof(flow->rss->queue_id[0]))) flow = NULL; } diff --git a/drivers/net/mlx5/mlx5_flow.c b/drivers/net/mlx5/mlx5_flow.c index 9923bfa59..75ea0cbcb 100644 --- a/drivers/net/mlx5/mlx5_flow.c +++ b/drivers/net/mlx5/mlx5_flow.c @@ -2446,9 +2446,16 @@ mlx5_ctrl_flow_vlan(struct rte_eth_dev *dev, .type = RTE_FLOW_ITEM_TYPE_END, }, }; + uint16_t queue[priv->reta_idx_n]; + struct rte_flow_action_rss action_rss = { + .rss_conf = &priv->rss_conf, + .num = priv->reta_idx_n, + .queue = queue, + }; struct rte_flow_action actions[] = { { .type = RTE_FLOW_ACTION_TYPE_RSS, + .conf = &action_rss, }, { .type = RTE_FLOW_ACTION_TYPE_END, @@ -2457,24 +2464,13 @@ mlx5_ctrl_flow_vlan(struct rte_eth_dev *dev, struct rte_flow *flow; struct rte_flow_error error; unsigned int i; - union { - struct rte_flow_action_rss rss; - struct { - const struct rte_eth_rss_conf *rss_conf; - uint16_t num; - uint16_t queue[RTE_MAX_QUEUES_PER_PORT]; - } local; - } action_rss; if (!priv->reta_idx_n) { rte_errno = EINVAL; return -rte_errno; } for (i = 0; i != priv->reta_idx_n; ++i) - action_rss.local.queue[i] = (*priv->reta_idx)[i]; - action_rss.local.rss_conf = &priv->rss_conf; - action_rss.local.num = priv->reta_idx_n; - actions[0].conf = (const void *)&action_rss.rss; + queue[i] = (*priv->reta_idx)[i]; flow = mlx5_flow_list_create(dev, &priv->ctrl_flows, &attr, items, actions, &error); if (!flow) diff --git a/examples/ipsec-secgw/ipsec.c b/examples/ipsec-secgw/ipsec.c index 5fb5bc16e..8b2047adb 100644 --- a/examples/ipsec-secgw/ipsec.c +++ b/examples/ipsec-secgw/ipsec.c @@ -186,14 +186,8 @@ create_session(struct ipsec_ctx *ipsec_ctx, struct ipsec_sa *sa) .rss_key_len = 40, }; struct rte_eth_dev *eth_dev; - union { - struct rte_flow_action_rss rss; - struct { - const struct rte_eth_rss_conf *rss_conf; - uint16_t num; - uint16_t queue[RTE_MAX_QUEUES_PER_PORT]; - } local; - } action_rss; + uint16_t queue[RTE_MAX_QUEUES_PER_PORT]; + struct rte_flow_action_rss action_rss; unsigned int i; unsigned int j; @@ -207,9 +201,10 @@ create_session(struct ipsec_ctx *ipsec_ctx, struct ipsec_sa *sa) for (i = 0, j = 0; i < eth_dev->data->nb_rx_queues; ++i) if (eth_dev->data->rx_queues[i]) - action_rss.local.queue[j++] = i; - action_rss.local.num = j; - action_rss.local.rss_conf = &rss_conf; + queue[j++] = i; + action_rss.rss_conf = &rss_conf; + action_rss.num = j; + action_rss.queue = queue; ret = rte_flow_validate(sa->portid, &sa->attr, sa->pattern, sa->action, &err); diff --git a/lib/librte_ether/rte_flow.c b/lib/librte_ether/rte_flow.c index 80f9cb6cb..bb19e28c6 100644 --- a/lib/librte_ether/rte_flow.c +++ b/lib/librte_ether/rte_flow.c @@ -39,7 +39,7 @@ static const struct rte_flow_desc_data rte_flow_desc_item[] = { MK_FLOW_ITEM(PF, 0), MK_FLOW_ITEM(VF, sizeof(struct rte_flow_item_vf)), MK_FLOW_ITEM(PORT, sizeof(struct rte_flow_item_port)), - MK_FLOW_ITEM(RAW, sizeof(struct rte_flow_item_raw)), /* +pattern[] */ + 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)), @@ -73,7 +73,7 @@ static const struct rte_flow_desc_data rte_flow_desc_action[] = { MK_FLOW_ACTION(QUEUE, sizeof(struct rte_flow_action_queue)), MK_FLOW_ACTION(DROP, 0), MK_FLOW_ACTION(COUNT, 0), - MK_FLOW_ACTION(RSS, sizeof(struct rte_flow_action_rss)), /* +queue[] */ + 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)), }; @@ -282,14 +282,20 @@ flow_item_spec_copy(void *buf, const struct rte_flow_item *item, union { struct rte_flow_item_raw *raw; } dst; + size_t off; case RTE_FLOW_ITEM_TYPE_RAW: src.raw = item_spec; dst.raw = buf; - size = offsetof(struct rte_flow_item_raw, pattern) + - src.raw->length * sizeof(*src.raw->pattern); - if (dst.raw) - memcpy(dst.raw, src.raw, size); + off = RTE_ALIGN_CEIL(sizeof(struct rte_flow_item_raw), + sizeof(*src.raw->pattern)); + size = off + src.raw->length * 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 = rte_flow_desc_item[item->type].size; @@ -326,11 +332,14 @@ flow_action_conf_copy(void *buf, const struct rte_flow_action *action) *dst.rss = (struct rte_flow_action_rss){ .num = src.rss->num, }; - off += offsetof(struct rte_flow_action_rss, queue); + off += sizeof(*src.rss); if (src.rss->num) { + off = RTE_ALIGN_CEIL(off, sizeof(double)); size = sizeof(*src.rss->queue) * src.rss->num; if (dst.rss) - memcpy(dst.rss->queue, src.rss->queue, size); + dst.rss->queue = memcpy + ((void *)((uintptr_t)dst.rss + off), + src.rss->queue, size); off += size; } off = RTE_ALIGN_CEIL(off, sizeof(double)); diff --git a/lib/librte_ether/rte_flow.h b/lib/librte_ether/rte_flow.h index 96184f030..ad2e55b8e 100644 --- a/lib/librte_ether/rte_flow.h +++ b/lib/librte_ether/rte_flow.h @@ -14,6 +14,7 @@ * associated actions in hardware through flow rules. */ +#include #include #include @@ -432,7 +433,7 @@ struct rte_flow_item_raw { int32_t offset; /**< Absolute or relative offset for pattern. */ uint16_t limit; /**< Search area limit for start of pattern. */ uint16_t length; /**< Pattern length. */ - uint8_t pattern[]; /**< Byte string to look for. */ + const uint8_t *pattern; /**< Byte string to look for. */ }; /** Default mask for RTE_FLOW_ITEM_TYPE_RAW. */ @@ -444,6 +445,7 @@ static const struct rte_flow_item_raw rte_flow_item_raw_mask = { .offset = 0xffffffff, .limit = 0xffff, .length = 0xffff, + .pattern = NULL, }; #endif @@ -1037,8 +1039,8 @@ struct rte_flow_query_count { */ struct rte_flow_action_rss { const struct rte_eth_rss_conf *rss_conf; /**< RSS parameters. */ - uint16_t num; /**< Number of entries in queue[]. */ - uint16_t queue[]; /**< Queues indices to use. */ + uint16_t num; /**< Number of entries in @p queue. */ + const uint16_t *queue; /**< Queue indices to use. */ }; /** -- 2.11.0