diff options
authorAdrien Mazarguil <>2017-07-10 14:09:36 +0200
committerYuanhan Liu <>2017-08-29 14:50:28 +0800
commit5dac9b55e2795ee901cdb85b14a6c2705a550ab6 (patch)
parent9bc7ceefa22e6102a62baa810cb63739b0741f75 (diff)
app/testpmd: fix token matching in flow command
[ upstream commit a00cbb4586bdff936c81a9179a93b869c52e9b0c ] While matching user input against a token name or any other fixed string, comparison stops at the end of user input if shorter (e.g. "foo" matches token name "foobar"). Although the unintended consequence of this behavior allows users to abbreviate command names and various parameters yet generate valid commands, the parser was not designed to support this and does not prevent ambiguous tokens. For instance, entering "i" for a pattern item matches "ipv4", "ipv6" and "icmp" then defaults to one of them in an unspecified manner. Prevent this behavior by taking the length of fixed strings into account. Fixes: 19c90af6285c ("app/testpmd: add flow command") Fixes: 5ac3502ed1be ("app/testpmd: add flow query command") Fixes: abc3d81aca1b ("app/testpmd: add item raw to flow command") Fixes: 05d34c6e9d2c ("app/testpmd: add queue actions to flow command") Signed-off-by: Adrien Mazarguil <>
1 files changed, 17 insertions, 4 deletions
diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c
index dfff8be..4d47e79 100644
--- a/app/test-pmd/cmdline_flow.c
+++ b/app/test-pmd/cmdline_flow.c
@@ -1573,6 +1573,19 @@ arg_entry_bf_fill(void *dst, uintmax_t val, const struct arg *arg)
return len;
+/** Compare a string with a partial one of a given length. */
+static int
+strcmp_partial(const char *full, const char *partial, size_t partial_len)
+ int r = strncmp(full, partial, partial_len);
+ if (r)
+ return r;
+ if (strlen(full) <= partial_len)
+ return 0;
+ return full[partial_len];
* Parse a prefix length and generate a bit-mask.
@@ -1655,7 +1668,7 @@ parse_default(struct context *ctx, const struct token *token,
- if (strncmp(str, token->name, len))
+ if (strcmp_partial(token->name, str, len))
return -1;
return len;
@@ -1898,7 +1911,7 @@ parse_vc_action_rss_queue(struct context *ctx, const struct token *token,
if (ctx->curr != ACTION_RSS_QUEUE)
return -1;
i = ctx->objdata >> 16;
- if (!strncmp(str, "end", len)) {
+ if (!strcmp_partial("end", str, len)) {
ctx->objdata &= 0xffff;
return len;
@@ -2033,7 +2046,7 @@ parse_action(struct context *ctx, const struct token *token,
const struct parse_action_priv *priv;
token = &token_list[next_action[i]];
- if (strncmp(token->name, str, len))
+ if (strcmp_partial(token->name, str, len))
priv = token->priv;
if (!priv)
@@ -2373,7 +2386,7 @@ parse_boolean(struct context *ctx, const struct token *token,
if (!arg)
return -1;
for (i = 0; boolean_name[i]; ++i)
- if (!strncmp(str, boolean_name[i], len))
+ if (!strcmp_partial(boolean_name[i], str, len))
/* Process token as integer. */
if (boolean_name[i])