aboutsummaryrefslogtreecommitdiffstats
path: root/app/test-pmd/cmdline_flow.c
diff options
context:
space:
mode:
Diffstat (limited to 'app/test-pmd/cmdline_flow.c')
-rw-r--r--app/test-pmd/cmdline_flow.c119
1 files changed, 101 insertions, 18 deletions
diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c
index 0fd69f90..a17a0043 100644
--- a/app/test-pmd/cmdline_flow.c
+++ b/app/test-pmd/cmdline_flow.c
@@ -80,6 +80,7 @@ enum index {
FLUSH,
QUERY,
LIST,
+ ISOLATE,
/* Destroy arguments. */
DESTROY_RULE,
@@ -152,6 +153,7 @@ enum index {
ITEM_TCP,
ITEM_TCP_SRC,
ITEM_TCP_DST,
+ ITEM_TCP_FLAGS,
ITEM_SCTP,
ITEM_SCTP_SRC,
ITEM_SCTP_DST,
@@ -167,6 +169,8 @@ enum index {
ITEM_MPLS_LABEL,
ITEM_GRE,
ITEM_GRE_PROTO,
+ ITEM_FUZZY,
+ ITEM_FUZZY_THRESH,
/* Validate/create actions. */
ACTIONS,
@@ -220,7 +224,6 @@ struct context {
enum index prev; /**< Index of the last token seen. */
int next_num; /**< Number of entries in next[]. */
int args_num; /**< Number of entries in args[]. */
- uint32_t reparse:1; /**< Start over from the beginning. */
uint32_t eol:1; /**< EOL has been detected. */
uint32_t last:1; /**< No more arguments. */
uint16_t port; /**< Current port ID (for completions). */
@@ -365,6 +368,9 @@ struct buffer {
uint32_t *group;
uint32_t group_n;
} list; /**< List arguments. */
+ struct {
+ int set;
+ } isolate; /**< Isolated mode arguments. */
} args; /**< Command arguments. */
};
@@ -444,6 +450,13 @@ static const enum index next_item[] = {
ITEM_NVGRE,
ITEM_MPLS,
ITEM_GRE,
+ ITEM_FUZZY,
+ ZERO,
+};
+
+static const enum index item_fuzzy[] = {
+ ITEM_FUZZY_THRESH,
+ ITEM_NEXT,
ZERO,
};
@@ -531,6 +544,7 @@ static const enum index item_udp[] = {
static const enum index item_tcp[] = {
ITEM_TCP_SRC,
ITEM_TCP_DST,
+ ITEM_TCP_FLAGS,
ITEM_NEXT,
ZERO,
};
@@ -649,6 +663,9 @@ static int parse_action(struct context *, const struct token *,
static int parse_list(struct context *, const struct token *,
const char *, unsigned int,
void *, unsigned int);
+static int parse_isolate(struct context *, const struct token *,
+ const char *, unsigned int,
+ void *, unsigned int);
static int parse_int(struct context *, const struct token *,
const char *, unsigned int,
void *, unsigned int);
@@ -795,7 +812,8 @@ static const struct token token_list[] = {
DESTROY,
FLUSH,
LIST,
- QUERY)),
+ QUERY,
+ ISOLATE)),
.call = parse_init,
},
/* Sub-level commands. */
@@ -845,6 +863,15 @@ static const struct token token_list[] = {
.args = ARGS(ARGS_ENTRY(struct buffer, port)),
.call = parse_list,
},
+ [ISOLATE] = {
+ .name = "isolate",
+ .help = "restrict ingress traffic to the defined flow rules",
+ .next = NEXT(NEXT_ENTRY(BOOLEAN),
+ NEXT_ENTRY(PORT_ID)),
+ .args = ARGS(ARGS_ENTRY(struct buffer, args.isolate.set),
+ ARGS_ENTRY(struct buffer, port)),
+ .call = parse_isolate,
+ },
/* Destroy arguments. */
[DESTROY_RULE] = {
.name = "rule",
@@ -1267,6 +1294,13 @@ static const struct token token_list[] = {
.args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_tcp,
hdr.dst_port)),
},
+ [ITEM_TCP_FLAGS] = {
+ .name = "flags",
+ .help = "TCP flags",
+ .next = NEXT(item_tcp, NEXT_ENTRY(UNSIGNED), item_param),
+ .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_tcp,
+ hdr.tcp_flags)),
+ },
[ITEM_SCTP] = {
.name = "sctp",
.help = "match SCTP header",
@@ -1372,6 +1406,22 @@ static const struct token token_list[] = {
.args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_gre,
protocol)),
},
+ [ITEM_FUZZY] = {
+ .name = "fuzzy",
+ .help = "fuzzy pattern match, expect faster than default",
+ .priv = PRIV_ITEM(FUZZY,
+ sizeof(struct rte_flow_item_fuzzy)),
+ .next = NEXT(item_fuzzy),
+ .call = parse_vc,
+ },
+ [ITEM_FUZZY_THRESH] = {
+ .name = "thresh",
+ .help = "match accuracy threshold",
+ .next = NEXT(item_fuzzy, NEXT_ENTRY(UNSIGNED), item_param),
+ .args = ARGS(ARGS_ENTRY(struct rte_flow_item_fuzzy,
+ thresh)),
+ },
+
/* Validate/create actions. */
[ACTIONS] = {
.name = "actions",
@@ -1574,6 +1624,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.
*
@@ -1656,7 +1719,7 @@ parse_default(struct context *ctx, const struct token *token,
(void)ctx;
(void)buf;
(void)size;
- if (strncmp(str, token->name, len))
+ if (strcmp_partial(token->name, str, len))
return -1;
return len;
}
@@ -1899,7 +1962,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;
}
@@ -2034,7 +2097,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))
continue;
priv = token->priv;
if (!priv)
@@ -2087,6 +2150,33 @@ parse_list(struct context *ctx, const struct token *token,
return len;
}
+/** Parse tokens for isolate command. */
+static int
+parse_isolate(struct context *ctx, const struct token *token,
+ const char *str, unsigned int len,
+ void *buf, unsigned int size)
+{
+ struct buffer *out = buf;
+
+ /* Token name must match. */
+ if (parse_default(ctx, token, str, len, NULL, 0) < 0)
+ return -1;
+ /* Nothing else to do if there is no buffer. */
+ if (!out)
+ return len;
+ if (!out->command) {
+ if (ctx->curr != ISOLATE)
+ return -1;
+ if (sizeof(*out) > size)
+ return -1;
+ out->command = ctx->curr;
+ ctx->objdata = 0;
+ ctx->object = out;
+ ctx->objmask = NULL;
+ }
+ return len;
+}
+
/**
* Parse signed/unsigned integers 8 to 64-bit long.
*
@@ -2374,7 +2464,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))
break;
/* Process token as integer. */
if (boolean_name[i])
@@ -2534,7 +2624,6 @@ cmd_flow_context_init(struct context *ctx)
ctx->prev = ZERO;
ctx->next_num = 0;
ctx->args_num = 0;
- ctx->reparse = 0;
ctx->eol = 0;
ctx->last = 0;
ctx->port = 0;
@@ -2555,9 +2644,6 @@ cmd_flow_parse(cmdline_parse_token_hdr_t *hdr, const char *src, void *result,
int i;
(void)hdr;
- /* Restart as requested. */
- if (ctx->reparse)
- cmd_flow_context_init(ctx);
token = &token_list[ctx->curr];
/* Check argument length. */
ctx->eol = 0;
@@ -2633,8 +2719,6 @@ cmd_flow_complete_get_nb(cmdline_parse_token_hdr_t *hdr)
int i;
(void)hdr;
- /* Tell cmd_flow_parse() that context must be reinitialized. */
- ctx->reparse = 1;
/* Count number of tokens in current list. */
if (ctx->next_num)
list = ctx->next[ctx->next_num - 1];
@@ -2668,8 +2752,6 @@ cmd_flow_complete_get_elt(cmdline_parse_token_hdr_t *hdr, int index,
int i;
(void)hdr;
- /* Tell cmd_flow_parse() that context must be reinitialized. */
- ctx->reparse = 1;
/* Count number of tokens in current list. */
if (ctx->next_num)
list = ctx->next[ctx->next_num - 1];
@@ -2704,8 +2786,6 @@ cmd_flow_get_help(cmdline_parse_token_hdr_t *hdr, char *dst, unsigned int size)
const struct token *token = &token_list[ctx->prev];
(void)hdr;
- /* Tell cmd_flow_parse() that context must be reinitialized. */
- ctx->reparse = 1;
if (!size)
return -1;
/* Set token type and update global help with details. */
@@ -2731,12 +2811,12 @@ static struct cmdline_token_hdr cmd_flow_token_hdr = {
/** Populate the next dynamic token. */
static void
cmd_flow_tok(cmdline_parse_token_hdr_t **hdr,
- cmdline_parse_token_hdr_t *(*hdrs)[])
+ cmdline_parse_token_hdr_t **hdr_inst)
{
struct context *ctx = &cmd_flow_context;
/* Always reinitialize context before requesting the first token. */
- if (!(hdr - *hdrs))
+ if (!(hdr_inst - cmd_flow.tokens))
cmd_flow_context_init(ctx);
/* Return NULL when no more tokens are expected. */
if (!ctx->next_num && ctx->curr) {
@@ -2786,6 +2866,9 @@ cmd_flow_parsed(const struct buffer *in)
port_flow_list(in->port, in->args.list.group_n,
in->args.list.group);
break;
+ case ISOLATE:
+ port_flow_isolate(in->port, in->args.isolate.set);
+ break;
default:
break;
}