#include <rte_ethdev.h>
#include <rte_byteorder.h>
#include <cmdline_parse.h>
-#include <cmdline_parse_etheraddr.h>
#include <rte_flow.h>
#include "testpmd.h"
ITEM_MPLS_LABEL,
ITEM_GRE,
ITEM_GRE_PROTO,
+ ITEM_GRE_C_RSVD0_VER,
+ ITEM_GRE_C_BIT,
+ ITEM_GRE_K_BIT,
+ ITEM_GRE_S_BIT,
ITEM_FUZZY,
ITEM_FUZZY_THRESH,
ITEM_GTP,
ITEM_ICMP6_ND_OPT_TLA_ETH_TLA,
ITEM_META,
ITEM_META_DATA,
+ ITEM_GRE_KEY,
+ ITEM_GRE_KEY_VALUE,
/* Validate/create actions. */
ACTIONS,
ACTION_SET_MAC_SRC_MAC_SRC,
ACTION_SET_MAC_DST,
ACTION_SET_MAC_DST_MAC_DST,
+ ACTION_INC_TCP_SEQ,
+ ACTION_INC_TCP_SEQ_VALUE,
+ ACTION_DEC_TCP_SEQ,
+ ACTION_DEC_TCP_SEQ_VALUE,
+ ACTION_INC_TCP_ACK,
+ ACTION_INC_TCP_ACK_VALUE,
+ ACTION_DEC_TCP_ACK,
+ ACTION_DEC_TCP_ACK_VALUE,
};
/** Maximum size for pattern in struct rte_flow_item_raw. */
.size = sizeof(((s *)0)->f), \
})
+/** Same as ARGS_ENTRY_HTON() for a single argument, without structure. */
+#define ARG_ENTRY_HTON(s) \
+ (&(const struct arg){ \
+ .hton = 1, \
+ .offset = 0, \
+ .size = sizeof(s), \
+ })
+
/** Parser output buffer layout expected by cmd_flow_parsed(). */
struct buffer {
enum index command; /**< Flow command. */
ITEM_ICMP6_ND_OPT_SLA_ETH,
ITEM_ICMP6_ND_OPT_TLA_ETH,
ITEM_META,
+ ITEM_GRE_KEY,
ZERO,
};
static const enum index item_gre[] = {
ITEM_GRE_PROTO,
+ ITEM_GRE_C_RSVD0_VER,
+ ITEM_GRE_C_BIT,
+ ITEM_GRE_K_BIT,
+ ITEM_GRE_S_BIT,
+ ITEM_NEXT,
+ ZERO,
+};
+
+static const enum index item_gre_key[] = {
+ ITEM_GRE_KEY_VALUE,
ITEM_NEXT,
ZERO,
};
ACTION_SET_TTL,
ACTION_SET_MAC_SRC,
ACTION_SET_MAC_DST,
+ ACTION_INC_TCP_SEQ,
+ ACTION_DEC_TCP_SEQ,
+ ACTION_INC_TCP_ACK,
+ ACTION_DEC_TCP_ACK,
ZERO,
};
ZERO,
};
+static const enum index action_inc_tcp_seq[] = {
+ ACTION_INC_TCP_SEQ_VALUE,
+ ACTION_NEXT,
+ ZERO,
+};
+
+static const enum index action_dec_tcp_seq[] = {
+ ACTION_DEC_TCP_SEQ_VALUE,
+ ACTION_NEXT,
+ ZERO,
+};
+
+static const enum index action_inc_tcp_ack[] = {
+ ACTION_INC_TCP_ACK_VALUE,
+ ACTION_NEXT,
+ ZERO,
+};
+
+static const enum index action_dec_tcp_ack[] = {
+ ACTION_DEC_TCP_ACK_VALUE,
+ ACTION_NEXT,
+ ZERO,
+};
+
static int parse_init(struct context *, const struct token *,
const char *, unsigned int,
void *, unsigned int);
.args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_gre,
protocol)),
},
+ [ITEM_GRE_C_RSVD0_VER] = {
+ .name = "c_rsvd0_ver",
+ .help =
+ "checksum (1b), undefined (1b), key bit (1b),"
+ " sequence number (1b), reserved 0 (9b),"
+ " version (3b)",
+ .next = NEXT(item_gre, NEXT_ENTRY(UNSIGNED), item_param),
+ .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_gre,
+ c_rsvd0_ver)),
+ },
+ [ITEM_GRE_C_BIT] = {
+ .name = "c_bit",
+ .help = "checksum bit (C)",
+ .next = NEXT(item_gre, NEXT_ENTRY(BOOLEAN), item_param),
+ .args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_gre,
+ c_rsvd0_ver,
+ "\x80\x00\x00\x00")),
+ },
+ [ITEM_GRE_S_BIT] = {
+ .name = "s_bit",
+ .help = "sequence number bit (S)",
+ .next = NEXT(item_gre, NEXT_ENTRY(BOOLEAN), item_param),
+ .args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_gre,
+ c_rsvd0_ver,
+ "\x10\x00\x00\x00")),
+ },
+ [ITEM_GRE_K_BIT] = {
+ .name = "k_bit",
+ .help = "key bit (K)",
+ .next = NEXT(item_gre, NEXT_ENTRY(BOOLEAN), item_param),
+ .args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_gre,
+ c_rsvd0_ver,
+ "\x20\x00\x00\x00")),
+ },
[ITEM_FUZZY] = {
.name = "fuzzy",
.help = "fuzzy pattern match, expect faster than default",
.args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_meta,
data, "\xff\xff\xff\xff")),
},
+ [ITEM_GRE_KEY] = {
+ .name = "gre_key",
+ .help = "match GRE key",
+ .priv = PRIV_ITEM(GRE_KEY, sizeof(rte_be32_t)),
+ .next = NEXT(item_gre_key),
+ .call = parse_vc,
+ },
+ [ITEM_GRE_KEY_VALUE] = {
+ .name = "value",
+ .help = "key value",
+ .next = NEXT(item_gre_key, NEXT_ENTRY(UNSIGNED), item_param),
+ .args = ARGS(ARG_ENTRY_HTON(rte_be32_t)),
+ },
/* Validate/create actions. */
[ACTIONS] = {
(struct rte_flow_action_set_mac, mac_addr)),
.call = parse_vc_conf,
},
+ [ACTION_INC_TCP_SEQ] = {
+ .name = "inc_tcp_seq",
+ .help = "increase TCP sequence number",
+ .priv = PRIV_ACTION(INC_TCP_SEQ, sizeof(rte_be32_t)),
+ .next = NEXT(action_inc_tcp_seq),
+ .call = parse_vc,
+ },
+ [ACTION_INC_TCP_SEQ_VALUE] = {
+ .name = "value",
+ .help = "the value to increase TCP sequence number by",
+ .next = NEXT(action_inc_tcp_seq, NEXT_ENTRY(UNSIGNED)),
+ .args = ARGS(ARG_ENTRY_HTON(rte_be32_t)),
+ .call = parse_vc_conf,
+ },
+ [ACTION_DEC_TCP_SEQ] = {
+ .name = "dec_tcp_seq",
+ .help = "decrease TCP sequence number",
+ .priv = PRIV_ACTION(DEC_TCP_SEQ, sizeof(rte_be32_t)),
+ .next = NEXT(action_dec_tcp_seq),
+ .call = parse_vc,
+ },
+ [ACTION_DEC_TCP_SEQ_VALUE] = {
+ .name = "value",
+ .help = "the value to decrease TCP sequence number by",
+ .next = NEXT(action_dec_tcp_seq, NEXT_ENTRY(UNSIGNED)),
+ .args = ARGS(ARG_ENTRY_HTON(rte_be32_t)),
+ .call = parse_vc_conf,
+ },
+ [ACTION_INC_TCP_ACK] = {
+ .name = "inc_tcp_ack",
+ .help = "increase TCP acknowledgment number",
+ .priv = PRIV_ACTION(INC_TCP_ACK, sizeof(rte_be32_t)),
+ .next = NEXT(action_inc_tcp_ack),
+ .call = parse_vc,
+ },
+ [ACTION_INC_TCP_ACK_VALUE] = {
+ .name = "value",
+ .help = "the value to increase TCP acknowledgment number by",
+ .next = NEXT(action_inc_tcp_ack, NEXT_ENTRY(UNSIGNED)),
+ .args = ARGS(ARG_ENTRY_HTON(rte_be32_t)),
+ .call = parse_vc_conf,
+ },
+ [ACTION_DEC_TCP_ACK] = {
+ .name = "dec_tcp_ack",
+ .help = "decrease TCP acknowledgment number",
+ .priv = PRIV_ACTION(DEC_TCP_ACK, sizeof(rte_be32_t)),
+ .next = NEXT(action_dec_tcp_ack),
+ .call = parse_vc,
+ },
+ [ACTION_DEC_TCP_ACK_VALUE] = {
+ .name = "value",
+ .help = "the value to decrease TCP acknowledgment number by",
+ .next = NEXT(action_dec_tcp_ack, NEXT_ENTRY(UNSIGNED)),
+ .args = ARGS(ARG_ENTRY_HTON(rte_be32_t)),
+ .call = parse_vc_conf,
+ },
};
/** Remove and return last entry from argument stack. */
{
static const enum index next[] = NEXT_ENTRY(ACTION_RSS_QUEUE);
struct action_rss_data *action_rss_data;
+ const struct arg *arg;
int ret;
int i;
}
if (i >= ACTION_RSS_QUEUE_NUM)
return -1;
- if (push_args(ctx,
- ARGS_ENTRY_ARB(offsetof(struct action_rss_data, queue) +
- i * sizeof(action_rss_data->queue[i]),
- sizeof(action_rss_data->queue[i]))))
+ arg = ARGS_ENTRY_ARB(offsetof(struct action_rss_data, queue) +
+ i * sizeof(action_rss_data->queue[i]),
+ sizeof(action_rss_data->queue[i]));
+ if (push_args(ctx, arg))
return -1;
ret = parse_int(ctx, token, str, len, NULL, 0);
if (ret < 0) {
.src_addr = mplsogre_encap_conf.ipv4_src,
.dst_addr = mplsogre_encap_conf.ipv4_dst,
.next_proto_id = IPPROTO_GRE,
+ .version_ihl = RTE_IPV4_VHL_DEF,
+ .time_to_live = IPDEFTTL,
},
};
struct rte_flow_item_ipv6 ipv6 = {
.hdr = {
.proto = IPPROTO_GRE,
+ .hop_limits = IPDEFTTL,
},
};
struct rte_flow_item_gre gre = {
.src_addr = mplsoudp_encap_conf.ipv4_src,
.dst_addr = mplsoudp_encap_conf.ipv4_dst,
.next_proto_id = IPPROTO_UDP,
+ .version_ihl = RTE_IPV4_VHL_DEF,
+ .time_to_live = IPDEFTTL,
},
};
struct rte_flow_item_ipv6 ipv6 = {
.hdr = {
.proto = IPPROTO_UDP,
+ .hop_limits = IPDEFTTL,
},
};
struct rte_flow_item_udp udp = {
/* 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)
+ ret = rte_ether_unformat_addr(str, &tmp);
+ if (ret < 0)
goto error;
if (!ctx->object)
return len;