diff options
Diffstat (limited to 'app/test-pmd/cmdline_flow.c')
-rw-r--r-- | app/test-pmd/cmdline_flow.c | 119 |
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; } |