@@ -408,6 +408,16 @@ enum index {
ACTION_SAMPLE_INDEX_VALUE,
ACTION_SHARED,
SHARED_ACTION_ID2PTR,
+ ACTION_COPY_ITEM,
+ ACTION_COPY_ITEM_DST_TYPE,
+ ACTION_COPY_ITEM_DST_TYPE_VALUE,
+ ACTION_COPY_ITEM_DST_INDEX,
+ ACTION_COPY_ITEM_DST_OFFSET,
+ ACTION_COPY_ITEM_SRC_TYPE,
+ ACTION_COPY_ITEM_SRC_TYPE_VALUE,
+ ACTION_COPY_ITEM_SRC_INDEX,
+ ACTION_COPY_ITEM_SRC_OFFSET,
+ ACTION_COPY_ITEM_WIDTH,
};
/** Maximum size for pattern in struct rte_flow_item_raw. */
@@ -561,6 +571,18 @@ struct rte_flow_action_count sample_count[RAW_SAMPLE_CONFS_MAX_NUM];
struct rte_flow_action_port_id sample_port_id[RAW_SAMPLE_CONFS_MAX_NUM];
struct rte_flow_action_raw_encap sample_encap[RAW_SAMPLE_CONFS_MAX_NUM];
+static const char *const copy_item_table[] = {
+ "none", "mac_dst", "mac_src",
+ "vlan_type", "vlan_id", "mac_type",
+ "ipv4_dscp", "ipv4_ttl", "ipv4_src", "ipv4_dst",
+ "ipv6_hoplimit", "ipv6_src", "ipv6_dst",
+ "tcp_port_src", "tcp_port_dst",
+ "tcp_seq_num", "tcp_ack_num", "tcp_flags",
+ "udp_port_src", "udp_port_dst",
+ "vxlan_vni", "geneve_vni", "gtp_teid",
+ "tag", "mark", "meta", NULL
+};
+
/** Maximum number of subsequent tokens and arguments on the stack. */
#define CTX_STACK_SIZE 16
@@ -1306,6 +1328,7 @@ static const enum index next_action[] = {
ACTION_AGE,
ACTION_SAMPLE,
ACTION_SHARED,
+ ACTION_COPY_ITEM,
ZERO,
};
@@ -1638,6 +1661,10 @@ static int
parse_vc_action_sample_index(struct context *ctx, const struct token *token,
const char *str, unsigned int len, void *buf,
unsigned int size);
+static int
+parse_vc_copy_item(struct context *ctx, const struct token *token,
+ const char *str, unsigned int len, void *buf,
+ unsigned int size);
static int parse_destroy(struct context *, const struct token *,
const char *, unsigned int,
void *, unsigned int);
@@ -1722,6 +1749,8 @@ static int comp_set_raw_index(struct context *, const struct token *,
unsigned int, char *, unsigned int);
static int comp_set_sample_index(struct context *, const struct token *,
unsigned int, char *, unsigned int);
+static int comp_set_copy_item(struct context *, const struct token *,
+ unsigned int, char *, unsigned int);
/** Token definitions. */
static const struct token token_list[] = {
@@ -4037,6 +4066,85 @@ static const struct token token_list[] = {
.call = parse_vc_action_raw_decap_index,
.comp = comp_set_raw_index,
},
+ [ACTION_COPY_ITEM] = {
+ .name = "copy_item",
+ .help = "copy data from dst to src item",
+ .priv = PRIV_ACTION(COPY_ITEM,
+ sizeof(struct rte_flow_action_copy_item)),
+ .next = NEXT(NEXT_ENTRY(ACTION_COPY_ITEM_DST_TYPE)),
+ .call = parse_vc,
+ },
+ [ACTION_COPY_ITEM_DST_TYPE] = {
+ .name = "dst_type",
+ .help = "destination item type",
+ .next = NEXT(NEXT_ENTRY(ACTION_COPY_ITEM_DST_INDEX),
+ NEXT_ENTRY(ACTION_COPY_ITEM_DST_TYPE_VALUE)),
+ .call = parse_vc_conf,
+ },
+ [ACTION_COPY_ITEM_DST_TYPE_VALUE] = {
+ .name = "{type}",
+ .help = "destination item type value",
+ .call = parse_vc_copy_item,
+ .comp = comp_set_copy_item,
+ },
+ [ACTION_COPY_ITEM_DST_INDEX] = {
+ .name = "dst_index",
+ .help = "destination item index",
+ .next = NEXT(NEXT_ENTRY(ACTION_COPY_ITEM_DST_OFFSET),
+ NEXT_ENTRY(UNSIGNED)),
+ .args = ARGS(ARGS_ENTRY(struct rte_flow_action_copy_item,
+ dst.index)),
+ .call = parse_vc_conf,
+ },
+ [ACTION_COPY_ITEM_DST_OFFSET] = {
+ .name = "dst_offset",
+ .help = "destination item offset",
+ .next = NEXT(NEXT_ENTRY(ACTION_COPY_ITEM_SRC_TYPE),
+ NEXT_ENTRY(UNSIGNED)),
+ .args = ARGS(ARGS_ENTRY(struct rte_flow_action_copy_item,
+ dst.offset)),
+ .call = parse_vc_conf,
+ },
+ [ACTION_COPY_ITEM_SRC_TYPE] = {
+ .name = "src_type",
+ .help = "source item type",
+ .next = NEXT(NEXT_ENTRY(ACTION_COPY_ITEM_SRC_INDEX),
+ NEXT_ENTRY(ACTION_COPY_ITEM_SRC_TYPE_VALUE)),
+ .call = parse_vc_conf,
+ },
+ [ACTION_COPY_ITEM_SRC_TYPE_VALUE] = {
+ .name = "{type}",
+ .help = "source item type value",
+ .call = parse_vc_copy_item,
+ .comp = comp_set_copy_item,
+ },
+ [ACTION_COPY_ITEM_SRC_INDEX] = {
+ .name = "src_index",
+ .help = "source item type index",
+ .next = NEXT(NEXT_ENTRY(ACTION_COPY_ITEM_SRC_OFFSET),
+ NEXT_ENTRY(UNSIGNED)),
+ .args = ARGS(ARGS_ENTRY(struct rte_flow_action_copy_item,
+ src.index)),
+ .call = parse_vc_conf,
+ },
+ [ACTION_COPY_ITEM_SRC_OFFSET] = {
+ .name = "src_offset",
+ .help = "source item type offset",
+ .next = NEXT(NEXT_ENTRY(ACTION_COPY_ITEM_WIDTH),
+ NEXT_ENTRY(UNSIGNED)),
+ .args = ARGS(ARGS_ENTRY(struct rte_flow_action_copy_item,
+ src.offset)),
+ .call = parse_vc_conf,
+ },
+ [ACTION_COPY_ITEM_WIDTH] = {
+ .name = "width",
+ .help = "number of bits to copy",
+ .next = NEXT(NEXT_ENTRY(ACTION_NEXT),
+ NEXT_ENTRY(UNSIGNED)),
+ .args = ARGS(ARGS_ENTRY(struct rte_flow_action_copy_item,
+ width)),
+ .call = parse_vc_conf,
+ },
/* Top level command. */
[SET] = {
.name = "set",
@@ -5960,6 +6068,36 @@ parse_vc_action_sample_index(struct context *ctx, const struct token *token,
return len;
}
+/** Parse tokens for copy_item command. */
+static int
+parse_vc_copy_item(struct context *ctx, const struct token *token,
+ const char *str, unsigned int len, void *buf,
+ unsigned int size)
+{
+ struct rte_flow_action_copy_item *action_copy_item;
+ unsigned int i;
+
+ (void)token;
+ (void)buf;
+ (void)size;
+ if (ctx->curr != ACTION_COPY_ITEM_DST_TYPE_VALUE &&
+ ctx->curr != ACTION_COPY_ITEM_SRC_TYPE_VALUE)
+ return -1;
+ for (i = 0; copy_item_table[i]; ++i)
+ if (!strcmp_partial(copy_item_table[i], str, len))
+ break;
+ if (!copy_item_table[i])
+ return -1;
+ if (!ctx->object)
+ return len;
+ action_copy_item = ctx->object;
+ if (ctx->curr == ACTION_COPY_ITEM_DST_TYPE_VALUE)
+ action_copy_item->dst.item = i;
+ else
+ action_copy_item->src.item = i;
+ return len;
+}
+
/** Parse tokens for destroy command. */
static int
parse_destroy(struct context *ctx, const struct token *token,
@@ -7029,6 +7167,24 @@ comp_set_sample_index(struct context *ctx, const struct token *token,
return nb;
}
+/** Complete item type for copy_item command. */
+static int
+comp_set_copy_item(struct context *ctx, const struct token *token,
+ unsigned int ent, char *buf, unsigned int size)
+{
+ uint16_t idx = 0;
+
+ RTE_SET_USED(ctx);
+ RTE_SET_USED(token);
+ for (idx = 0; copy_item_table[idx]; ++idx)
+ ;
+ if (!buf)
+ return idx + 1;
+ if (ent < idx)
+ return strlcpy(buf, copy_item_table[ent], size);
+ return -1;
+}
+
/** Internal context. */
static struct context cmd_flow_context;