From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-wr0-f196.google.com (mail-wr0-f196.google.com [209.85.128.196]) by dpdk.org (Postfix) with ESMTP id CE9D77EB0 for ; Thu, 19 Apr 2018 12:07:54 +0200 (CEST) Received: by mail-wr0-f196.google.com with SMTP id w3-v6so12430207wrg.2 for ; Thu, 19 Apr 2018 03:07: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=PUkBCAHt1UeQWaUQ0eRMV3akFelS46twejHIkqZ8Mmc=; b=t+2Dfd2u2b9TvIFwUW53D9R2mMFkGfFcx6c6i7ue8xoMDvYTS1VHCxQqKLLH6LacpQ 3Dvsexv/d4j2fj3Sl2Gbq7dpfKQt6j1J2xZvI/g9BiPjt0MbPR5iGnYyBiBV/JzYzEQK JPFKAWLHE5O4lyVYWNtGc3FN9j3iZbPrbWW3AfjLQFhjMXWkiavMylAdbzjFajNIj9qB QTLT2D7EybBSzWerZb1PWSFtXZFMxrjo+jgwZ/GXCUADNC4tuZGhijiGTBu+4izwtGhM nFk+uij0tcJRzgD9IVB6mgITjwDcHKyM0sn/b3HmLyPPygE2XhMFqOw8C5JbGJr/xXQH 9VWg== 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=PUkBCAHt1UeQWaUQ0eRMV3akFelS46twejHIkqZ8Mmc=; b=BPi0larQiSAO9xhpPIfu9z9PiP48f69pEbO6eqUivgjPzqzwTmeWBFSEg3dYsLYMGE hTdWtwhxqLFzEnHsX7ijOKeCZPGyKEW9rAzdy6PDrdquoGQjcb9yY8YDXTOpYTsZAMUs Vt63Q4Qjvc4fmPhanciXvxicdeKEy721QXnVUQAn5AeiBX1ZF5eL+sgUF93b0O9lcRP0 0srHV8ZgdFzhzxInEb6LQ71a/0TRpjv1Jp7670s6M2CJTO4S2N3D+0hukmrDK3c8NDZs 0oCFGr1newtmFPRau8EBUbhXxoGKBEEKKCWgBWAwiuPyoFTupT8LDXtXiWEg8pcKgVov 1VWw== X-Gm-Message-State: ALQs6tA6jUOG13iAUI4Ig2h2rI8tej9nh/2pfFHMsdTa166/hM99YWHI zbWmEccNUU3r/w9UR5xyFRaI9+HT X-Google-Smtp-Source: AIpwx48RP/OAbzZJjgOEFCZONkopPRZfvQU6S0ImIBmXZrN/2BxwPclUUHUnx77k/VQWiEq/CmqqYw== X-Received: by 2002:adf:8861:: with SMTP id e30-v6mr4099835wre.252.1524132474237; Thu, 19 Apr 2018 03:07: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 133sm4536609wms.8.2018.04.19.03.07.53 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 19 Apr 2018 03:07:53 -0700 (PDT) Date: Thu, 19 Apr 2018 12:07:40 +0200 From: Adrien Mazarguil To: dev@dpdk.org Cc: stable@dpdk.org, Wenzhuo Lu , Jingjing Wu Message-ID: <20180419100204.5728-9-adrien.mazarguil@6wind.com> References: <20180416150058.2620-1-adrien.mazarguil@6wind.com> <20180419100204.5728-1-adrien.mazarguil@6wind.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20180419100204.5728-1-adrien.mazarguil@6wind.com> X-Mailer: git-send-email 2.11.0 Subject: [dpdk-dev] [PATCH v6 08/11] app/testpmd: fix missing RSS fields in flow action 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: Thu, 19 Apr 2018 10:07:54 -0000 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") Cc: stable@dpdk.org Signed-off-by: Adrien Mazarguil Acked-by: Nelio Laranjeiro Cc: Wenzhuo Lu Cc: Jingjing Wu --- 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 d37c5f39f..fcd76b56e 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", @@ -2076,6 +2138,50 @@ parse_vc_action_rss(struct context *ctx, const struct token *token, } /** + * 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. * * Valid tokens are queue indices and the "end" token. @@ -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 97a959b2a..5daa93bb3 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 @@ -1835,7 +1835,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; } @@ -1864,7 +1864,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); } @@ -1888,7 +1888,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 98d84da84..070919822 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.11.0