[dpdk-dev] [PATCH 3/3] lib/cmdline: Cross platform fixes for cmdline_flow
Georgios Katsikas
george.dit at gmail.com
Fri Jan 12 22:01:27 CET 2018
Signed-off-by: Georgios Katsikas <george.dit at gmail.com>
---
app/test-pmd/Makefile | 2 +
app/test-pmd/cmdline.c | 4 +
app/test-pmd/testpmd.h | 14 -
lib/librte_cmdline/Makefile | 3 +
lib/librte_cmdline/cmdline_flow.c | 555 ++++++--------------------------
lib/librte_cmdline/cmdline_flow.h | 653 +++++++++++++++++++++++++++++++-------
lib/librte_ether/rte_flow.c | 4 +-
lib/librte_ether/rte_flow.h | 10 -
8 files changed, 640 insertions(+), 605 deletions(-)
diff --git a/app/test-pmd/Makefile b/app/test-pmd/Makefile
index ec48773..26de9f3 100644
--- a/app/test-pmd/Makefile
+++ b/app/test-pmd/Makefile
@@ -38,6 +38,8 @@ endif
ifeq ($(CONFIG_RTE_BUILD_SHARED_LIB),y)
+LDLIBS += -lrte_cmdline
+
ifeq ($(CONFIG_RTE_LIBRTE_PMD_BOND),y)
LDLIBS += -lrte_pmd_bond
endif
diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c
index 5b2e2ef..d1c6428 100644
--- a/app/test-pmd/cmdline.c
+++ b/app/test-pmd/cmdline.c
@@ -10921,7 +10921,11 @@ cmdline_parse_inst_t cmd_set_flow_director_flex_payload = {
};
/* Generic flow interface command. */
+#ifdef RTE_BUILD_SHARED_LIB
+cmdline_parse_inst_t cmd_flow;
+#else
extern cmdline_parse_inst_t cmd_flow;
+#endif
/* *** Classification Filters Control *** */
/* *** Get symmetric hash enable per port *** */
diff --git a/app/test-pmd/testpmd.h b/app/test-pmd/testpmd.h
index 303a9ec..71da7ef 100644
--- a/app/test-pmd/testpmd.h
+++ b/app/test-pmd/testpmd.h
@@ -498,20 +498,6 @@ void port_reg_bit_field_set(portid_t port_id, uint32_t reg_off,
uint8_t bit1_pos, uint8_t bit2_pos, uint32_t value);
void port_reg_display(portid_t port_id, uint32_t reg_off);
void port_reg_set(portid_t port_id, uint32_t reg_off, uint32_t value);
-int port_flow_validate(portid_t port_id,
- const struct rte_flow_attr *attr,
- const struct rte_flow_item *pattern,
- const struct rte_flow_action *actions);
-int port_flow_create(portid_t port_id,
- const struct rte_flow_attr *attr,
- const struct rte_flow_item *pattern,
- const struct rte_flow_action *actions);
-int port_flow_destroy(portid_t port_id, uint32_t n, const uint32_t *rule);
-int port_flow_flush(portid_t port_id);
-int port_flow_query(portid_t port_id, uint32_t rule,
- enum rte_flow_action_type action);
-void port_flow_list(portid_t port_id, uint32_t n, const uint32_t *group);
-int port_flow_isolate(portid_t port_id, int set);
void rx_ring_desc_display(portid_t port_id, queueid_t rxq_id, uint16_t rxd_id);
void tx_ring_desc_display(portid_t port_id, queueid_t txq_id, uint16_t txd_id);
diff --git a/lib/librte_cmdline/Makefile b/lib/librte_cmdline/Makefile
index cf46b22..475b1f7 100644
--- a/lib/librte_cmdline/Makefile
+++ b/lib/librte_cmdline/Makefile
@@ -28,6 +28,9 @@ SRCS-$(CONFIG_RTE_LIBRTE_CMDLINE) += cmdline_parse_portlist.c
CFLAGS += -D_GNU_SOURCE
LDLIBS += -lrte_eal
+ifeq ($(CONFIG_RTE_BUILD_SHARED_LIB),y)
+LDLIBS += -lrte_ethdev
+endif
# install includes
INCS := cmdline.h cmdline_parse.h cmdline_parse_num.h cmdline_parse_ipaddr.h
diff --git a/lib/librte_cmdline/cmdline_flow.c b/lib/librte_cmdline/cmdline_flow.c
index b43c10f..e4a8230 100644
--- a/lib/librte_cmdline/cmdline_flow.c
+++ b/lib/librte_cmdline/cmdline_flow.c
@@ -43,21 +43,6 @@
#include "cmdline_flow.h"
-int
-port_id_is_invalid(portid_t port_id, enum print_warning warning)
-{
- if (port_id == (portid_t)RTE_PORT_ALL)
- return 0;
-
- if (rte_eth_dev_is_valid_port(port_id))
- return 0;
-
- if (warning == ENABLED_WARN)
- printf("Invalid port %d\n", port_id);
-
- return 1;
-}
-
/** Remove and return last entry from argument stack. */
const struct arg *
pop_args(struct context *ctx)
@@ -134,7 +119,7 @@ strcmp_partial(const char *full, const char *partial, size_t partial_len)
* location and whether the result must use network byte ordering.
*/
int
-parse_prefix(struct context *ctx, const struct token *token,
+cmd_parse_prefix(struct context *ctx, const struct token *token,
const char *str, unsigned int len,
void *buf, unsigned int size)
{
@@ -202,7 +187,7 @@ parse_prefix(struct context *ctx, const struct token *token,
/** Default parsing function for token name matching. */
int
-parse_default(struct context *ctx, const struct token *token,
+cmd_parse_default(struct context *ctx, const struct token *token,
const char *str, unsigned int len,
void *buf, unsigned int size)
{
@@ -216,14 +201,14 @@ parse_default(struct context *ctx, const struct token *token,
/** Parse flow command, initialize output buffer for subsequent tokens. */
int
-parse_init(struct context *ctx, const struct token *token,
+cmd_parse_init(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)
+ if (cmd_parse_default(ctx, token, str, len, NULL, 0) < 0)
return -1;
/* Nothing else to do if there is no buffer. */
if (!out)
@@ -242,7 +227,7 @@ parse_init(struct context *ctx, const struct token *token,
/** Parse tokens for validate/create commands. */
int
-parse_vc(struct context *ctx, const struct token *token,
+cmd_parse_vc(struct context *ctx, const struct token *token,
const char *str, unsigned int len,
void *buf, unsigned int size)
{
@@ -251,7 +236,7 @@ parse_vc(struct context *ctx, const struct token *token,
uint32_t data_size;
/* Token name must match. */
- if (parse_default(ctx, token, str, len, NULL, 0) < 0)
+ if (cmd_parse_default(ctx, token, str, len, NULL, 0) < 0)
return -1;
/* Nothing else to do if there is no buffer. */
if (!out)
@@ -345,7 +330,7 @@ parse_vc(struct context *ctx, const struct token *token,
/** Parse pattern item parameter type. */
int
-parse_vc_spec(struct context *ctx, const struct token *token,
+cmd_parse_vc_spec(struct context *ctx, const struct token *token,
const char *str, unsigned int len,
void *buf, unsigned int size)
{
@@ -357,7 +342,7 @@ parse_vc_spec(struct context *ctx, const struct token *token,
(void)size;
/* Token name must match. */
- if (parse_default(ctx, token, str, len, NULL, 0) < 0)
+ if (cmd_parse_default(ctx, token, str, len, NULL, 0) < 0)
return -1;
/* Parse parameter types. */
switch (ctx->curr) {
@@ -407,7 +392,7 @@ parse_vc_spec(struct context *ctx, const struct token *token,
/** Parse action configuration field. */
int
-parse_vc_conf(struct context *ctx, const struct token *token,
+cmd_parse_vc_conf(struct context *ctx, const struct token *token,
const char *str, unsigned int len,
void *buf, unsigned int size)
{
@@ -416,7 +401,7 @@ parse_vc_conf(struct context *ctx, const struct token *token,
(void)size;
/* Token name must match. */
- if (parse_default(ctx, token, str, len, NULL, 0) < 0)
+ if (cmd_parse_default(ctx, token, str, len, NULL, 0) < 0)
return -1;
/* Nothing else to do if there is no buffer. */
if (!out)
@@ -438,7 +423,7 @@ parse_vc_conf(struct context *ctx, const struct token *token,
* Valid tokens are queue indices and the "end" token.
*/
int
-parse_vc_action_rss_queue(struct context *ctx, const struct token *token,
+cmd_parse_vc_action_rss_queue(struct context *ctx, const struct token *token,
const char *str, unsigned int len,
void *buf, unsigned int size)
{
@@ -460,7 +445,7 @@ parse_vc_action_rss_queue(struct context *ctx, const struct token *token,
return -1;
if (push_args(ctx, ARGS_ENTRY(struct rte_flow_action_rss, queue[i])))
return -1;
- ret = parse_int(ctx, token, str, len, NULL, 0);
+ ret = cmd_parse_int(ctx, token, str, len, NULL, 0);
if (ret < 0) {
pop_args(ctx);
return -1;
@@ -479,14 +464,14 @@ parse_vc_action_rss_queue(struct context *ctx, const struct token *token,
/** Parse tokens for destroy command. */
int
-parse_destroy(struct context *ctx, const struct token *token,
+cmd_parse_destroy(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)
+ if (cmd_parse_default(ctx, token, str, len, NULL, 0) < 0)
return -1;
/* Nothing else to do if there is no buffer. */
if (!out)
@@ -516,14 +501,14 @@ parse_destroy(struct context *ctx, const struct token *token,
/** Parse tokens for flush command. */
int
-parse_flush(struct context *ctx, const struct token *token,
+cmd_parse_flush(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)
+ if (cmd_parse_default(ctx, token, str, len, NULL, 0) < 0)
return -1;
/* Nothing else to do if there is no buffer. */
if (!out)
@@ -543,14 +528,14 @@ parse_flush(struct context *ctx, const struct token *token,
/** Parse tokens for query command. */
int
-parse_query(struct context *ctx, const struct token *token,
+cmd_parse_query(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)
+ if (cmd_parse_default(ctx, token, str, len, NULL, 0) < 0)
return -1;
/* Nothing else to do if there is no buffer. */
if (!out)
@@ -570,7 +555,7 @@ parse_query(struct context *ctx, const struct token *token,
/** Parse action names. */
int
-parse_action(struct context *ctx, const struct token *token,
+cmd_parse_action(struct context *ctx, const struct token *token,
const char *str, unsigned int len,
void *buf, unsigned int size)
{
@@ -605,14 +590,14 @@ parse_action(struct context *ctx, const struct token *token,
/** Parse tokens for list command. */
int
-parse_list(struct context *ctx, const struct token *token,
+cmd_parse_list(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)
+ if (cmd_parse_default(ctx, token, str, len, NULL, 0) < 0)
return -1;
/* Nothing else to do if there is no buffer. */
if (!out)
@@ -642,14 +627,14 @@ parse_list(struct context *ctx, const struct token *token,
/** Parse tokens for isolate command. */
int
-parse_isolate(struct context *ctx, const struct token *token,
+cmd_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)
+ if (cmd_parse_default(ctx, token, str, len, NULL, 0) < 0)
return -1;
/* Nothing else to do if there is no buffer. */
if (!out)
@@ -674,7 +659,7 @@ parse_isolate(struct context *ctx, const struct token *token,
* storage location.
*/
int
-parse_int(struct context *ctx, const struct token *token,
+cmd_parse_int(struct context *ctx, const struct token *token,
const char *str, unsigned int len,
void *buf, unsigned int size)
{
@@ -750,7 +735,7 @@ parse_int(struct context *ctx, const struct token *token,
* its length (in that order).
*/
int
-parse_string(struct context *ctx, const struct token *token,
+cmd_parse_string(struct context *ctx, const struct token *token,
const char *str, unsigned int len,
void *buf, unsigned int size)
{
@@ -772,12 +757,12 @@ parse_string(struct context *ctx, const struct token *token,
goto error;
if (!ctx->object)
return len;
- /* Let parse_int() fill length information first. */
+ /* Let cmd_parse_int() fill length information first. */
ret = snprintf(tmp, sizeof(tmp), "%u", len);
if (ret < 0)
goto error;
push_args(ctx, arg_len);
- ret = parse_int(ctx, token, tmp, ret, NULL, 0);
+ ret = cmd_parse_int(ctx, token, tmp, ret, NULL, 0);
if (ret < 0) {
pop_args(ctx);
goto error;
@@ -802,7 +787,7 @@ parse_string(struct context *ctx, const struct token *token,
* location.
*/
int
-parse_mac_addr(struct context *ctx, const struct token *token,
+cmd_parse_mac_addr(struct context *ctx, const struct token *token,
const char *str, unsigned int len,
void *buf, unsigned int size)
{
@@ -843,7 +828,7 @@ parse_mac_addr(struct context *ctx, const struct token *token,
* location.
*/
int
-parse_ipv4_addr(struct context *ctx, const struct token *token,
+cmd_parse_ipv4_addr(struct context *ctx, const struct token *token,
const char *str, unsigned int len,
void *buf, unsigned int size)
{
@@ -868,7 +853,7 @@ parse_ipv4_addr(struct context *ctx, const struct token *token,
if (ret != 1) {
/* Attempt integer parsing. */
push_args(ctx, arg);
- return parse_int(ctx, token, str, len, buf, size);
+ return cmd_parse_int(ctx, token, str, len, buf, size);
}
if (!ctx->object)
return len;
@@ -889,7 +874,7 @@ parse_ipv4_addr(struct context *ctx, const struct token *token,
* location.
*/
int
-parse_ipv6_addr(struct context *ctx, const struct token *token,
+cmd_parse_ipv6_addr(struct context *ctx, const struct token *token,
const char *str, unsigned int len,
void *buf, unsigned int size)
{
@@ -942,7 +927,7 @@ static const char *const boolean_name[] = {
* location.
*/
int
-parse_boolean(struct context *ctx, const struct token *token,
+cmd_parse_boolean(struct context *ctx, const struct token *token,
const char *str, unsigned int len,
void *buf, unsigned int size)
{
@@ -960,13 +945,13 @@ parse_boolean(struct context *ctx, const struct token *token,
if (boolean_name[i])
str = i & 1 ? "1" : "0";
push_args(ctx, arg);
- ret = parse_int(ctx, token, str, strlen(str), buf, size);
+ ret = cmd_parse_int(ctx, token, str, strlen(str), buf, size);
return ret > 0 ? (int)len : ret;
}
/** Parse port and update context. */
int
-parse_port(struct context *ctx, const struct token *token,
+cmd_parse_port(struct context *ctx, const struct token *token,
const char *str, unsigned int len,
void *buf, unsigned int size)
{
@@ -981,7 +966,7 @@ parse_port(struct context *ctx, const struct token *token,
ctx->objmask = NULL;
size = sizeof(*out);
}
- ret = parse_int(ctx, token, str, len, out, size);
+ ret = cmd_parse_int(ctx, token, str, len, out, size);
if (ret >= 0)
ctx->port = out->port;
if (!buf)
@@ -1102,9 +1087,6 @@ comp_vc_action_rss_queue(struct context *ctx, const struct token *token,
/** Internal context. */
static struct context cmd_flow_context;
-/** Global parser instance (cmdline API). */
-cmdline_parse_inst_t cmd_flow;
-
/** Initialize context. */
void
cmd_flow_context_init(struct context *ctx)
@@ -1173,7 +1155,7 @@ cmd_flow_parse(cmdline_parse_token_hdr_t *hdr, const char *src, void *result,
if (next->call)
tmp = next->call(ctx, next, src, len, result, size);
else
- tmp = parse_default(ctx, next, src, len, result, size);
+ tmp = cmd_parse_default(ctx, next, src, len, result, size);
if (tmp == -1 || tmp != len)
continue;
token = next;
@@ -1328,6 +1310,64 @@ cmd_flow_tok(cmdline_parse_token_hdr_t **hdr,
*hdr = &cmd_flow_token_hdr;
}
+/* Generic flow management functions. */
+
+/** Compute storage space needed by item specification. */
+void
+flow_item_spec_size(const struct rte_flow_item *item,
+ size_t *size, size_t *pad)
+{
+ if (!item->spec) {
+ *size = 0;
+ goto empty;
+ }
+ switch (item->type) {
+ union {
+ const struct rte_flow_item_raw *raw;
+ } spec;
+
+ /* Not a fall-through */
+ case RTE_FLOW_ITEM_TYPE_RAW:
+ spec.raw = item->spec;
+ *size = offsetof(struct rte_flow_item_raw, pattern) +
+ spec.raw->length * sizeof(*spec.raw->pattern);
+ break;
+ default:
+ *size = flow_item[item->type].size;
+ break;
+ }
+empty:
+ *pad = RTE_ALIGN_CEIL(*size, sizeof(double)) - *size;
+}
+
+/** Compute storage space needed by action configuration. */
+void
+flow_action_conf_size(const struct rte_flow_action *action,
+ size_t *size, size_t *pad)
+{
+ if (!action->conf) {
+ *size = 0;
+ goto empty;
+ }
+ switch (action->type) {
+ union {
+ const struct rte_flow_action_rss *rss;
+ } conf;
+
+ /* Not a fall-through. */
+ case RTE_FLOW_ACTION_TYPE_RSS:
+ conf.rss = action->conf;
+ *size = offsetof(struct rte_flow_action_rss, queue) +
+ conf.rss->num * sizeof(*conf.rss->queue);
+ break;
+ default:
+ *size = flow_action[action->type].size;
+ break;
+ }
+empty:
+ *pad = RTE_ALIGN_CEIL(*size, sizeof(double)) - *size;
+}
+
/** Dispatch parsed buffer to function calls. */
void
cmd_flow_parsed(const struct buffer *in)
@@ -1374,7 +1414,7 @@ cmd_flow_cb(void *arg0, struct cmdline *cl, void *arg2)
cmd_flow_parsed(arg0);
}
-/** Global parser instance (cmdline API). */
+/** Global parser instance (properly initialized). */
cmdline_parse_inst_t cmd_flow = {
.f = cmd_flow_cb,
.data = NULL, /**< Unused. */
@@ -1383,408 +1423,3 @@ cmdline_parse_inst_t cmd_flow = {
NULL,
}, /**< Tokens are returned by cmd_flow_tok(). */
};
-
-/* Generic flow management functions. */
-
-/** Generate a port_flow entry from attributes/pattern/actions. */
-static struct port_flow *
-port_flow_new(const struct rte_flow_attr *attr,
- const struct rte_flow_item *pattern,
- const struct rte_flow_action *actions)
-{
- const struct rte_flow_item *item;
- const struct rte_flow_action *action;
- struct port_flow *pf = NULL;
- size_t tmp;
- size_t pad;
- size_t off1 = 0;
- size_t off2 = 0;
- int err = ENOTSUP;
-
-store:
- item = pattern;
- if (pf)
- pf->pattern = (void *)&pf->data[off1];
- do {
- struct rte_flow_item *dst = NULL;
-
- if ((unsigned int)item->type >= RTE_DIM(flow_item) ||
- !flow_item[item->type].name)
- goto notsup;
- if (pf)
- dst = memcpy(pf->data + off1, item, sizeof(*item));
- off1 += sizeof(*item);
- flow_item_spec_size(item, &tmp, &pad);
- if (item->spec) {
- if (pf)
- dst->spec = memcpy(pf->data + off2,
- item->spec, tmp);
- off2 += tmp + pad;
- }
- if (item->last) {
- if (pf)
- dst->last = memcpy(pf->data + off2,
- item->last, tmp);
- off2 += tmp + pad;
- }
- if (item->mask) {
- if (pf)
- dst->mask = memcpy(pf->data + off2,
- item->mask, tmp);
- off2 += tmp + pad;
- }
- off2 = RTE_ALIGN_CEIL(off2, sizeof(double));
- } while ((item++)->type != RTE_FLOW_ITEM_TYPE_END);
- off1 = RTE_ALIGN_CEIL(off1, sizeof(double));
- action = actions;
- if (pf)
- pf->actions = (void *)&pf->data[off1];
- do {
- struct rte_flow_action *dst = NULL;
-
- if ((unsigned int)action->type >= RTE_DIM(flow_action) ||
- !flow_action[action->type].name)
- goto notsup;
- if (pf)
- dst = memcpy(pf->data + off1, action, sizeof(*action));
- off1 += sizeof(*action);
- flow_action_conf_size(action, &tmp, &pad);
- if (action->conf) {
- if (pf)
- dst->conf = memcpy(pf->data + off2,
- action->conf, tmp);
- off2 += tmp + pad;
- }
- off2 = RTE_ALIGN_CEIL(off2, sizeof(double));
- } while ((action++)->type != RTE_FLOW_ACTION_TYPE_END);
- if (pf != NULL)
- return pf;
- off1 = RTE_ALIGN_CEIL(off1, sizeof(double));
- tmp = RTE_ALIGN_CEIL(offsetof(struct port_flow, data), sizeof(double));
- pf = calloc(1, tmp + off1 + off2);
- if (pf == NULL)
- err = errno;
- else {
- *pf = (const struct port_flow){
- .size = tmp + off1 + off2,
- .attr = *attr,
- };
- tmp -= offsetof(struct port_flow, data);
- off2 = tmp + off1;
- off1 = tmp;
- goto store;
- }
-notsup:
- rte_errno = err;
- return NULL;
-}
-
-/** Print a message out of a flow error. */
-static int
-port_flow_complain(struct rte_flow_error *error)
-{
- static const char *const errstrlist[] = {
- [RTE_FLOW_ERROR_TYPE_NONE] = "no error",
- [RTE_FLOW_ERROR_TYPE_UNSPECIFIED] = "cause unspecified",
- [RTE_FLOW_ERROR_TYPE_HANDLE] = "flow rule (handle)",
- [RTE_FLOW_ERROR_TYPE_ATTR_GROUP] = "group field",
- [RTE_FLOW_ERROR_TYPE_ATTR_PRIORITY] = "priority field",
- [RTE_FLOW_ERROR_TYPE_ATTR_INGRESS] = "ingress field",
- [RTE_FLOW_ERROR_TYPE_ATTR_EGRESS] = "egress field",
- [RTE_FLOW_ERROR_TYPE_ATTR] = "attributes structure",
- [RTE_FLOW_ERROR_TYPE_ITEM_NUM] = "pattern length",
- [RTE_FLOW_ERROR_TYPE_ITEM] = "specific pattern item",
- [RTE_FLOW_ERROR_TYPE_ACTION_NUM] = "number of actions",
- [RTE_FLOW_ERROR_TYPE_ACTION] = "specific action",
- };
- const char *errstr;
- char buf[32];
- int err = rte_errno;
-
- if ((unsigned int)error->type >= RTE_DIM(errstrlist) ||
- !errstrlist[error->type])
- errstr = "unknown type";
- else
- errstr = errstrlist[error->type];
- printf("Caught error type %d (%s): %s%s\n",
- error->type, errstr,
- error->cause ? (snprintf(buf, sizeof(buf), "cause: %p, ",
- error->cause), buf) : "",
- error->message ? error->message : "(no stated reason)");
- return -err;
-}
-
-/** Validate flow rule. */
-int
-port_flow_validate(portid_t port_id,
- const struct rte_flow_attr *attr,
- const struct rte_flow_item *pattern,
- const struct rte_flow_action *actions)
-{
- struct rte_flow_error error;
-
- /* Poisoning to make sure PMDs update it in case of error. */
- memset(&error, 0x11, sizeof(error));
- if (rte_flow_validate(port_id, attr, pattern, actions, &error))
- return port_flow_complain(&error);
- printf("Flow rule validated\n");
- return 0;
-}
-
-/** Create flow rule. */
-int
-port_flow_create(portid_t port_id,
- const struct rte_flow_attr *attr,
- const struct rte_flow_item *pattern,
- const struct rte_flow_action *actions)
-{
- struct rte_flow *flow;
- struct rte_port *port;
- struct port_flow *pf;
- uint32_t id;
- struct rte_flow_error error;
-
- /* Poisoning to make sure PMDs update it in case of error. */
- memset(&error, 0x22, sizeof(error));
- flow = rte_flow_create(port_id, attr, pattern, actions, &error);
- if (!flow)
- return port_flow_complain(&error);
- port = &ports[port_id];
- if (port->flow_list) {
- if (port->flow_list->id == UINT32_MAX) {
- printf("Highest rule ID is already assigned, delete"
- " it first");
- rte_flow_destroy(port_id, flow, NULL);
- return -ENOMEM;
- }
- id = port->flow_list->id + 1;
- } else
- id = 0;
- pf = port_flow_new(attr, pattern, actions);
- if (!pf) {
- int err = rte_errno;
-
- printf("Cannot allocate flow: %s\n", rte_strerror(err));
- rte_flow_destroy(port_id, flow, NULL);
- return -err;
- }
- pf->next = port->flow_list;
- pf->id = id;
- pf->flow = flow;
- port->flow_list = pf;
- printf("Flow rule #%u created\n", pf->id);
- return 0;
-}
-
-/** Destroy a number of flow rules. */
-int
-port_flow_destroy(portid_t port_id, uint32_t n, const uint32_t *rule)
-{
- struct rte_port *port;
- struct port_flow **tmp;
- uint32_t c = 0;
- int ret = 0;
-
- if (port_id_is_invalid(port_id, ENABLED_WARN) ||
- port_id == (portid_t)RTE_PORT_ALL)
- return -EINVAL;
- port = &ports[port_id];
- tmp = &port->flow_list;
- while (*tmp) {
- uint32_t i;
-
- for (i = 0; i != n; ++i) {
- struct rte_flow_error error;
- struct port_flow *pf = *tmp;
-
- if (rule[i] != pf->id)
- continue;
- /*
- * Poisoning to make sure PMDs update it in case
- * of error.
- */
- memset(&error, 0x33, sizeof(error));
- if (rte_flow_destroy(port_id, pf->flow, &error)) {
- ret = port_flow_complain(&error);
- continue;
- }
- printf("Flow rule #%u destroyed\n", pf->id);
- *tmp = pf->next;
- free(pf);
- break;
- }
- if (i == n)
- tmp = &(*tmp)->next;
- ++c;
- }
- return ret;
-}
-
-/** Remove all flow rules. */
-int
-port_flow_flush(portid_t port_id)
-{
- struct rte_flow_error error;
- struct rte_port *port;
- int ret = 0;
-
- /* Poisoning to make sure PMDs update it in case of error. */
- memset(&error, 0x44, sizeof(error));
- if (rte_flow_flush(port_id, &error)) {
- ret = port_flow_complain(&error);
- if (port_id_is_invalid(port_id, DISABLED_WARN) ||
- port_id == (portid_t)RTE_PORT_ALL)
- return ret;
- }
- port = &ports[port_id];
- while (port->flow_list) {
- struct port_flow *pf = port->flow_list->next;
-
- free(port->flow_list);
- port->flow_list = pf;
- }
- return ret;
-}
-
-/** Query a flow rule. */
-int
-port_flow_query(portid_t port_id, uint32_t rule,
- enum rte_flow_action_type action)
-{
- struct rte_flow_error error;
- struct rte_port *port;
- struct port_flow *pf;
- const char *name;
- union {
- struct rte_flow_query_count count;
- } query;
-
- if (port_id_is_invalid(port_id, ENABLED_WARN) ||
- port_id == (portid_t)RTE_PORT_ALL)
- return -EINVAL;
- port = &ports[port_id];
- for (pf = port->flow_list; pf; pf = pf->next)
- if (pf->id == rule)
- break;
- if (!pf) {
- printf("Flow rule #%u not found\n", rule);
- return -ENOENT;
- }
- if ((unsigned int)action >= RTE_DIM(flow_action) ||
- !flow_action[action].name)
- name = "unknown";
- else
- name = flow_action[action].name;
- switch (action) {
- case RTE_FLOW_ACTION_TYPE_COUNT:
- break;
- default:
- printf("Cannot query action type %d (%s)\n", action, name);
- return -ENOTSUP;
- }
- /* Poisoning to make sure PMDs update it in case of error. */
- memset(&error, 0x55, sizeof(error));
- memset(&query, 0, sizeof(query));
- if (rte_flow_query(port_id, pf->flow, action, &query, &error))
- return port_flow_complain(&error);
- switch (action) {
- case RTE_FLOW_ACTION_TYPE_COUNT:
- printf("%s:\n"
- " hits_set: %u\n"
- " bytes_set: %u\n"
- " hits: %" PRIu64 "\n"
- " bytes: %" PRIu64 "\n",
- name,
- query.count.hits_set,
- query.count.bytes_set,
- query.count.hits,
- query.count.bytes);
- break;
- default:
- printf("Cannot display result for action type %d (%s)\n",
- action, name);
- break;
- }
- return 0;
-}
-
-/** List flow rules. */
-void
-port_flow_list(portid_t port_id, uint32_t n, const uint32_t group[n])
-{
- struct rte_port *port;
- struct port_flow *pf;
- struct port_flow *list = NULL;
- uint32_t i;
-
- if (port_id_is_invalid(port_id, ENABLED_WARN) ||
- port_id == (portid_t)RTE_PORT_ALL)
- return;
- port = &ports[port_id];
- if (!port->flow_list)
- return;
- /* Sort flows by group, priority and ID. */
- for (pf = port->flow_list; pf != NULL; pf = pf->next) {
- struct port_flow **tmp;
-
- if (n) {
- /* Filter out unwanted groups. */
- for (i = 0; i != n; ++i)
- if (pf->attr.group == group[i])
- break;
- if (i == n)
- continue;
- }
- tmp = &list;
- while (*tmp &&
- (pf->attr.group > (*tmp)->attr.group ||
- (pf->attr.group == (*tmp)->attr.group &&
- pf->attr.priority > (*tmp)->attr.priority) ||
- (pf->attr.group == (*tmp)->attr.group &&
- pf->attr.priority == (*tmp)->attr.priority &&
- pf->id > (*tmp)->id)))
- tmp = &(*tmp)->tmp;
- pf->tmp = *tmp;
- *tmp = pf;
- }
- printf("ID\tGroup\tPrio\tAttr\tRule\n");
- for (pf = list; pf != NULL; pf = pf->tmp) {
- const struct rte_flow_item *item = pf->pattern;
- const struct rte_flow_action *action = pf->actions;
-
- printf("%" PRIu32 "\t%" PRIu32 "\t%" PRIu32 "\t%c%c\t",
- pf->id,
- pf->attr.group,
- pf->attr.priority,
- pf->attr.ingress ? 'i' : '-',
- pf->attr.egress ? 'e' : '-');
- while (item->type != RTE_FLOW_ITEM_TYPE_END) {
- if (item->type != RTE_FLOW_ITEM_TYPE_VOID)
- printf("%s ", flow_item[item->type].name);
- ++item;
- }
- printf("=>");
- while (action->type != RTE_FLOW_ACTION_TYPE_END) {
- if (action->type != RTE_FLOW_ACTION_TYPE_VOID)
- printf(" %s", flow_action[action->type].name);
- ++action;
- }
- printf("\n");
- }
-}
-
-/** Restrict ingress traffic to the defined flow rules. */
-int
-port_flow_isolate(portid_t port_id, int set)
-{
- struct rte_flow_error error;
-
- /* Poisoning to make sure PMDs update it in case of error. */
- memset(&error, 0x66, sizeof(error));
- if (rte_flow_isolate(port_id, set, &error))
- return port_flow_complain(&error);
- printf("Ingress traffic on port %u is %s to the defined flow rules\n",
- port_id,
- set ? "now restricted" : "not restricted anymore");
- return 0;
-}
diff --git a/lib/librte_cmdline/cmdline_flow.h b/lib/librte_cmdline/cmdline_flow.h
index 7066254..9cb8045 100644
--- a/lib/librte_cmdline/cmdline_flow.h
+++ b/lib/librte_cmdline/cmdline_flow.h
@@ -814,8 +814,21 @@ static const struct {
};
/** Helper functions for parsing. */
-int port_id_is_invalid(portid_t port_id,
- enum print_warning warning);
+inline int
+port_id_is_invalid(portid_t port_id, enum print_warning warning)
+{
+ if (port_id == (portid_t)RTE_PORT_ALL)
+ return 0;
+
+ if (rte_eth_dev_is_valid_port(port_id))
+ return 0;
+
+ if (warning == ENABLED_WARN)
+ printf("Invalid port %d\n", port_id);
+
+ return 1;
+}
+
const struct arg *pop_args(struct context *ctx);
int push_args(struct context *ctx,
const struct arg *arg);
@@ -823,68 +836,75 @@ size_t arg_entry_bf_fill(void *dst, uintmax_t val,
const struct arg *arg);
int strcmp_partial(const char *full,
const char *partial, size_t partial_len);
+/** Compute storage space needed by item specification. */
+void flow_item_spec_size(const struct rte_flow_item *item,
+ size_t *size, size_t *pad);
+
+/** Compute storage space needed by action configuration. */
+void flow_action_conf_size(const struct rte_flow_action *action,
+ size_t *size, size_t *pad);
/** Parsing functions. */
-int parse_prefix(struct context *, const struct token *,
+int cmd_parse_prefix(struct context *, const struct token *,
const char *, unsigned int,
void *, unsigned int);
-int parse_default(struct context *ctx,
+int cmd_parse_default(struct context *ctx,
const struct token *token,
const char *str, unsigned int len,
void *buf, unsigned int size);
-int parse_init(struct context *, const struct token *,
+int cmd_parse_init(struct context *, const struct token *,
const char *, unsigned int,
void *, unsigned int);
-int parse_vc(struct context *, const struct token *,
+int cmd_parse_vc(struct context *, const struct token *,
const char *, unsigned int,
void *, unsigned int);
-int parse_vc_spec(struct context *, const struct token *,
+int cmd_parse_vc_spec(struct context *, const struct token *,
const char *, unsigned int, void *,
unsigned int);
-int parse_vc_conf(struct context *, const struct token *,
+int cmd_parse_vc_conf(struct context *, const struct token *,
const char *, unsigned int, void *,
unsigned int);
-int parse_vc_action_rss_queue(struct context *,
+int cmd_parse_vc_action_rss_queue(struct context *,
const struct token *,
const char *, unsigned int, void *,
unsigned int);
-int parse_destroy(struct context *, const struct token *,
+int cmd_parse_destroy(struct context *, const struct token *,
const char *, unsigned int,
void *, unsigned int);
-int parse_flush(struct context *, const struct token *,
+int cmd_parse_flush(struct context *, const struct token *,
const char *, unsigned int,
void *, unsigned int);
-int parse_query(struct context *, const struct token *,
+int cmd_parse_query(struct context *, const struct token *,
const char *, unsigned int,
void *, unsigned int);
-int parse_action(struct context *, const struct token *,
+int cmd_parse_action(struct context *, const struct token *,
const char *, unsigned int,
void *, unsigned int);
-int parse_list(struct context *, const struct token *,
+int cmd_parse_list(struct context *, const struct token *,
const char *, unsigned int,
void *, unsigned int);
-int parse_isolate(struct context *, const struct token *,
+int cmd_parse_isolate(struct context *, const struct token *,
const char *, unsigned int,
void *, unsigned int);
-int parse_int(struct context *, const struct token *,
+int cmd_parse_int(struct context *, const struct token *,
const char *, unsigned int,
void *, unsigned int);
-int parse_string(struct context *, const struct token *,
+int cmd_parse_string(struct context *, const struct token *,
const char *, unsigned int,
void *, unsigned int);
-int parse_mac_addr(struct context *, const struct token *,
+int cmd_parse_mac_addr(struct context *, const struct token *,
const char *, unsigned int,
void *, unsigned int);
-int parse_ipv4_addr(struct context *, const struct token *,
+int cmd_parse_ipv4_addr(struct context *, const struct token *,
const char *, unsigned int,
void *, unsigned int);
-int parse_ipv6_addr(struct context *, const struct token *,
+int cmd_parse_ipv6_addr(struct context *, const struct token *,
const char *, unsigned int,
void *, unsigned int);
-int parse_boolean(struct context *, const struct token *,
+int cmd_parse_boolean(struct context *, const struct token *,
const char *, unsigned int,
void *, unsigned int);
-int parse_port(struct context *, const struct token *,
+int cmd_parse_port(struct context *, const struct token *,
const char *, unsigned int,
void *, unsigned int);
@@ -920,23 +940,418 @@ void cmd_flow_tok(cmdline_parse_token_hdr_t **hdr,
void cmd_flow_parsed(const struct buffer *in);
void cmd_flow_cb(void *arg0, struct cmdline *cl, void *arg2);
-/** Generic flow management functions. */
-int port_flow_validate(portid_t port_id,
- const struct rte_flow_attr *attr,
- const struct rte_flow_item *pattern,
- const struct rte_flow_action *actions);
-int port_flow_create(portid_t port_id,
- const struct rte_flow_attr *attr,
- const struct rte_flow_item *pattern,
- const struct rte_flow_action *actions);
-int port_flow_destroy(portid_t port_id, uint32_t n,
- const uint32_t *rule);
-int port_flow_flush(portid_t port_id);
-int port_flow_query(portid_t port_id, uint32_t rule,
- enum rte_flow_action_type action);
-void port_flow_list(portid_t port_id, uint32_t n,
- const uint32_t *group);
-int port_flow_isolate(portid_t port_id, int set);
+/**
+ * Generic flow management functions.
+ *
+ * Allow the creation, validation, insertion, query,
+ * list, and deletion of a NIC's flows.
+ */
+
+/** Generate a port_flow entry from attributes/pattern/actions. */
+static inline struct port_flow *
+port_flow_new(const struct rte_flow_attr *attr,
+ const struct rte_flow_item *pattern,
+ const struct rte_flow_action *actions)
+{
+ const struct rte_flow_item *item;
+ const struct rte_flow_action *action;
+ struct port_flow *pf = NULL;
+ size_t tmp;
+ size_t pad;
+ size_t off1 = 0;
+ size_t off2 = 0;
+ int err = ENOTSUP;
+
+store:
+ item = pattern;
+ if (pf)
+ pf->pattern = (void *)&pf->data[off1];
+ do {
+ struct rte_flow_item *dst = NULL;
+
+ if ((unsigned int)item->type >= RTE_DIM(flow_item) ||
+ !flow_item[item->type].name)
+ goto notsup;
+ if (pf)
+ dst = memcpy(pf->data + off1, item, sizeof(*item));
+ off1 += sizeof(*item);
+ flow_item_spec_size(item, &tmp, &pad);
+ if (item->spec) {
+ if (pf)
+ dst->spec = memcpy(pf->data + off2,
+ item->spec, tmp);
+ off2 += tmp + pad;
+ }
+ if (item->last) {
+ if (pf)
+ dst->last = memcpy(pf->data + off2,
+ item->last, tmp);
+ off2 += tmp + pad;
+ }
+ if (item->mask) {
+ if (pf)
+ dst->mask = memcpy(pf->data + off2,
+ item->mask, tmp);
+ off2 += tmp + pad;
+ }
+ off2 = RTE_ALIGN_CEIL(off2, sizeof(double));
+ } while ((item++)->type != RTE_FLOW_ITEM_TYPE_END);
+ off1 = RTE_ALIGN_CEIL(off1, sizeof(double));
+ action = actions;
+ if (pf)
+ pf->actions = (void *)&pf->data[off1];
+ do {
+ struct rte_flow_action *dst = NULL;
+
+ if ((unsigned int)action->type >= RTE_DIM(flow_action) ||
+ !flow_action[action->type].name)
+ goto notsup;
+ if (pf)
+ dst = memcpy(pf->data + off1, action, sizeof(*action));
+ off1 += sizeof(*action);
+ flow_action_conf_size(action, &tmp, &pad);
+ if (action->conf) {
+ if (pf)
+ dst->conf = memcpy(pf->data + off2,
+ action->conf, tmp);
+ off2 += tmp + pad;
+ }
+ off2 = RTE_ALIGN_CEIL(off2, sizeof(double));
+ } while ((action++)->type != RTE_FLOW_ACTION_TYPE_END);
+ if (pf != NULL)
+ return pf;
+ off1 = RTE_ALIGN_CEIL(off1, sizeof(double));
+ tmp = RTE_ALIGN_CEIL(offsetof(struct port_flow, data), sizeof(double));
+ pf = calloc(1, tmp + off1 + off2);
+ if (pf == NULL)
+ err = errno;
+ else {
+ *pf = (const struct port_flow){
+ .size = tmp + off1 + off2,
+ .attr = *attr,
+ };
+ tmp -= offsetof(struct port_flow, data);
+ off2 = tmp + off1;
+ off1 = tmp;
+ goto store;
+ }
+notsup:
+ rte_errno = err;
+ return NULL;
+}
+
+/** Print a message out of a flow error. */
+inline int
+port_flow_complain(struct rte_flow_error *error)
+{
+ static const char *const errstrlist[] = {
+ [RTE_FLOW_ERROR_TYPE_NONE] = "no error",
+ [RTE_FLOW_ERROR_TYPE_UNSPECIFIED] = "cause unspecified",
+ [RTE_FLOW_ERROR_TYPE_HANDLE] = "flow rule (handle)",
+ [RTE_FLOW_ERROR_TYPE_ATTR_GROUP] = "group field",
+ [RTE_FLOW_ERROR_TYPE_ATTR_PRIORITY] = "priority field",
+ [RTE_FLOW_ERROR_TYPE_ATTR_INGRESS] = "ingress field",
+ [RTE_FLOW_ERROR_TYPE_ATTR_EGRESS] = "egress field",
+ [RTE_FLOW_ERROR_TYPE_ATTR] = "attributes structure",
+ [RTE_FLOW_ERROR_TYPE_ITEM_NUM] = "pattern length",
+ [RTE_FLOW_ERROR_TYPE_ITEM] = "specific pattern item",
+ [RTE_FLOW_ERROR_TYPE_ACTION_NUM] = "number of actions",
+ [RTE_FLOW_ERROR_TYPE_ACTION] = "specific action",
+ };
+ const char *errstr;
+ char buf[32];
+ int err = rte_errno;
+
+ if ((unsigned int)error->type >= RTE_DIM(errstrlist) ||
+ !errstrlist[error->type])
+ errstr = "unknown type";
+ else
+ errstr = errstrlist[error->type];
+ printf("Caught error type %d (%s): %s%s\n",
+ error->type, errstr,
+ error->cause ? (snprintf(buf, sizeof(buf), "cause: %p, ",
+ error->cause), buf) : "",
+ error->message ? error->message : "(no stated reason)");
+ return -err;
+}
+
+/** Validate flow rule. */
+inline int
+port_flow_validate(portid_t port_id,
+ const struct rte_flow_attr *attr,
+ const struct rte_flow_item *pattern,
+ const struct rte_flow_action *actions)
+{
+ struct rte_flow_error error;
+
+ /* Poisoning to make sure PMDs update it in case of error. */
+ memset(&error, 0x11, sizeof(error));
+ if (rte_flow_validate(port_id, attr, pattern, actions, &error))
+ return port_flow_complain(&error);
+ printf("Flow rule validated\n");
+ return 0;
+}
+
+/** Create flow rule. */
+static inline int
+port_flow_create(portid_t port_id,
+ const struct rte_flow_attr *attr,
+ const struct rte_flow_item *pattern,
+ const struct rte_flow_action *actions)
+{
+ struct rte_flow *flow;
+ struct rte_port *port;
+ struct port_flow *pf;
+ uint32_t id;
+ struct rte_flow_error error;
+
+ /* Poisoning to make sure PMDs update it in case of error. */
+ memset(&error, 0x22, sizeof(error));
+ flow = rte_flow_create(port_id, attr, pattern, actions, &error);
+ if (!flow)
+ return port_flow_complain(&error);
+ port = &ports[port_id];
+ if (port->flow_list) {
+ if (port->flow_list->id == UINT32_MAX) {
+ printf("Highest rule ID is already assigned, delete"
+ " it first");
+ rte_flow_destroy(port_id, flow, NULL);
+ return -ENOMEM;
+ }
+ id = port->flow_list->id + 1;
+ } else
+ id = 0;
+ pf = port_flow_new(attr, pattern, actions);
+ if (!pf) {
+ int err = rte_errno;
+
+ printf("Cannot allocate flow: %s\n", rte_strerror(err));
+ rte_flow_destroy(port_id, flow, NULL);
+ return -err;
+ }
+ pf->next = port->flow_list;
+ pf->id = id;
+ pf->flow = flow;
+ port->flow_list = pf;
+ printf("Flow rule #%u created\n", pf->id);
+ return 0;
+}
+
+/** Destroy a number of flow rules. */
+inline int
+port_flow_destroy(portid_t port_id, uint32_t n, const uint32_t *rule)
+{
+ struct rte_port *port;
+ struct port_flow **tmp;
+ uint32_t c = 0;
+ int ret = 0;
+
+ if (port_id_is_invalid(port_id, ENABLED_WARN) ||
+ port_id == (portid_t)RTE_PORT_ALL)
+ return -EINVAL;
+ port = &ports[port_id];
+ tmp = &port->flow_list;
+ while (*tmp) {
+ uint32_t i;
+
+ for (i = 0; i != n; ++i) {
+ struct rte_flow_error error;
+ struct port_flow *pf = *tmp;
+
+ if (rule[i] != pf->id)
+ continue;
+ /*
+ * Poisoning to make sure PMDs update it in case
+ * of error.
+ */
+ memset(&error, 0x33, sizeof(error));
+ if (rte_flow_destroy(port_id, pf->flow, &error)) {
+ ret = port_flow_complain(&error);
+ continue;
+ }
+ printf("Flow rule #%u destroyed\n", pf->id);
+ *tmp = pf->next;
+ free(pf);
+ break;
+ }
+ if (i == n)
+ tmp = &(*tmp)->next;
+ ++c;
+ }
+ return ret;
+}
+
+/** Remove all flow rules. */
+inline int
+port_flow_flush(portid_t port_id)
+{
+ struct rte_flow_error error;
+ struct rte_port *port;
+ int ret = 0;
+
+ /* Poisoning to make sure PMDs update it in case of error. */
+ memset(&error, 0x44, sizeof(error));
+ if (rte_flow_flush(port_id, &error)) {
+ ret = port_flow_complain(&error);
+ if (port_id_is_invalid(port_id, DISABLED_WARN) ||
+ port_id == (portid_t)RTE_PORT_ALL)
+ return ret;
+ }
+ port = &ports[port_id];
+ while (port->flow_list) {
+ struct port_flow *pf = port->flow_list->next;
+
+ free(port->flow_list);
+ port->flow_list = pf;
+ }
+ return ret;
+}
+
+/** Query a flow rule. */
+static inline int
+port_flow_query(portid_t port_id, uint32_t rule,
+ enum rte_flow_action_type action)
+{
+ struct rte_flow_error error;
+ struct rte_port *port;
+ struct port_flow *pf;
+ const char *name;
+ union {
+ struct rte_flow_query_count count;
+ } query;
+
+ if (port_id_is_invalid(port_id, ENABLED_WARN) ||
+ port_id == (portid_t)RTE_PORT_ALL)
+ return -EINVAL;
+ port = &ports[port_id];
+ for (pf = port->flow_list; pf; pf = pf->next)
+ if (pf->id == rule)
+ break;
+ if (!pf) {
+ printf("Flow rule #%u not found\n", rule);
+ return -ENOENT;
+ }
+ if ((unsigned int)action >= RTE_DIM(flow_action) ||
+ !flow_action[action].name)
+ name = "unknown";
+ else
+ name = flow_action[action].name;
+ switch (action) {
+ case RTE_FLOW_ACTION_TYPE_COUNT:
+ break;
+ default:
+ printf("Cannot query action type %d (%s)\n", action, name);
+ return -ENOTSUP;
+ }
+ /* Poisoning to make sure PMDs update it in case of error. */
+ memset(&error, 0x55, sizeof(error));
+ memset(&query, 0, sizeof(query));
+ if (rte_flow_query(port_id, pf->flow, action, &query, &error))
+ return port_flow_complain(&error);
+ switch (action) {
+ case RTE_FLOW_ACTION_TYPE_COUNT:
+ printf("%s:\n"
+ " hits_set: %u\n"
+ " bytes_set: %u\n"
+ " hits: %" PRIu64 "\n"
+ " bytes: %" PRIu64 "\n",
+ name,
+ query.count.hits_set,
+ query.count.bytes_set,
+ query.count.hits,
+ query.count.bytes);
+ break;
+ default:
+ printf("Cannot display result for action type %d (%s)\n",
+ action, name);
+ break;
+ }
+ return 0;
+}
+
+/** List flow rules. */
+static inline void
+port_flow_list(portid_t port_id, uint32_t n, const uint32_t group[n])
+{
+ struct rte_port *port;
+ struct port_flow *pf;
+ struct port_flow *list = NULL;
+ uint32_t i;
+
+ if (port_id_is_invalid(port_id, ENABLED_WARN) ||
+ port_id == (portid_t)RTE_PORT_ALL)
+ return;
+ port = &ports[port_id];
+ if (!port->flow_list)
+ return;
+ /* Sort flows by group, priority and ID. */
+ for (pf = port->flow_list; pf != NULL; pf = pf->next) {
+ struct port_flow **tmp;
+
+ if (n) {
+ /* Filter out unwanted groups. */
+ for (i = 0; i != n; ++i)
+ if (pf->attr.group == group[i])
+ break;
+ if (i == n)
+ continue;
+ }
+ tmp = &list;
+ while (*tmp &&
+ (pf->attr.group > (*tmp)->attr.group ||
+ (pf->attr.group == (*tmp)->attr.group &&
+ pf->attr.priority > (*tmp)->attr.priority) ||
+ (pf->attr.group == (*tmp)->attr.group &&
+ pf->attr.priority == (*tmp)->attr.priority &&
+ pf->id > (*tmp)->id)))
+ tmp = &(*tmp)->tmp;
+ pf->tmp = *tmp;
+ *tmp = pf;
+ }
+ printf("ID\tGroup\tPrio\tAttr\tRule\n");
+ for (pf = list; pf != NULL; pf = pf->tmp) {
+ const struct rte_flow_item *item = pf->pattern;
+ const struct rte_flow_action *action = pf->actions;
+
+ printf("%" PRIu32 "\t%" PRIu32 "\t%" PRIu32 "\t%c%c\t",
+ pf->id,
+ pf->attr.group,
+ pf->attr.priority,
+ pf->attr.ingress ? 'i' : '-',
+ pf->attr.egress ? 'e' : '-');
+ while (item->type != RTE_FLOW_ITEM_TYPE_END) {
+ if (item->type != RTE_FLOW_ITEM_TYPE_VOID)
+ printf("%s ", flow_item[item->type].name);
+ ++item;
+ }
+ printf("=>");
+ while (action->type != RTE_FLOW_ACTION_TYPE_END) {
+ if (action->type != RTE_FLOW_ACTION_TYPE_VOID)
+ printf(" %s", flow_action[action->type].name);
+ ++action;
+ }
+ printf("\n");
+ }
+}
+
+/** Restrict ingress traffic to the defined flow rules. */
+inline int
+port_flow_isolate(portid_t port_id, int set)
+{
+ struct rte_flow_error error;
+
+ /* Poisoning to make sure PMDs update it in case of error. */
+ memset(&error, 0x66, sizeof(error));
+ if (rte_flow_isolate(port_id, set, &error))
+ return port_flow_complain(&error);
+ printf("Ingress traffic on port %u is %s to the defined flow rules\n",
+ port_id,
+ set ? "now restricted" : "not restricted anymore");
+ return 0;
+}
+
+/** Global parser instance (cmdline API). */
+extern cmdline_parse_inst_t cmd_flow;
/** Token definitions. */
static const struct token token_list[] = {
@@ -956,84 +1371,84 @@ static const struct token token_list[] = {
.name = "{int}",
.type = "INTEGER",
.help = "integer value",
- .call = parse_int,
+ .call = cmd_parse_int,
.comp = comp_none,
},
[UNSIGNED] = {
.name = "{unsigned}",
.type = "UNSIGNED",
.help = "unsigned integer value",
- .call = parse_int,
+ .call = cmd_parse_int,
.comp = comp_none,
},
[PREFIX] = {
.name = "{prefix}",
.type = "PREFIX",
.help = "prefix length for bit-mask",
- .call = parse_prefix,
+ .call = cmd_parse_prefix,
.comp = comp_none,
},
[BOOLEAN] = {
.name = "{boolean}",
.type = "BOOLEAN",
.help = "any boolean value",
- .call = parse_boolean,
+ .call = cmd_parse_boolean,
.comp = comp_boolean,
},
[STRING] = {
.name = "{string}",
.type = "STRING",
.help = "fixed string",
- .call = parse_string,
+ .call = cmd_parse_string,
.comp = comp_none,
},
[MAC_ADDR] = {
.name = "{MAC address}",
.type = "MAC-48",
.help = "standard MAC address notation",
- .call = parse_mac_addr,
+ .call = cmd_parse_mac_addr,
.comp = comp_none,
},
[IPV4_ADDR] = {
.name = "{IPv4 address}",
.type = "IPV4 ADDRESS",
.help = "standard IPv4 address notation",
- .call = parse_ipv4_addr,
+ .call = cmd_parse_ipv4_addr,
.comp = comp_none,
},
[IPV6_ADDR] = {
.name = "{IPv6 address}",
.type = "IPV6 ADDRESS",
.help = "standard IPv6 address notation",
- .call = parse_ipv6_addr,
+ .call = cmd_parse_ipv6_addr,
.comp = comp_none,
},
[RULE_ID] = {
.name = "{rule id}",
.type = "RULE ID",
.help = "rule identifier",
- .call = parse_int,
+ .call = cmd_parse_int,
.comp = comp_rule_id,
},
[PORT_ID] = {
.name = "{port_id}",
.type = "PORT ID",
.help = "port identifier",
- .call = parse_port,
+ .call = cmd_parse_port,
.comp = comp_port,
},
[GROUP_ID] = {
.name = "{group_id}",
.type = "GROUP ID",
.help = "group identifier",
- .call = parse_int,
+ .call = cmd_parse_int,
.comp = comp_none,
},
[PRIORITY_LEVEL] = {
.name = "{level}",
.type = "PRIORITY",
.help = "priority level",
- .call = parse_int,
+ .call = cmd_parse_int,
.comp = comp_none,
},
/* Top-level command. */
@@ -1049,7 +1464,7 @@ static const struct token token_list[] = {
LIST,
QUERY,
ISOLATE)),
- .call = parse_init,
+ .call = cmd_parse_init,
},
/* Sub-level commands. */
[VALIDATE] = {
@@ -1057,28 +1472,28 @@ static const struct token token_list[] = {
.help = "check whether a flow rule can be created",
.next = NEXT(next_vc_attr, NEXT_ENTRY(PORT_ID)),
.args = ARGS(ARGS_ENTRY(struct buffer, port)),
- .call = parse_vc,
+ .call = cmd_parse_vc,
},
[CREATE] = {
.name = "create",
.help = "create a flow rule",
.next = NEXT(next_vc_attr, NEXT_ENTRY(PORT_ID)),
.args = ARGS(ARGS_ENTRY(struct buffer, port)),
- .call = parse_vc,
+ .call = cmd_parse_vc,
},
[DESTROY] = {
.name = "destroy",
.help = "destroy specific flow rules",
.next = NEXT(NEXT_ENTRY(DESTROY_RULE), NEXT_ENTRY(PORT_ID)),
.args = ARGS(ARGS_ENTRY(struct buffer, port)),
- .call = parse_destroy,
+ .call = cmd_parse_destroy,
},
[FLUSH] = {
.name = "flush",
.help = "destroy all flow rules",
.next = NEXT(NEXT_ENTRY(PORT_ID)),
.args = ARGS(ARGS_ENTRY(struct buffer, port)),
- .call = parse_flush,
+ .call = cmd_parse_flush,
},
[QUERY] = {
.name = "query",
@@ -1089,14 +1504,14 @@ static const struct token token_list[] = {
.args = ARGS(ARGS_ENTRY(struct buffer, args.query.action),
ARGS_ENTRY(struct buffer, args.query.rule),
ARGS_ENTRY(struct buffer, port)),
- .call = parse_query,
+ .call = cmd_parse_query,
},
[LIST] = {
.name = "list",
.help = "list existing flow rules",
.next = NEXT(next_list_attr, NEXT_ENTRY(PORT_ID)),
.args = ARGS(ARGS_ENTRY(struct buffer, port)),
- .call = parse_list,
+ .call = cmd_parse_list,
},
[ISOLATE] = {
.name = "isolate",
@@ -1105,7 +1520,7 @@ static const struct token token_list[] = {
NEXT_ENTRY(PORT_ID)),
.args = ARGS(ARGS_ENTRY(struct buffer, args.isolate.set),
ARGS_ENTRY(struct buffer, port)),
- .call = parse_isolate,
+ .call = cmd_parse_isolate,
},
/* Destroy arguments. */
[DESTROY_RULE] = {
@@ -1113,14 +1528,14 @@ static const struct token token_list[] = {
.help = "specify a rule identifier",
.next = NEXT(next_destroy_attr, NEXT_ENTRY(RULE_ID)),
.args = ARGS(ARGS_ENTRY_PTR(struct buffer, args.destroy.rule)),
- .call = parse_destroy,
+ .call = cmd_parse_destroy,
},
/* Query arguments. */
[QUERY_ACTION] = {
.name = "{action}",
.type = "ACTION",
.help = "action to query, must be part of the rule",
- .call = parse_action,
+ .call = cmd_parse_action,
.comp = comp_action,
},
/* List arguments. */
@@ -1129,7 +1544,7 @@ static const struct token token_list[] = {
.help = "specify a group",
.next = NEXT(next_list_attr, NEXT_ENTRY(GROUP_ID)),
.args = ARGS(ARGS_ENTRY_PTR(struct buffer, args.list.group)),
- .call = parse_list,
+ .call = cmd_parse_list,
},
/* Validate/create attributes. */
[GROUP] = {
@@ -1137,58 +1552,58 @@ static const struct token token_list[] = {
.help = "specify a group",
.next = NEXT(next_vc_attr, NEXT_ENTRY(GROUP_ID)),
.args = ARGS(ARGS_ENTRY(struct rte_flow_attr, group)),
- .call = parse_vc,
+ .call = cmd_parse_vc,
},
[PRIORITY] = {
.name = "priority",
.help = "specify a priority level",
.next = NEXT(next_vc_attr, NEXT_ENTRY(PRIORITY_LEVEL)),
.args = ARGS(ARGS_ENTRY(struct rte_flow_attr, priority)),
- .call = parse_vc,
+ .call = cmd_parse_vc,
},
[INGRESS] = {
.name = "ingress",
.help = "affect rule to ingress",
.next = NEXT(next_vc_attr),
- .call = parse_vc,
+ .call = cmd_parse_vc,
},
[EGRESS] = {
.name = "egress",
.help = "affect rule to egress",
.next = NEXT(next_vc_attr),
- .call = parse_vc,
+ .call = cmd_parse_vc,
},
/* Validate/create pattern. */
[PATTERN] = {
.name = "pattern",
.help = "submit a list of pattern items",
.next = NEXT(next_item),
- .call = parse_vc,
+ .call = cmd_parse_vc,
},
[ITEM_PARAM_IS] = {
.name = "is",
.help = "match value perfectly (with full bit-mask)",
- .call = parse_vc_spec,
+ .call = cmd_parse_vc_spec,
},
[ITEM_PARAM_SPEC] = {
.name = "spec",
.help = "match value according to configured bit-mask",
- .call = parse_vc_spec,
+ .call = cmd_parse_vc_spec,
},
[ITEM_PARAM_LAST] = {
.name = "last",
.help = "specify upper bound to establish a range",
- .call = parse_vc_spec,
+ .call = cmd_parse_vc_spec,
},
[ITEM_PARAM_MASK] = {
.name = "mask",
.help = "specify bit-mask with relevant bits set to one",
- .call = parse_vc_spec,
+ .call = cmd_parse_vc_spec,
},
[ITEM_PARAM_PREFIX] = {
.name = "prefix",
.help = "generate bit-mask from a prefix length",
- .call = parse_vc_spec,
+ .call = cmd_parse_vc_spec,
},
[ITEM_NEXT] = {
.name = "/",
@@ -1200,28 +1615,28 @@ static const struct token token_list[] = {
.help = "end list of pattern items",
.priv = PRIV_ITEM(END, 0),
.next = NEXT(NEXT_ENTRY(ACTIONS)),
- .call = parse_vc,
+ .call = cmd_parse_vc,
},
[ITEM_VOID] = {
.name = "void",
.help = "no-op pattern item",
.priv = PRIV_ITEM(VOID, 0),
.next = NEXT(NEXT_ENTRY(ITEM_NEXT)),
- .call = parse_vc,
+ .call = cmd_parse_vc,
},
[ITEM_INVERT] = {
.name = "invert",
.help = "perform actions when pattern does not match",
.priv = PRIV_ITEM(INVERT, 0),
.next = NEXT(NEXT_ENTRY(ITEM_NEXT)),
- .call = parse_vc,
+ .call = cmd_parse_vc,
},
[ITEM_ANY] = {
.name = "any",
.help = "match any protocol for the current layer",
.priv = PRIV_ITEM(ANY, sizeof(struct rte_flow_item_any)),
.next = NEXT(item_any),
- .call = parse_vc,
+ .call = cmd_parse_vc,
},
[ITEM_ANY_NUM] = {
.name = "num",
@@ -1234,14 +1649,14 @@ static const struct token token_list[] = {
.help = "match packets addressed to the physical function",
.priv = PRIV_ITEM(PF, 0),
.next = NEXT(NEXT_ENTRY(ITEM_NEXT)),
- .call = parse_vc,
+ .call = cmd_parse_vc,
},
[ITEM_VF] = {
.name = "vf",
.help = "match packets addressed to a virtual function ID",
.priv = PRIV_ITEM(VF, sizeof(struct rte_flow_item_vf)),
.next = NEXT(item_vf),
- .call = parse_vc,
+ .call = cmd_parse_vc,
},
[ITEM_VF_ID] = {
.name = "id",
@@ -1254,7 +1669,7 @@ static const struct token token_list[] = {
.help = "device-specific physical port index to use",
.priv = PRIV_ITEM(PORT, sizeof(struct rte_flow_item_port)),
.next = NEXT(item_port),
- .call = parse_vc,
+ .call = cmd_parse_vc,
},
[ITEM_PORT_INDEX] = {
.name = "index",
@@ -1267,7 +1682,7 @@ static const struct token token_list[] = {
.help = "match an arbitrary byte string",
.priv = PRIV_ITEM(RAW, ITEM_RAW_SIZE),
.next = NEXT(item_raw),
- .call = parse_vc,
+ .call = cmd_parse_vc,
},
[ITEM_RAW_RELATIVE] = {
.name = "relative",
@@ -1313,7 +1728,7 @@ static const struct token token_list[] = {
.help = "match Ethernet header",
.priv = PRIV_ITEM(ETH, sizeof(struct rte_flow_item_eth)),
.next = NEXT(item_eth),
- .call = parse_vc,
+ .call = cmd_parse_vc,
},
[ITEM_ETH_DST] = {
.name = "dst",
@@ -1338,7 +1753,7 @@ static const struct token token_list[] = {
.help = "match 802.1Q/ad VLAN tag",
.priv = PRIV_ITEM(VLAN, sizeof(struct rte_flow_item_vlan)),
.next = NEXT(item_vlan),
- .call = parse_vc,
+ .call = cmd_parse_vc,
},
[ITEM_VLAN_TPID] = {
.name = "tpid",
@@ -1378,7 +1793,7 @@ static const struct token token_list[] = {
.help = "match IPv4 header",
.priv = PRIV_ITEM(IPV4, sizeof(struct rte_flow_item_ipv4)),
.next = NEXT(item_ipv4),
- .call = parse_vc,
+ .call = cmd_parse_vc,
},
[ITEM_IPV4_TOS] = {
.name = "tos",
@@ -1420,7 +1835,7 @@ static const struct token token_list[] = {
.help = "match IPv6 header",
.priv = PRIV_ITEM(IPV6, sizeof(struct rte_flow_item_ipv6)),
.next = NEXT(item_ipv6),
- .call = parse_vc,
+ .call = cmd_parse_vc,
},
[ITEM_IPV6_TC] = {
.name = "tc",
@@ -1471,7 +1886,7 @@ static const struct token token_list[] = {
.help = "match ICMP header",
.priv = PRIV_ITEM(ICMP, sizeof(struct rte_flow_item_icmp)),
.next = NEXT(item_icmp),
- .call = parse_vc,
+ .call = cmd_parse_vc,
},
[ITEM_ICMP_TYPE] = {
.name = "type",
@@ -1492,7 +1907,7 @@ static const struct token token_list[] = {
.help = "match UDP header",
.priv = PRIV_ITEM(UDP, sizeof(struct rte_flow_item_udp)),
.next = NEXT(item_udp),
- .call = parse_vc,
+ .call = cmd_parse_vc,
},
[ITEM_UDP_SRC] = {
.name = "src",
@@ -1513,7 +1928,7 @@ static const struct token token_list[] = {
.help = "match TCP header",
.priv = PRIV_ITEM(TCP, sizeof(struct rte_flow_item_tcp)),
.next = NEXT(item_tcp),
- .call = parse_vc,
+ .call = cmd_parse_vc,
},
[ITEM_TCP_SRC] = {
.name = "src",
@@ -1541,7 +1956,7 @@ static const struct token token_list[] = {
.help = "match SCTP header",
.priv = PRIV_ITEM(SCTP, sizeof(struct rte_flow_item_sctp)),
.next = NEXT(item_sctp),
- .call = parse_vc,
+ .call = cmd_parse_vc,
},
[ITEM_SCTP_SRC] = {
.name = "src",
@@ -1576,7 +1991,7 @@ static const struct token token_list[] = {
.help = "match VXLAN header",
.priv = PRIV_ITEM(VXLAN, sizeof(struct rte_flow_item_vxlan)),
.next = NEXT(item_vxlan),
- .call = parse_vc,
+ .call = cmd_parse_vc,
},
[ITEM_VXLAN_VNI] = {
.name = "vni",
@@ -1589,7 +2004,7 @@ static const struct token token_list[] = {
.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,
+ .call = cmd_parse_vc,
},
[ITEM_E_TAG_GRP_ECID_B] = {
.name = "grp_ecid_b",
@@ -1604,7 +2019,7 @@ static const struct token token_list[] = {
.help = "match NVGRE header",
.priv = PRIV_ITEM(NVGRE, sizeof(struct rte_flow_item_nvgre)),
.next = NEXT(item_nvgre),
- .call = parse_vc,
+ .call = cmd_parse_vc,
},
[ITEM_NVGRE_TNI] = {
.name = "tni",
@@ -1617,7 +2032,7 @@ static const struct token token_list[] = {
.help = "match MPLS header",
.priv = PRIV_ITEM(MPLS, sizeof(struct rte_flow_item_mpls)),
.next = NEXT(item_mpls),
- .call = parse_vc,
+ .call = cmd_parse_vc,
},
[ITEM_MPLS_LABEL] = {
.name = "label",
@@ -1632,7 +2047,7 @@ static const struct token token_list[] = {
.help = "match GRE header",
.priv = PRIV_ITEM(GRE, sizeof(struct rte_flow_item_gre)),
.next = NEXT(item_gre),
- .call = parse_vc,
+ .call = cmd_parse_vc,
},
[ITEM_GRE_PROTO] = {
.name = "protocol",
@@ -1647,7 +2062,7 @@ static const struct token token_list[] = {
.priv = PRIV_ITEM(FUZZY,
sizeof(struct rte_flow_item_fuzzy)),
.next = NEXT(item_fuzzy),
- .call = parse_vc,
+ .call = cmd_parse_vc,
},
[ITEM_FUZZY_THRESH] = {
.name = "thresh",
@@ -1661,7 +2076,7 @@ static const struct token token_list[] = {
.help = "match GTP header",
.priv = PRIV_ITEM(GTP, sizeof(struct rte_flow_item_gtp)),
.next = NEXT(item_gtp),
- .call = parse_vc,
+ .call = cmd_parse_vc,
},
[ITEM_GTP_TEID] = {
.name = "teid",
@@ -1674,14 +2089,14 @@ static const struct token token_list[] = {
.help = "match GTP header",
.priv = PRIV_ITEM(GTPC, sizeof(struct rte_flow_item_gtp)),
.next = NEXT(item_gtp),
- .call = parse_vc,
+ .call = cmd_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,
+ .call = cmd_parse_vc,
},
/* Validate/create actions. */
@@ -1689,7 +2104,7 @@ static const struct token token_list[] = {
.name = "actions",
.help = "submit a list of associated actions",
.next = NEXT(next_action),
- .call = parse_vc,
+ .call = cmd_parse_vc,
},
[ACTION_NEXT] = {
.name = "/",
@@ -1700,42 +2115,42 @@ static const struct token token_list[] = {
.name = "end",
.help = "end list of actions",
.priv = PRIV_ACTION(END, 0),
- .call = parse_vc,
+ .call = cmd_parse_vc,
},
[ACTION_VOID] = {
.name = "void",
.help = "no-op action",
.priv = PRIV_ACTION(VOID, 0),
.next = NEXT(NEXT_ENTRY(ACTION_NEXT)),
- .call = parse_vc,
+ .call = cmd_parse_vc,
},
[ACTION_PASSTHRU] = {
.name = "passthru",
.help = "let subsequent rule process matched packets",
.priv = PRIV_ACTION(PASSTHRU, 0),
.next = NEXT(NEXT_ENTRY(ACTION_NEXT)),
- .call = parse_vc,
+ .call = cmd_parse_vc,
},
[ACTION_MARK] = {
.name = "mark",
.help = "attach 32 bit value to packets",
.priv = PRIV_ACTION(MARK, sizeof(struct rte_flow_action_mark)),
.next = NEXT(action_mark),
- .call = parse_vc,
+ .call = cmd_parse_vc,
},
[ACTION_MARK_ID] = {
.name = "id",
.help = "32 bit value to return with packets",
.next = NEXT(action_mark, NEXT_ENTRY(UNSIGNED)),
.args = ARGS(ARGS_ENTRY(struct rte_flow_action_mark, id)),
- .call = parse_vc_conf,
+ .call = cmd_parse_vc_conf,
},
[ACTION_FLAG] = {
.name = "flag",
.help = "flag packets",
.priv = PRIV_ACTION(FLAG, 0),
.next = NEXT(NEXT_ENTRY(ACTION_NEXT)),
- .call = parse_vc,
+ .call = cmd_parse_vc,
},
[ACTION_QUEUE] = {
.name = "queue",
@@ -1743,60 +2158,60 @@ static const struct token token_list[] = {
.priv = PRIV_ACTION(QUEUE,
sizeof(struct rte_flow_action_queue)),
.next = NEXT(action_queue),
- .call = parse_vc,
+ .call = cmd_parse_vc,
},
[ACTION_QUEUE_INDEX] = {
.name = "index",
.help = "queue index to use",
.next = NEXT(action_queue, NEXT_ENTRY(UNSIGNED)),
.args = ARGS(ARGS_ENTRY(struct rte_flow_action_queue, index)),
- .call = parse_vc_conf,
+ .call = cmd_parse_vc_conf,
},
[ACTION_DROP] = {
.name = "drop",
.help = "drop packets (note: passthru has priority)",
.priv = PRIV_ACTION(DROP, 0),
.next = NEXT(NEXT_ENTRY(ACTION_NEXT)),
- .call = parse_vc,
+ .call = cmd_parse_vc,
},
[ACTION_COUNT] = {
.name = "count",
.help = "enable counters for this rule",
.priv = PRIV_ACTION(COUNT, 0),
.next = NEXT(NEXT_ENTRY(ACTION_NEXT)),
- .call = parse_vc,
+ .call = cmd_parse_vc,
},
[ACTION_DUP] = {
.name = "dup",
.help = "duplicate packets to a given queue index",
.priv = PRIV_ACTION(DUP, sizeof(struct rte_flow_action_dup)),
.next = NEXT(action_dup),
- .call = parse_vc,
+ .call = cmd_parse_vc,
},
[ACTION_DUP_INDEX] = {
.name = "index",
.help = "queue index to duplicate packets to",
.next = NEXT(action_dup, NEXT_ENTRY(UNSIGNED)),
.args = ARGS(ARGS_ENTRY(struct rte_flow_action_dup, index)),
- .call = parse_vc_conf,
+ .call = cmd_parse_vc_conf,
},
[ACTION_RSS] = {
.name = "rss",
.help = "spread packets among several queues",
.priv = PRIV_ACTION(RSS, ACTION_RSS_SIZE),
.next = NEXT(action_rss),
- .call = parse_vc,
+ .call = cmd_parse_vc,
},
[ACTION_RSS_QUEUES] = {
.name = "queues",
.help = "queue indices to use",
.next = NEXT(action_rss, NEXT_ENTRY(ACTION_RSS_QUEUE)),
- .call = parse_vc_conf,
+ .call = cmd_parse_vc_conf,
},
[ACTION_RSS_QUEUE] = {
.name = "{queue}",
.help = "queue index",
- .call = parse_vc_action_rss_queue,
+ .call = cmd_parse_vc_action_rss_queue,
.comp = comp_vc_action_rss_queue,
},
[ACTION_PF] = {
@@ -1804,14 +2219,14 @@ static const struct token token_list[] = {
.help = "redirect packets to physical device function",
.priv = PRIV_ACTION(PF, 0),
.next = NEXT(NEXT_ENTRY(ACTION_NEXT)),
- .call = parse_vc,
+ .call = cmd_parse_vc,
},
[ACTION_VF] = {
.name = "vf",
.help = "redirect packets to virtual device function",
.priv = PRIV_ACTION(VF, sizeof(struct rte_flow_action_vf)),
.next = NEXT(action_vf),
- .call = parse_vc,
+ .call = cmd_parse_vc,
},
[ACTION_VF_ORIGINAL] = {
.name = "original",
@@ -1819,14 +2234,14 @@ static const struct token token_list[] = {
.next = NEXT(action_vf, NEXT_ENTRY(BOOLEAN)),
.args = ARGS(ARGS_ENTRY_BF(struct rte_flow_action_vf,
original, 1)),
- .call = parse_vc_conf,
+ .call = cmd_parse_vc_conf,
},
[ACTION_VF_ID] = {
.name = "id",
.help = "VF ID to redirect packets to",
.next = NEXT(action_vf, NEXT_ENTRY(UNSIGNED)),
.args = ARGS(ARGS_ENTRY(struct rte_flow_action_vf, id)),
- .call = parse_vc_conf,
+ .call = cmd_parse_vc_conf,
},
[ACTION_METER] = {
.name = "meter",
@@ -1834,14 +2249,14 @@ static const struct token token_list[] = {
.priv = PRIV_ACTION(METER,
sizeof(struct rte_flow_action_meter)),
.next = NEXT(action_meter),
- .call = parse_vc,
+ .call = cmd_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,
+ .call = cmd_parse_vc_conf,
},
};
diff --git a/lib/librte_ether/rte_flow.c b/lib/librte_ether/rte_flow.c
index 3302208..e437d03 100644
--- a/lib/librte_ether/rte_flow.c
+++ b/lib/librte_ether/rte_flow.c
@@ -249,7 +249,7 @@ rte_flow_error_set(struct rte_flow_error *error,
}
/** Compute storage space needed by item specification. */
-void
+static void
flow_item_spec_size(const struct rte_flow_item *item,
size_t *size, size_t *pad)
{
@@ -277,7 +277,7 @@ flow_item_spec_size(const struct rte_flow_item *item,
}
/** Compute storage space needed by action configuration. */
-void
+static void
flow_action_conf_size(const struct rte_flow_action *action,
size_t *size, size_t *pad)
{
diff --git a/lib/librte_ether/rte_flow.h b/lib/librte_ether/rte_flow.h
index c2184b6..4178203 100644
--- a/lib/librte_ether/rte_flow.h
+++ b/lib/librte_ether/rte_flow.h
@@ -1180,16 +1180,6 @@ struct rte_flow_action {
*/
struct rte_flow;
-/** Compute storage space needed by item specification. */
-void
-flow_item_spec_size(const struct rte_flow_item *item,
- size_t *size, size_t *pad);
-
-/** Compute storage space needed by action configuration. */
-void
-flow_action_conf_size(const struct rte_flow_action *action,
- size_t *size, size_t *pad);
-
/**
* Verbose error types.
*
--
2.7.4
More information about the dev
mailing list