app/testpmd: add items eth/vlan to flow command

These pattern items match basic Ethernet headers (source, destination and
type) and related 802.1Q/ad VLAN headers.

Signed-off-by: Adrien Mazarguil <adrien.mazarguil@6wind.com>
Acked-by: Olga Shern <olgas@mellanox.com>
This commit is contained in:
Adrien Mazarguil 2016-12-21 15:51:36 +01:00 committed by Thomas Monjalon
parent abc3d81aca
commit 6df81b325f

View File

@ -43,6 +43,7 @@
#include <rte_ethdev.h>
#include <rte_byteorder.h>
#include <cmdline_parse.h>
#include <cmdline_parse_etheraddr.h>
#include <rte_flow.h>
#include "testpmd.h"
@ -59,6 +60,7 @@ enum index {
PREFIX,
BOOLEAN,
STRING,
MAC_ADDR,
RULE_ID,
PORT_ID,
GROUP_ID,
@ -114,6 +116,13 @@ enum index {
ITEM_RAW_OFFSET,
ITEM_RAW_LIMIT,
ITEM_RAW_PATTERN,
ITEM_ETH,
ITEM_ETH_DST,
ITEM_ETH_SRC,
ITEM_ETH_TYPE,
ITEM_VLAN,
ITEM_VLAN_TPID,
ITEM_VLAN_TCI,
/* Validate/create actions. */
ACTIONS,
@ -238,6 +247,14 @@ struct token {
.size = (sz), \
})
/** Same as ARGS_ENTRY() using network byte ordering. */
#define ARGS_ENTRY_HTON(s, f) \
(&(const struct arg){ \
.hton = 1, \
.offset = offsetof(s, f), \
.size = sizeof(((s *)0)->f), \
})
/** Parser output buffer layout expected by cmd_flow_parsed(). */
struct buffer {
enum index command; /**< Flow command. */
@ -329,6 +346,8 @@ static const enum index next_item[] = {
ITEM_VF,
ITEM_PORT,
ITEM_RAW,
ITEM_ETH,
ITEM_VLAN,
ZERO,
};
@ -360,6 +379,21 @@ static const enum index item_raw[] = {
ZERO,
};
static const enum index item_eth[] = {
ITEM_ETH_DST,
ITEM_ETH_SRC,
ITEM_ETH_TYPE,
ITEM_NEXT,
ZERO,
};
static const enum index item_vlan[] = {
ITEM_VLAN_TPID,
ITEM_VLAN_TCI,
ITEM_NEXT,
ZERO,
};
static const enum index next_action[] = {
ACTION_END,
ACTION_VOID,
@ -402,6 +436,9 @@ static int parse_boolean(struct context *, const struct token *,
static int parse_string(struct context *, const struct token *,
const char *, unsigned int,
void *, unsigned int);
static int parse_mac_addr(struct context *, const struct token *,
const char *, unsigned int,
void *, unsigned int);
static int parse_port(struct context *, const struct token *,
const char *, unsigned int,
void *, unsigned int);
@ -465,6 +502,13 @@ static const struct token token_list[] = {
.call = parse_string,
.comp = comp_none,
},
[MAC_ADDR] = {
.name = "{MAC address}",
.type = "MAC-48",
.help = "standard MAC address notation",
.call = parse_mac_addr,
.comp = comp_none,
},
[RULE_ID] = {
.name = "{rule id}",
.type = "RULE ID",
@ -755,6 +799,50 @@ static const struct token token_list[] = {
pattern,
ITEM_RAW_PATTERN_SIZE)),
},
[ITEM_ETH] = {
.name = "eth",
.help = "match Ethernet header",
.priv = PRIV_ITEM(ETH, sizeof(struct rte_flow_item_eth)),
.next = NEXT(item_eth),
.call = parse_vc,
},
[ITEM_ETH_DST] = {
.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)),
},
[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)),
},
[ITEM_ETH_TYPE] = {
.name = "type",
.help = "EtherType",
.next = NEXT(item_eth, NEXT_ENTRY(UNSIGNED), item_param),
.args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_eth, type)),
},
[ITEM_VLAN] = {
.name = "vlan",
.help = "match 802.1Q/ad VLAN tag",
.priv = PRIV_ITEM(VLAN, sizeof(struct rte_flow_item_vlan)),
.next = NEXT(item_vlan),
.call = parse_vc,
},
[ITEM_VLAN_TPID] = {
.name = "tpid",
.help = "tag protocol identifier",
.next = NEXT(item_vlan, NEXT_ENTRY(UNSIGNED), item_param),
.args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_vlan, tpid)),
},
[ITEM_VLAN_TCI] = {
.name = "tci",
.help = "tag control information",
.next = NEXT(item_vlan, NEXT_ENTRY(UNSIGNED), item_param),
.args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_vlan, tci)),
},
/* Validate/create actions. */
[ACTIONS] = {
.name = "actions",
@ -1399,6 +1487,44 @@ parse_string(struct context *ctx, const struct token *token,
return -1;
}
/**
* Parse a MAC address.
*
* Last argument (ctx->args) is retrieved to determine storage size and
* location.
*/
static int
parse_mac_addr(struct context *ctx, const struct token *token,
const char *str, unsigned int len,
void *buf, unsigned int size)
{
const struct arg *arg = pop_args(ctx);
struct ether_addr tmp;
int ret;
(void)token;
/* Argument is expected. */
if (!arg)
return -1;
size = arg->size;
/* Bit-mask fill is not supported. */
if (arg->mask || size != sizeof(tmp))
goto error;
ret = cmdline_parse_etheraddr(NULL, str, &tmp, size);
if (ret < 0 || (unsigned int)ret != len)
goto error;
if (!ctx->object)
return len;
buf = (uint8_t *)ctx->object + arg->offset;
memcpy(buf, &tmp, size);
if (ctx->objmask)
memset((uint8_t *)ctx->objmask + arg->offset, 0xff, size);
return len;
error:
push_args(ctx, arg);
return -1;
}
/** Boolean values (even indices stand for false). */
static const char *const boolean_name[] = {
"0", "1",