From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-wm0-f67.google.com (mail-wm0-f67.google.com [74.125.82.67]) by dpdk.org (Postfix) with ESMTP id E8D6EDD2 for ; Mon, 30 Apr 2018 16:54:40 +0200 (CEST) Received: by mail-wm0-f67.google.com with SMTP id j4so13674119wme.1 for ; Mon, 30 Apr 2018 07:54:40 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=yYxl6GoF+JC2L15Mry5gPmeDC/tfsM5VeTQZlhmTx8I=; b=aOKnDKW+8hkY70eXseYj5GOdCoa3Dx5wJs41T7022Gfa2O01ImQo6jiOltJOrRBwU+ h0TnRgI3fiUwB56759eiCtfPUff0FOMvV5+RXkc/JAU3fq7MwI1T8m7nZwiefa1KIekS YnmIwG3O540B6Dy6Gqft9PLPUHTZYBQRV5FXC9TMCeiJuxMv1JAKZR53FpI73w5iHEXR 0alPv1VRGT33XJtXc6NJGm2HDRMqTV8RO+7wqqsce9pauDQaufP0/uQnhcg7O4+qVGH8 I2MzGGhRt8EVVuLjBdVOIVscleBqjsGkAhmj86vS6Da+mE+ovDoKyVjXwoo3MdhwNQm9 E8+A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=yYxl6GoF+JC2L15Mry5gPmeDC/tfsM5VeTQZlhmTx8I=; b=ZqWplCfka86qPjn+thYpizFVFBHgEan91JTU1dllGnN+4ijQzSeO9aiS5wgWo4kWpq KkiULVSD0f/65olcws9uANQSdFdLUAXBcM8P7qlbWQCtRv2o9Q5ZiD+hhWbqztDuMCnr GHbazK15pSdc0Gg5Y8a8diSsRH3ZYk57Nf2F4JraEyGPOFjBZTI2VtGLhAf4tLsAaTwu SqDqeZsEt3Ofi0s6htYbdl3dcC0IwSQoEGhQ2vROGkwd8in2cJnChSnjvWpCapaR4AWD 0W6Tz9A4U2OMjgv09++zMYUrE71bLlho71Ye8PoRuSAibNgK7ctQLOr+9nHjXh5h/cW8 BkHQ== X-Gm-Message-State: ALQs6tBqjuytBDzowXV8AFEFqIvgEcqkDGCuuQocLgLp1Ed4KwePg239 /pL6sBHsO+oYsP061m8MBvk= X-Google-Smtp-Source: AB8JxZpz5sDHymP3xZDUpAJhOdlOLWF55lcAeRh2uUas0IW0jOrNwMROBXv/d1w3OpG2QyGrhVcagw== X-Received: by 10.28.181.71 with SMTP id e68mr1821111wmf.158.1525100080239; Mon, 30 Apr 2018 07:54:40 -0700 (PDT) Received: from localhost ([2a00:23c5:be9a:5200:ce4c:82c0:d567:ecbb]) by smtp.gmail.com with ESMTPSA id h12sm9699725wmc.7.2018.04.30.07.54.39 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Mon, 30 Apr 2018 07:54:39 -0700 (PDT) From: luca.boccassi@gmail.com To: Adrien Mazarguil Cc: Nelio Laranjeiro , Ferruh Yigit , dpdk stable Date: Mon, 30 Apr 2018 15:53:42 +0100 Message-Id: <20180430145402.23057-23-luca.boccassi@gmail.com> X-Mailer: git-send-email 2.14.2 In-Reply-To: <20180430145402.23057-1-luca.boccassi@gmail.com> References: <20180430144223.18657-85-luca.boccassi@gmail.com> <20180430145402.23057-1-luca.boccassi@gmail.com> Subject: [dpdk-stable] patch 'app/testpmd: fix missing RSS fields in flow action' has been queued to stable release 18.02.2 X-BeenThere: stable@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: patches for DPDK stable branches List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 30 Apr 2018 14:54:41 -0000 Hi, FYI, your patch has been queued to stable release 18.02.2 Note it hasn't been pushed to http://dpdk.org/browse/dpdk-stable yet. It will be pushed if I get no objections before 05/02/18. So please shout if anyone has objections. Thanks. Luca Boccassi --- >>From 5b9632a2d38e04e55d925e6d0169cdd9eebe3401 Mon Sep 17 00:00:00 2001 From: Adrien Mazarguil Date: Thu, 19 Apr 2018 12:07:40 +0200 Subject: [PATCH] app/testpmd: fix missing RSS fields in flow action [ upstream commit f4d623f96119ed720e87b16fb33985879160bfb7 ] Users cannot override the default RSS settings when entering a RSS action, only a list of queues can be provided. This patch enables them to set a RSS hash key and types for a flow rule. Fixes: 05d34c6e9d2c ("app/testpmd: add queue actions to flow command") Signed-off-by: Adrien Mazarguil Acked-by: Nelio Laranjeiro Acked-by: Ferruh Yigit --- app/test-pmd/cmdline_flow.c | 133 +++++++++++++++++++++++++++- app/test-pmd/config.c | 20 ++--- app/test-pmd/testpmd.h | 13 +++ doc/guides/testpmd_app_ug/testpmd_funcs.rst | 8 ++ 4 files changed, 163 insertions(+), 11 deletions(-) diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c index 0e250d595..e43705303 100644 --- a/app/test-pmd/cmdline_flow.c +++ b/app/test-pmd/cmdline_flow.c @@ -167,6 +167,10 @@ enum index { ACTION_DUP, ACTION_DUP_INDEX, ACTION_RSS, + ACTION_RSS_TYPES, + ACTION_RSS_TYPE, + ACTION_RSS_KEY, + ACTION_RSS_KEY_LEN, ACTION_RSS_QUEUES, ACTION_RSS_QUEUE, ACTION_PF, @@ -223,6 +227,9 @@ struct context { struct arg { uint32_t hton:1; /**< Use network byte ordering. */ uint32_t sign:1; /**< Value is signed. */ + uint32_t bounded:1; /**< Value is bounded. */ + uintmax_t min; /**< Minimum value if bounded. */ + uintmax_t max; /**< Maximum value if bounded. */ uint32_t offset; /**< Relative offset from ctx->object. */ uint32_t size; /**< Field size. */ const uint8_t *mask; /**< Bit-mask to use instead of offset/size. */ @@ -329,6 +336,16 @@ struct token { .size = (s), \ }) +/** Same as ARGS_ENTRY_ARB() with bounded values. */ +#define ARGS_ENTRY_ARB_BOUNDED(o, s, i, a) \ + (&(const struct arg){ \ + .bounded = 1, \ + .min = (i), \ + .max = (a), \ + .offset = (o), \ + .size = (s), \ + }) + /** Same as ARGS_ENTRY() using network byte ordering. */ #define ARGS_ENTRY_HTON(s, f) \ (&(const struct arg){ \ @@ -635,6 +652,9 @@ static const enum index action_dup[] = { }; static const enum index action_rss[] = { + ACTION_RSS_TYPES, + ACTION_RSS_KEY, + ACTION_RSS_KEY_LEN, ACTION_RSS_QUEUES, ACTION_NEXT, ZERO, @@ -666,6 +686,9 @@ static int parse_vc_conf(struct context *, const struct token *, static int parse_vc_action_rss(struct context *, const struct token *, const char *, unsigned int, void *, unsigned int); +static int parse_vc_action_rss_type(struct context *, const struct token *, + const char *, unsigned int, void *, + unsigned int); static int parse_vc_action_rss_queue(struct context *, const struct token *, const char *, unsigned int, void *, unsigned int); @@ -721,6 +744,8 @@ static int comp_port(struct context *, const struct token *, unsigned int, char *, unsigned int); static int comp_rule_id(struct context *, const struct token *, unsigned int, char *, unsigned int); +static int comp_vc_action_rss_type(struct context *, const struct token *, + unsigned int, char *, unsigned int); static int comp_vc_action_rss_queue(struct context *, const struct token *, unsigned int, char *, unsigned int); @@ -1593,6 +1618,43 @@ static const struct token token_list[] = { .next = NEXT(action_rss), .call = parse_vc_action_rss, }, + [ACTION_RSS_TYPES] = { + .name = "types", + .help = "RSS hash types", + .next = NEXT(action_rss, NEXT_ENTRY(ACTION_RSS_TYPE)), + }, + [ACTION_RSS_TYPE] = { + .name = "{type}", + .help = "RSS hash type", + .call = parse_vc_action_rss_type, + .comp = comp_vc_action_rss_type, + }, + [ACTION_RSS_KEY] = { + .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), + 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)), + }, + [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), + sizeof(((struct rte_eth_rss_conf *)0)-> + rss_key_len), + 0, + RSS_HASH_KEY_LENGTH)), + }, [ACTION_RSS_QUEUES] = { .name = "queues", .help = "queue indices to use", @@ -2075,6 +2137,50 @@ parse_vc_action_rss(struct context *ctx, const struct token *token, return ret; } +/** + * Parse type field for RSS action. + * + * Valid tokens are type field names and the "end" token. + */ +static int +parse_vc_action_rss_type(struct context *ctx, const struct token *token, + const char *str, unsigned int len, + void *buf, unsigned int size) +{ + static const enum index next[] = NEXT_ENTRY(ACTION_RSS_TYPE); + union action_rss_data *action_rss_data; + unsigned int i; + + (void)token; + (void)buf; + (void)size; + if (ctx->curr != ACTION_RSS_TYPE) + return -1; + if (!(ctx->objdata >> 16) && ctx->object) { + action_rss_data = ctx->object; + action_rss_data->s.rss_conf.rss_hf = 0; + } + if (!strcmp_partial("end", str, len)) { + ctx->objdata &= 0xffff; + return len; + } + for (i = 0; rss_type_table[i].str; ++i) + if (!strcmp_partial(rss_type_table[i].str, str, len)) + break; + if (!rss_type_table[i].str) + return -1; + ctx->objdata = 1 << 16 | (ctx->objdata & 0xffff); + /* Repeat token. */ + if (ctx->next_num == RTE_DIM(ctx->next)) + return -1; + ctx->next[ctx->next_num++] = next; + if (!ctx->object) + return len; + action_rss_data = ctx->object; + action_rss_data->s.rss_conf.rss_hf |= rss_type_table[i].rss_type; + return len; +} + /** * Parse queue field for RSS action. * @@ -2341,6 +2447,11 @@ parse_int(struct context *ctx, const struct token *token, strtoumax(str, &end, 0); if (errno || (size_t)(end - str) != len) goto error; + if (arg->bounded && + ((arg->sign && ((intmax_t)u < (intmax_t)arg->min || + (intmax_t)u > (intmax_t)arg->max)) || + (!arg->sign && (u < arg->min || u > arg->max)))) + goto error; if (!ctx->object) return len; if (arg->mask) { @@ -2434,7 +2545,7 @@ parse_string(struct context *ctx, const struct token *token, buf = (uint8_t *)ctx->object + arg_data->offset; /* Output buffer is not necessarily NUL-terminated. */ memcpy(buf, str, len); - memset((uint8_t *)buf + len, 0x55, size - len); + memset((uint8_t *)buf + len, 0x00, size - len); if (ctx->objmask) memset((uint8_t *)ctx->objmask + arg_data->offset, 0xff, len); return len; @@ -2730,6 +2841,26 @@ comp_rule_id(struct context *ctx, const struct token *token, return i; } +/** Complete type field for RSS action. */ +static int +comp_vc_action_rss_type(struct context *ctx, const struct token *token, + unsigned int ent, char *buf, unsigned int size) +{ + unsigned int i; + + (void)ctx; + (void)token; + for (i = 0; rss_type_table[i].str; ++i) + ; + if (!buf) + return i + 1; + if (ent < i) + return snprintf(buf, size, "%s", rss_type_table[ent].str); + if (ent == i) + return snprintf(buf, size, "end"); + return -1; +} + /** Complete queue field for RSS action. */ static int comp_vc_action_rss_queue(struct context *ctx, const struct token *token, diff --git a/app/test-pmd/config.c b/app/test-pmd/config.c index aab5db355..2058e6ec8 100644 --- a/app/test-pmd/config.c +++ b/app/test-pmd/config.c @@ -73,12 +73,7 @@ static const struct { }, }; -struct rss_type_info { - char str[32]; - uint64_t rss_type; -}; - -static const struct rss_type_info rss_type_table[] = { +const struct rss_type_info rss_type_table[] = { { "ipv4", ETH_RSS_IPV4 }, { "ipv4-frag", ETH_RSS_FRAG_IPV4 }, { "ipv4-tcp", ETH_RSS_NONFRAG_IPV4_TCP }, @@ -99,7 +94,12 @@ static const struct rss_type_info rss_type_table[] = { { "vxlan", ETH_RSS_VXLAN }, { "geneve", ETH_RSS_GENEVE }, { "nvgre", ETH_RSS_NVGRE }, - + { "ip", ETH_RSS_IP }, + { "udp", ETH_RSS_UDP }, + { "tcp", ETH_RSS_TCP }, + { "sctp", ETH_RSS_SCTP }, + { "tunnel", ETH_RSS_TUNNEL }, + { NULL, 0 }, }; static void @@ -1819,7 +1819,7 @@ port_rss_hash_conf_show(portid_t port_id, char rss_info[], int show_rss_key) } rss_conf.rss_hf = 0; - for (i = 0; i < RTE_DIM(rss_type_table); i++) { + for (i = 0; rss_type_table[i].str; i++) { if (!strcmp(rss_info, rss_type_table[i].str)) rss_conf.rss_hf = rss_type_table[i].rss_type; } @@ -1848,7 +1848,7 @@ port_rss_hash_conf_show(portid_t port_id, char rss_info[], int show_rss_key) return; } printf("RSS functions:\n "); - for (i = 0; i < RTE_DIM(rss_type_table); i++) { + for (i = 0; rss_type_table[i].str; i++) { if (rss_hf & rss_type_table[i].rss_type) printf("%s ", rss_type_table[i].str); } @@ -1872,7 +1872,7 @@ port_rss_hash_key_update(portid_t port_id, char rss_type[], uint8_t *hash_key, rss_conf.rss_key = NULL; rss_conf.rss_key_len = hash_key_len; rss_conf.rss_hf = 0; - for (i = 0; i < RTE_DIM(rss_type_table); i++) { + for (i = 0; rss_type_table[i].str; i++) { if (!strcmp(rss_type_table[i].str, rss_type)) rss_conf.rss_hf = rss_type_table[i].rss_type; } diff --git a/app/test-pmd/testpmd.h b/app/test-pmd/testpmd.h index 153abea05..593ae2160 100644 --- a/app/test-pmd/testpmd.h +++ b/app/test-pmd/testpmd.h @@ -79,6 +79,19 @@ struct pkt_burst_stats { }; #endif +/** Information for a given RSS type. */ +struct rss_type_info { + const char *str; /**< Type name. */ + uint64_t rss_type; /**< Type value. */ +}; + +/** + * RSS type information table. + * + * An entry with a NULL type name terminates the list. + */ +extern const struct rss_type_info rss_type_table[]; + /** * The data structure associated with a forwarding stream between a receive * port/queue and a transmit port/queue. diff --git a/doc/guides/testpmd_app_ug/testpmd_funcs.rst b/doc/guides/testpmd_app_ug/testpmd_funcs.rst index a766ac795..cb6f201e1 100644 --- a/doc/guides/testpmd_app_ug/testpmd_funcs.rst +++ b/doc/guides/testpmd_app_ug/testpmd_funcs.rst @@ -3406,6 +3406,14 @@ This section lists supported actions and their attributes, if any. - ``rss``: spread packets among several queues. + - ``types [{RSS hash type} [...]] end``: RSS hash types, allowed tokens + are the same as `set_hash_input_set`_, an empty list means none (0). + + - ``key {string}``: RSS hash key, overrides ``key_len``. + + - ``key_len {unsigned}``: RSS hash key length in bytes, can be used in + conjunction with ``key`` to pad or truncate it. + - ``queues [{unsigned} [...]] end``: queue indices to use. - ``pf``: redirect packets to physical device function. -- 2.14.2