X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;ds=sidebyside;f=app%2Ftest-pmd%2Fcmdline_flow.c;h=df16d2ab90a3b289ae422e347cced3e8977ea11b;hb=0ef45a9ae8d5b3792afbb2e32103affaad22cbe4;hp=db680c6868570b13aca07067f87a15b1cf342d78;hpb=05d34c6e9d2cfd844147339263ef43556dc5c36a;p=dpdk.git diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c index db680c6868..df16d2ab90 100644 --- a/app/test-pmd/cmdline_flow.c +++ b/app/test-pmd/cmdline_flow.c @@ -39,6 +39,7 @@ #include #include #include +#include #include #include @@ -79,6 +80,7 @@ enum index { FLUSH, QUERY, LIST, + ISOLATE, /* Destroy arguments. */ DESTROY_RULE, @@ -126,10 +128,20 @@ enum index { ITEM_VLAN, ITEM_VLAN_TPID, ITEM_VLAN_TCI, + ITEM_VLAN_PCP, + ITEM_VLAN_DEI, + ITEM_VLAN_VID, ITEM_IPV4, + ITEM_IPV4_TOS, + ITEM_IPV4_TTL, + ITEM_IPV4_PROTO, ITEM_IPV4_SRC, ITEM_IPV4_DST, ITEM_IPV6, + ITEM_IPV6_TC, + ITEM_IPV6_FLOW, + ITEM_IPV6_PROTO, + ITEM_IPV6_HOP, ITEM_IPV6_SRC, ITEM_IPV6_DST, ITEM_ICMP, @@ -141,11 +153,28 @@ enum index { ITEM_TCP, ITEM_TCP_SRC, ITEM_TCP_DST, + ITEM_TCP_FLAGS, ITEM_SCTP, ITEM_SCTP_SRC, ITEM_SCTP_DST, + ITEM_SCTP_TAG, + ITEM_SCTP_CKSUM, ITEM_VXLAN, ITEM_VXLAN_VNI, + ITEM_E_TAG, + ITEM_E_TAG_GRP_ECID_B, + ITEM_NVGRE, + ITEM_NVGRE_TNI, + ITEM_MPLS, + ITEM_MPLS_LABEL, + ITEM_GRE, + ITEM_GRE_PROTO, + ITEM_FUZZY, + ITEM_FUZZY_THRESH, + ITEM_GTP, + ITEM_GTP_TEID, + ITEM_GTPC, + ITEM_GTPU, /* Validate/create actions. */ ACTIONS, @@ -169,6 +198,8 @@ enum index { ACTION_VF, ACTION_VF_ORIGINAL, ACTION_VF_ID, + ACTION_METER, + ACTION_METER_ID, }; /** Size of pattern[] field in struct rte_flow_item_raw. */ @@ -199,10 +230,9 @@ 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). */ + portid_t port; /**< Current port ID (for completions). */ uint32_t objdata; /**< Object-specific data. */ void *object; /**< Address of current object for relative offsets. */ void *objmask; /**< Object a full mask must be written to. */ @@ -281,6 +311,23 @@ struct token { .mask = (const void *)&(const s){ .f = (1 << (b)) - 1 }, \ }) +/** Static initializer for ARGS() to target an arbitrary bit-mask. */ +#define ARGS_ENTRY_MASK(s, f, m) \ + (&(const struct arg){ \ + .offset = offsetof(s, f), \ + .size = sizeof(((s *)0)->f), \ + .mask = (const void *)(m), \ + }) + +/** Same as ARGS_ENTRY_MASK() using network byte ordering for the value. */ +#define ARGS_ENTRY_MASK_HTON(s, f, m) \ + (&(const struct arg){ \ + .hton = 1, \ + .offset = offsetof(s, f), \ + .size = sizeof(((s *)0)->f), \ + .mask = (const void *)(m), \ + }) + /** Static initializer for ARGS() to target a pointer. */ #define ARGS_ENTRY_PTR(s, f) \ (&(const struct arg){ \ @@ -305,7 +352,7 @@ struct token { /** Parser output buffer layout expected by cmd_flow_parsed(). */ struct buffer { enum index command; /**< Flow command. */ - uint16_t port; /**< Affected port ID. */ + portid_t port; /**< Affected port ID. */ union { struct { struct rte_flow_attr attr; @@ -327,6 +374,9 @@ struct buffer { uint32_t *group; uint32_t group_n; } list; /**< List arguments. */ + struct { + int set; + } isolate; /**< Isolated mode arguments. */ } args; /**< Command arguments. */ }; @@ -402,6 +452,20 @@ static const enum index next_item[] = { ITEM_TCP, ITEM_SCTP, ITEM_VXLAN, + ITEM_E_TAG, + ITEM_NVGRE, + ITEM_MPLS, + ITEM_GRE, + ITEM_FUZZY, + ITEM_GTP, + ITEM_GTPC, + ITEM_GTPU, + ZERO, +}; + +static const enum index item_fuzzy[] = { + ITEM_FUZZY_THRESH, + ITEM_NEXT, ZERO, }; @@ -444,11 +508,17 @@ static const enum index item_eth[] = { static const enum index item_vlan[] = { ITEM_VLAN_TPID, ITEM_VLAN_TCI, + ITEM_VLAN_PCP, + ITEM_VLAN_DEI, + ITEM_VLAN_VID, ITEM_NEXT, ZERO, }; static const enum index item_ipv4[] = { + ITEM_IPV4_TOS, + ITEM_IPV4_TTL, + ITEM_IPV4_PROTO, ITEM_IPV4_SRC, ITEM_IPV4_DST, ITEM_NEXT, @@ -456,6 +526,10 @@ static const enum index item_ipv4[] = { }; static const enum index item_ipv6[] = { + ITEM_IPV6_TC, + ITEM_IPV6_FLOW, + ITEM_IPV6_PROTO, + ITEM_IPV6_HOP, ITEM_IPV6_SRC, ITEM_IPV6_DST, ITEM_NEXT, @@ -479,6 +553,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, }; @@ -486,6 +561,8 @@ static const enum index item_tcp[] = { static const enum index item_sctp[] = { ITEM_SCTP_SRC, ITEM_SCTP_DST, + ITEM_SCTP_TAG, + ITEM_SCTP_CKSUM, ITEM_NEXT, ZERO, }; @@ -496,6 +573,36 @@ static const enum index item_vxlan[] = { ZERO, }; +static const enum index item_e_tag[] = { + ITEM_E_TAG_GRP_ECID_B, + ITEM_NEXT, + ZERO, +}; + +static const enum index item_nvgre[] = { + ITEM_NVGRE_TNI, + ITEM_NEXT, + ZERO, +}; + +static const enum index item_mpls[] = { + ITEM_MPLS_LABEL, + ITEM_NEXT, + ZERO, +}; + +static const enum index item_gre[] = { + ITEM_GRE_PROTO, + ITEM_NEXT, + ZERO, +}; + +static const enum index item_gtp[] = { + ITEM_GTP_TEID, + ITEM_NEXT, + ZERO, +}; + static const enum index next_action[] = { ACTION_END, ACTION_VOID, @@ -509,6 +616,7 @@ static const enum index next_action[] = { ACTION_RSS, ACTION_PF, ACTION_VF, + ACTION_METER, ZERO, }; @@ -543,6 +651,12 @@ static const enum index action_vf[] = { ZERO, }; +static const enum index action_meter[] = { + ACTION_METER_ID, + ACTION_NEXT, + ZERO, +}; + static int parse_init(struct context *, const struct token *, const char *, unsigned int, void *, unsigned int); @@ -571,6 +685,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); @@ -717,7 +834,8 @@ static const struct token token_list[] = { DESTROY, FLUSH, LIST, - QUERY)), + QUERY, + ISOLATE)), .call = parse_init, }, /* Sub-level commands. */ @@ -767,6 +885,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", @@ -979,13 +1106,13 @@ static const struct token token_list[] = { .name = "dst", .help = "destination MAC", .next = NEXT(item_eth, NEXT_ENTRY(MAC_ADDR), item_param), - .args = ARGS(ARGS_ENTRY(struct rte_flow_item_eth, dst)), + .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_eth, dst)), }, [ITEM_ETH_SRC] = { .name = "src", .help = "source MAC", .next = NEXT(item_eth, NEXT_ENTRY(MAC_ADDR), item_param), - .args = ARGS(ARGS_ENTRY(struct rte_flow_item_eth, src)), + .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_eth, src)), }, [ITEM_ETH_TYPE] = { .name = "type", @@ -1012,6 +1139,27 @@ static const struct token token_list[] = { .next = NEXT(item_vlan, NEXT_ENTRY(UNSIGNED), item_param), .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_vlan, tci)), }, + [ITEM_VLAN_PCP] = { + .name = "pcp", + .help = "priority code point", + .next = NEXT(item_vlan, NEXT_ENTRY(UNSIGNED), item_param), + .args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_vlan, + tci, "\xe0\x00")), + }, + [ITEM_VLAN_DEI] = { + .name = "dei", + .help = "drop eligible indicator", + .next = NEXT(item_vlan, NEXT_ENTRY(UNSIGNED), item_param), + .args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_vlan, + tci, "\x10\x00")), + }, + [ITEM_VLAN_VID] = { + .name = "vid", + .help = "VLAN identifier", + .next = NEXT(item_vlan, NEXT_ENTRY(UNSIGNED), item_param), + .args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_vlan, + tci, "\x0f\xff")), + }, [ITEM_IPV4] = { .name = "ipv4", .help = "match IPv4 header", @@ -1019,6 +1167,27 @@ static const struct token token_list[] = { .next = NEXT(item_ipv4), .call = parse_vc, }, + [ITEM_IPV4_TOS] = { + .name = "tos", + .help = "type of service", + .next = NEXT(item_ipv4, NEXT_ENTRY(UNSIGNED), item_param), + .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv4, + hdr.type_of_service)), + }, + [ITEM_IPV4_TTL] = { + .name = "ttl", + .help = "time to live", + .next = NEXT(item_ipv4, NEXT_ENTRY(UNSIGNED), item_param), + .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv4, + hdr.time_to_live)), + }, + [ITEM_IPV4_PROTO] = { + .name = "proto", + .help = "next protocol ID", + .next = NEXT(item_ipv4, NEXT_ENTRY(UNSIGNED), item_param), + .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv4, + hdr.next_proto_id)), + }, [ITEM_IPV4_SRC] = { .name = "src", .help = "source address", @@ -1040,6 +1209,36 @@ static const struct token token_list[] = { .next = NEXT(item_ipv6), .call = parse_vc, }, + [ITEM_IPV6_TC] = { + .name = "tc", + .help = "traffic class", + .next = NEXT(item_ipv6, NEXT_ENTRY(UNSIGNED), item_param), + .args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_ipv6, + hdr.vtc_flow, + "\x0f\xf0\x00\x00")), + }, + [ITEM_IPV6_FLOW] = { + .name = "flow", + .help = "flow label", + .next = NEXT(item_ipv6, NEXT_ENTRY(UNSIGNED), item_param), + .args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_ipv6, + hdr.vtc_flow, + "\x00\x0f\xff\xff")), + }, + [ITEM_IPV6_PROTO] = { + .name = "proto", + .help = "protocol (next header)", + .next = NEXT(item_ipv6, NEXT_ENTRY(UNSIGNED), item_param), + .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv6, + hdr.proto)), + }, + [ITEM_IPV6_HOP] = { + .name = "hop", + .help = "hop limit", + .next = NEXT(item_ipv6, NEXT_ENTRY(UNSIGNED), item_param), + .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv6, + hdr.hop_limits)), + }, [ITEM_IPV6_SRC] = { .name = "src", .help = "source address", @@ -1117,6 +1316,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", @@ -1138,6 +1344,20 @@ static const struct token token_list[] = { .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_sctp, hdr.dst_port)), }, + [ITEM_SCTP_TAG] = { + .name = "tag", + .help = "validation tag", + .next = NEXT(item_sctp, NEXT_ENTRY(UNSIGNED), item_param), + .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_sctp, + hdr.tag)), + }, + [ITEM_SCTP_CKSUM] = { + .name = "cksum", + .help = "checksum", + .next = NEXT(item_sctp, NEXT_ENTRY(UNSIGNED), item_param), + .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_sctp, + hdr.cksum)), + }, [ITEM_VXLAN] = { .name = "vxlan", .help = "match VXLAN header", @@ -1151,6 +1371,106 @@ static const struct token token_list[] = { .next = NEXT(item_vxlan, NEXT_ENTRY(UNSIGNED), item_param), .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_vxlan, vni)), }, + [ITEM_E_TAG] = { + .name = "e_tag", + .help = "match E-Tag header", + .priv = PRIV_ITEM(E_TAG, sizeof(struct rte_flow_item_e_tag)), + .next = NEXT(item_e_tag), + .call = parse_vc, + }, + [ITEM_E_TAG_GRP_ECID_B] = { + .name = "grp_ecid_b", + .help = "GRP and E-CID base", + .next = NEXT(item_e_tag, NEXT_ENTRY(UNSIGNED), item_param), + .args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_e_tag, + rsvd_grp_ecid_b, + "\x3f\xff")), + }, + [ITEM_NVGRE] = { + .name = "nvgre", + .help = "match NVGRE header", + .priv = PRIV_ITEM(NVGRE, sizeof(struct rte_flow_item_nvgre)), + .next = NEXT(item_nvgre), + .call = parse_vc, + }, + [ITEM_NVGRE_TNI] = { + .name = "tni", + .help = "virtual subnet ID", + .next = NEXT(item_nvgre, NEXT_ENTRY(UNSIGNED), item_param), + .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_nvgre, tni)), + }, + [ITEM_MPLS] = { + .name = "mpls", + .help = "match MPLS header", + .priv = PRIV_ITEM(MPLS, sizeof(struct rte_flow_item_mpls)), + .next = NEXT(item_mpls), + .call = parse_vc, + }, + [ITEM_MPLS_LABEL] = { + .name = "label", + .help = "MPLS label", + .next = NEXT(item_mpls, NEXT_ENTRY(UNSIGNED), item_param), + .args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_mpls, + label_tc_s, + "\xff\xff\xf0")), + }, + [ITEM_GRE] = { + .name = "gre", + .help = "match GRE header", + .priv = PRIV_ITEM(GRE, sizeof(struct rte_flow_item_gre)), + .next = NEXT(item_gre), + .call = parse_vc, + }, + [ITEM_GRE_PROTO] = { + .name = "protocol", + .help = "GRE protocol type", + .next = NEXT(item_gre, NEXT_ENTRY(UNSIGNED), item_param), + .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)), + }, + [ITEM_GTP] = { + .name = "gtp", + .help = "match GTP header", + .priv = PRIV_ITEM(GTP, sizeof(struct rte_flow_item_gtp)), + .next = NEXT(item_gtp), + .call = parse_vc, + }, + [ITEM_GTP_TEID] = { + .name = "teid", + .help = "tunnel endpoint identifier", + .next = NEXT(item_gtp, NEXT_ENTRY(UNSIGNED), item_param), + .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_gtp, teid)), + }, + [ITEM_GTPC] = { + .name = "gtpc", + .help = "match GTP header", + .priv = PRIV_ITEM(GTPC, sizeof(struct rte_flow_item_gtp)), + .next = NEXT(item_gtp), + .call = parse_vc, + }, + [ITEM_GTPU] = { + .name = "gtpu", + .help = "match GTP header", + .priv = PRIV_ITEM(GTPU, sizeof(struct rte_flow_item_gtp)), + .next = NEXT(item_gtp), + .call = parse_vc, + }, + /* Validate/create actions. */ [ACTIONS] = { .name = "actions", @@ -1295,6 +1615,21 @@ static const struct token token_list[] = { .args = ARGS(ARGS_ENTRY(struct rte_flow_action_vf, id)), .call = parse_vc_conf, }, + [ACTION_METER] = { + .name = "meter", + .help = "meter the directed packets at given id", + .priv = PRIV_ACTION(METER, + sizeof(struct rte_flow_action_meter)), + .next = NEXT(action_meter), + .call = parse_vc, + }, + [ACTION_METER_ID] = { + .name = "mtr_id", + .help = "meter id to use", + .next = NEXT(action_meter, NEXT_ENTRY(UNSIGNED)), + .args = ARGS(ARGS_ENTRY(struct rte_flow_action_meter, mtr_id)), + .call = parse_vc_conf, + }, }; /** Remove and return last entry from argument stack. */ @@ -1353,6 +1688,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. * @@ -1435,7 +1783,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; } @@ -1587,6 +1935,8 @@ parse_vc_spec(struct context *ctx, const struct token *token, return -1; /* Parse parameter types. */ switch (ctx->curr) { + static const enum index prefix[] = NEXT_ENTRY(PREFIX); + case ITEM_PARAM_IS: index = 0; objmask = 1; @@ -1601,7 +1951,7 @@ parse_vc_spec(struct context *ctx, const struct token *token, /* Modify next token to expect a prefix. */ if (ctx->next_num < 2) return -1; - ctx->next[ctx->next_num - 2] = NEXT_ENTRY(PREFIX); + ctx->next[ctx->next_num - 2] = prefix; /* Fall through. */ case ITEM_PARAM_MASK: index = 2; @@ -1676,7 +2026,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; } @@ -1811,7 +2161,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) @@ -1864,6 +2214,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. * @@ -2015,6 +2392,9 @@ parse_mac_addr(struct context *ctx, const struct token *token, /* Bit-mask fill is not supported. */ if (arg->mask || size != sizeof(tmp)) goto error; + /* Only network endian is supported. */ + if (!arg->hton) + goto error; ret = cmdline_parse_etheraddr(NULL, str, &tmp, size); if (ret < 0 || (unsigned int)ret != len) goto error; @@ -2148,7 +2528,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]) @@ -2241,7 +2621,7 @@ comp_port(struct context *ctx, const struct token *token, (void)ctx; (void)token; - FOREACH_PORT(p, ports) { + RTE_ETH_FOREACH_DEV(p) { if (buf && i == ent) return snprintf(buf, size, "%u", p); ++i; @@ -2262,7 +2642,7 @@ comp_rule_id(struct context *ctx, const struct token *token, (void)token; if (port_id_is_invalid(ctx->port, DISABLED_WARN) || - ctx->port == (uint16_t)RTE_PORT_ALL) + ctx->port == (portid_t)RTE_PORT_ALL) return -1; port = &ports[ctx->port]; for (pf = port->flow_list; pf != NULL; pf = pf->next) { @@ -2308,7 +2688,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; @@ -2329,9 +2708,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; @@ -2407,8 +2783,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]; @@ -2442,8 +2816,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]; @@ -2478,8 +2850,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. */ @@ -2505,12 +2875,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) { @@ -2560,6 +2930,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; }