From 19b3bc47c624296002a6b0c18b97afa423c082d7 Mon Sep 17 00:00:00 2001 From: Adrien Mazarguil Date: Wed, 25 Apr 2018 17:27:48 +0200 Subject: [PATCH] ethdev: fix C99 flexible arrays from flow API 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() Fixes: b1a4b4cbc0a8 ("ethdev: introduce generic flow API") Signed-off-by: Adrien Mazarguil Acked-by: Thomas Monjalon Acked-by: Nelio Laranjeiro --- app/test-pmd/cmdline_flow.c | 117 +++++++++++++------------ app/test-pmd/config.c | 25 ++++-- doc/guides/prog_guide/rte_flow.rst | 18 ++-- doc/guides/rel_notes/release_18_05.rst | 8 +- 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 +- 9 files changed, 141 insertions(+), 119 deletions(-) diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c index 2ddb08feb4..798b7948d6 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 @@ error: /** * 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 d5862ce338..5a68d0a6df 100644 --- a/app/test-pmd/config.c +++ b/app/test-pmd/config.c @@ -994,7 +994,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)), @@ -1043,14 +1043,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; @@ -1082,7 +1088,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)), @@ -1113,11 +1119,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 80360d0688..acbeaacbdf 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/doc/guides/rel_notes/release_18_05.rst b/doc/guides/rel_notes/release_18_05.rst index 4deb44c49c..9b98fa99fc 100644 --- a/doc/guides/rel_notes/release_18_05.rst +++ b/doc/guides/rel_notes/release_18_05.rst @@ -267,6 +267,8 @@ API Changes properties anymore. * Flow rules are now always terminating unless a PASSTHRU action is present. + * C99-style flexible arrays were replaced with standard pointers in RSS + action and in RAW pattern item structures due to compatibility issues. ABI Changes @@ -314,8 +316,10 @@ ABI Changes ``rte_flow_destroy``, ``rte_flow_error_set``, ``rte_flow_flush``, ``rte_flow_isolate``, ``rte_flow_query`` and ``rte_flow_validate``, due to changes in error type definitions (``enum rte_flow_error_type``), removal - of the unused DUP action (``enum rte_flow_action_type``) and modified - behavior for flow rule actions (see API changes). + of the unused DUP action (``enum rte_flow_action_type``), modified + behavior for flow rule actions (see API changes) and removal of C99 + flexible arrays from RSS action (``struct rte_flow_action_rss``) and RAW + pattern item (``struct rte_flow_item_raw``). Removed Items diff --git a/drivers/net/mlx4/mlx4_flow.c b/drivers/net/mlx4/mlx4_flow.c index 15cdf07b7b..8feb6ae31c 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 @@ next_vlan: 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 @@ next_vlan: 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 586e780c46..0c89bff457 100644 --- a/drivers/net/mlx5/mlx5_flow.c +++ b/drivers/net/mlx5/mlx5_flow.c @@ -2456,9 +2456,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, @@ -2467,24 +2474,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 acdd1898b5..5971937cfe 100644 --- a/examples/ipsec-secgw/ipsec.c +++ b/examples/ipsec-secgw/ipsec.c @@ -187,14 +187,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; @@ -208,9 +202,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 80f9cb6cb1..bb19e28c67 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 96184f030d..ad2e55b8e3 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.20.1