@@ -543,6 +543,28 @@ enum index {
ITEM_PTYPE,
ITEM_PTYPE_VALUE,
ITEM_NSH,
+ ITEM_COMPARE,
+ ITEM_COMPARE_OP,
+ ITEM_COMPARE_OP_VALUE,
+ ITEM_COMPARE_FIELD_A_TYPE,
+ ITEM_COMPARE_FIELD_A_TYPE_VALUE,
+ ITEM_COMPARE_FIELD_A_LEVEL,
+ ITEM_COMPARE_FIELD_A_LEVEL_VALUE,
+ ITEM_COMPARE_FIELD_A_TAG_INDEX,
+ ITEM_COMPARE_FIELD_A_TYPE_ID,
+ ITEM_COMPARE_FIELD_A_CLASS_ID,
+ ITEM_COMPARE_FIELD_A_OFFSET,
+ ITEM_COMPARE_FIELD_B_TYPE,
+ ITEM_COMPARE_FIELD_B_TYPE_VALUE,
+ ITEM_COMPARE_FIELD_B_LEVEL,
+ ITEM_COMPARE_FIELD_B_LEVEL_VALUE,
+ ITEM_COMPARE_FIELD_B_TAG_INDEX,
+ ITEM_COMPARE_FIELD_B_TYPE_ID,
+ ITEM_COMPARE_FIELD_B_CLASS_ID,
+ ITEM_COMPARE_FIELD_B_OFFSET,
+ ITEM_COMPARE_FIELD_B_VALUE,
+ ITEM_COMPARE_FIELD_B_POINTER,
+ ITEM_COMPARE_FIELD_WIDTH,
/* Validate/create actions. */
ACTIONS,
@@ -740,13 +762,17 @@ enum index {
#define ITEM_RAW_SIZE \
(sizeof(struct rte_flow_item_raw) + ITEM_RAW_PATTERN_SIZE)
-/** Maximum size for external pattern in struct rte_flow_action_modify_data. */
-#define ACTION_MODIFY_PATTERN_SIZE 32
+static const char *const compare_ops[] = {
+ "eq", "ne", "lt", "le", "gt", "ge", NULL
+};
+
+/** Maximum size for external pattern in struct rte_flow_field_data. */
+#define FLOW_FIELD_PATTERN_SIZE 32
/** Storage size for struct rte_flow_action_modify_field including pattern. */
#define ACTION_MODIFY_SIZE \
(sizeof(struct rte_flow_action_modify_field) + \
- ACTION_MODIFY_PATTERN_SIZE)
+ FLOW_FIELD_PATTERN_SIZE)
/** Maximum number of queue indices in struct rte_flow_action_rss. */
#define ACTION_RSS_QUEUE_NUM 128
@@ -940,7 +966,7 @@ static const char *const modify_field_ops[] = {
"set", "add", "sub", NULL
};
-static const char *const modify_field_ids[] = {
+static const char *const flow_field_ids[] = {
"start", "mac_dst", "mac_src",
"vlan_type", "vlan_id", "mac_type",
"ipv4_dscp", "ipv4_ttl", "ipv4_src", "ipv4_dst",
@@ -1590,6 +1616,7 @@ static const enum index next_item[] = {
ITEM_IB_BTH,
ITEM_PTYPE,
ITEM_NSH,
+ ITEM_COMPARE,
END_SET,
ZERO,
};
@@ -2121,6 +2148,38 @@ static const enum index item_nsh[] = {
ZERO,
};
+static const enum index item_compare_field[] = {
+ ITEM_COMPARE_OP,
+ ITEM_COMPARE_FIELD_A_TYPE,
+ ITEM_COMPARE_FIELD_B_TYPE,
+ ITEM_NEXT,
+ ZERO,
+};
+
+static const enum index compare_field_a[] = {
+ ITEM_COMPARE_FIELD_A_TYPE,
+ ITEM_COMPARE_FIELD_A_LEVEL,
+ ITEM_COMPARE_FIELD_A_TAG_INDEX,
+ ITEM_COMPARE_FIELD_A_TYPE_ID,
+ ITEM_COMPARE_FIELD_A_CLASS_ID,
+ ITEM_COMPARE_FIELD_A_OFFSET,
+ ITEM_COMPARE_FIELD_B_TYPE,
+ ZERO,
+};
+
+static const enum index compare_field_b[] = {
+ ITEM_COMPARE_FIELD_B_TYPE,
+ ITEM_COMPARE_FIELD_B_LEVEL,
+ ITEM_COMPARE_FIELD_B_TAG_INDEX,
+ ITEM_COMPARE_FIELD_B_TYPE_ID,
+ ITEM_COMPARE_FIELD_B_CLASS_ID,
+ ITEM_COMPARE_FIELD_B_OFFSET,
+ ITEM_COMPARE_FIELD_B_VALUE,
+ ITEM_COMPARE_FIELD_B_POINTER,
+ ITEM_COMPARE_FIELD_WIDTH,
+ ZERO,
+};
+
static const enum index next_action[] = {
ACTION_END,
ACTION_VOID,
@@ -2863,6 +2922,24 @@ comp_quota_update_name(struct context *ctx, const struct token *token,
static int
comp_qu_mode_name(struct context *ctx, const struct token *token,
unsigned int ent, char *buf, unsigned int size);
+static int
+comp_set_compare_field_id(struct context *ctx, const struct token *token,
+ unsigned int ent, char *buf, unsigned int size);
+static int
+comp_set_compare_op(struct context *ctx, const struct token *token,
+ unsigned int ent, char *buf, unsigned int size);
+static int
+parse_vc_compare_op(struct context *ctx, const struct token *token,
+ const char *str, unsigned int len, void *buf,
+ unsigned int size);
+static int
+parse_vc_compare_field_id(struct context *ctx, const struct token *token,
+ const char *str, unsigned int len, void *buf,
+ unsigned int size);
+static int
+parse_vc_compare_field_level(struct context *ctx, const struct token *token,
+ const char *str, unsigned int len, void *buf,
+ unsigned int size);
struct indlst_conf {
uint32_t id;
@@ -5982,6 +6059,174 @@ static const struct token token_list[] = {
.next = NEXT(item_nsh),
.call = parse_vc,
},
+ [ITEM_COMPARE] = {
+ .name = "compare",
+ .help = "match with the comparison result",
+ .priv = PRIV_ITEM(COMPARE, sizeof(struct rte_flow_item_compare)),
+ .next = NEXT(NEXT_ENTRY(ITEM_COMPARE_OP)),
+ .call = parse_vc,
+ },
+ [ITEM_COMPARE_OP] = {
+ .name = "op",
+ .help = "operation type",
+ .next = NEXT(item_compare_field,
+ NEXT_ENTRY(ITEM_COMPARE_OP_VALUE), item_param),
+ .args = ARGS(ARGS_ENTRY(struct rte_flow_item_compare, operation)),
+ },
+ [ITEM_COMPARE_OP_VALUE] = {
+ .name = "{operation}",
+ .help = "operation type value",
+ .call = parse_vc_compare_op,
+ .comp = comp_set_compare_op,
+ },
+ [ITEM_COMPARE_FIELD_A_TYPE] = {
+ .name = "a_type",
+ .help = "compared field type",
+ .next = NEXT(compare_field_a,
+ NEXT_ENTRY(ITEM_COMPARE_FIELD_A_TYPE_VALUE), item_param),
+ .args = ARGS(ARGS_ENTRY(struct rte_flow_item_compare, a.field)),
+ },
+ [ITEM_COMPARE_FIELD_A_TYPE_VALUE] = {
+ .name = "{a_type}",
+ .help = "compared field type value",
+ .call = parse_vc_compare_field_id,
+ .comp = comp_set_compare_field_id,
+ },
+ [ITEM_COMPARE_FIELD_A_LEVEL] = {
+ .name = "a_level",
+ .help = "compared field level",
+ .next = NEXT(compare_field_a,
+ NEXT_ENTRY(ITEM_COMPARE_FIELD_A_LEVEL_VALUE), item_param),
+ .args = ARGS(ARGS_ENTRY(struct rte_flow_item_compare, a.level)),
+ },
+ [ITEM_COMPARE_FIELD_A_LEVEL_VALUE] = {
+ .name = "{a_level}",
+ .help = "compared field level value",
+ .call = parse_vc_compare_field_level,
+ .comp = comp_none,
+ },
+ [ITEM_COMPARE_FIELD_A_TAG_INDEX] = {
+ .name = "a_tag_index",
+ .help = "compared field tag array",
+ .next = NEXT(compare_field_a,
+ NEXT_ENTRY(COMMON_UNSIGNED), item_param),
+ .args = ARGS(ARGS_ENTRY(struct rte_flow_item_compare,
+ a.tag_index)),
+ },
+ [ITEM_COMPARE_FIELD_A_TYPE_ID] = {
+ .name = "a_type_id",
+ .help = "compared field type ID",
+ .next = NEXT(compare_field_a,
+ NEXT_ENTRY(COMMON_UNSIGNED), item_param),
+ .args = ARGS(ARGS_ENTRY(struct rte_flow_item_compare,
+ a.type)),
+ },
+ [ITEM_COMPARE_FIELD_A_CLASS_ID] = {
+ .name = "a_class",
+ .help = "compared field class ID",
+ .next = NEXT(compare_field_a,
+ NEXT_ENTRY(COMMON_UNSIGNED), item_param),
+ .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_compare,
+ a.class_id)),
+ },
+ [ITEM_COMPARE_FIELD_A_OFFSET] = {
+ .name = "a_offset",
+ .help = "compared field bit offset",
+ .next = NEXT(compare_field_a,
+ NEXT_ENTRY(COMMON_UNSIGNED), item_param),
+ .args = ARGS(ARGS_ENTRY(struct rte_flow_item_compare,
+ a.offset)),
+ },
+ [ITEM_COMPARE_FIELD_B_TYPE] = {
+ .name = "b_type",
+ .help = "comparator field type",
+ .next = NEXT(compare_field_b,
+ NEXT_ENTRY(ITEM_COMPARE_FIELD_B_TYPE_VALUE), item_param),
+ .args = ARGS(ARGS_ENTRY(struct rte_flow_item_compare,
+ b.field)),
+ },
+ [ITEM_COMPARE_FIELD_B_TYPE_VALUE] = {
+ .name = "{b_type}",
+ .help = "comparator field type value",
+ .call = parse_vc_compare_field_id,
+ .comp = comp_set_compare_field_id,
+ },
+ [ITEM_COMPARE_FIELD_B_LEVEL] = {
+ .name = "b_level",
+ .help = "comparator field level",
+ .next = NEXT(compare_field_b,
+ NEXT_ENTRY(ITEM_COMPARE_FIELD_B_LEVEL_VALUE), item_param),
+ .args = ARGS(ARGS_ENTRY(struct rte_flow_item_compare,
+ b.level)),
+ },
+ [ITEM_COMPARE_FIELD_B_LEVEL_VALUE] = {
+ .name = "{b_level}",
+ .help = "comparator field level value",
+ .call = parse_vc_compare_field_level,
+ .comp = comp_none,
+ },
+ [ITEM_COMPARE_FIELD_B_TAG_INDEX] = {
+ .name = "b_tag_index",
+ .help = "comparator field tag array",
+ .next = NEXT(compare_field_b,
+ NEXT_ENTRY(COMMON_UNSIGNED), item_param),
+ .args = ARGS(ARGS_ENTRY(struct rte_flow_item_compare,
+ b.tag_index)),
+ },
+ [ITEM_COMPARE_FIELD_B_TYPE_ID] = {
+ .name = "b_type_id",
+ .help = "comparator field type ID",
+ .next = NEXT(compare_field_b,
+ NEXT_ENTRY(COMMON_UNSIGNED), item_param),
+ .args = ARGS(ARGS_ENTRY(struct rte_flow_item_compare,
+ b.type)),
+ },
+ [ITEM_COMPARE_FIELD_B_CLASS_ID] = {
+ .name = "b_class",
+ .help = "comparator field class ID",
+ .next = NEXT(compare_field_b,
+ NEXT_ENTRY(COMMON_UNSIGNED), item_param),
+ .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_compare,
+ b.class_id)),
+ },
+ [ITEM_COMPARE_FIELD_B_OFFSET] = {
+ .name = "b_offset",
+ .help = "comparator field bit offset",
+ .next = NEXT(compare_field_b,
+ NEXT_ENTRY(COMMON_UNSIGNED), item_param),
+ .args = ARGS(ARGS_ENTRY(struct rte_flow_item_compare,
+ b.offset)),
+ },
+ [ITEM_COMPARE_FIELD_B_VALUE] = {
+ .name = "b_value",
+ .help = "comparator immediate value",
+ .next = NEXT(compare_field_b,
+ NEXT_ENTRY(COMMON_HEX), item_param),
+ .args = ARGS(ARGS_ENTRY_ARB(0, 0),
+ ARGS_ENTRY_ARB(0, 0),
+ ARGS_ENTRY(struct rte_flow_item_compare,
+ b.value)),
+ },
+ [ITEM_COMPARE_FIELD_B_POINTER] = {
+ .name = "b_ptr",
+ .help = "pointer to comparator immediate value",
+ .next = NEXT(compare_field_b,
+ NEXT_ENTRY(COMMON_HEX), item_param),
+ .args = ARGS(ARGS_ENTRY(struct rte_flow_item_compare,
+ b.pvalue),
+ ARGS_ENTRY_ARB(0, 0),
+ ARGS_ENTRY_ARB
+ (sizeof(struct rte_flow_item_compare),
+ FLOW_FIELD_PATTERN_SIZE)),
+ },
+ [ITEM_COMPARE_FIELD_WIDTH] = {
+ .name = "width",
+ .help = "number of bits to compare",
+ .next = NEXT(item_compare_field,
+ NEXT_ENTRY(COMMON_UNSIGNED), item_param),
+ .args = ARGS(ARGS_ENTRY(struct rte_flow_item_compare,
+ width)),
+ },
/* Validate/create actions. */
[ACTIONS] = {
@@ -6961,7 +7206,7 @@ static const struct token token_list[] = {
ARGS_ENTRY_ARB(0, 0),
ARGS_ENTRY_ARB
(sizeof(struct rte_flow_action_modify_field),
- ACTION_MODIFY_PATTERN_SIZE)),
+ FLOW_FIELD_PATTERN_SIZE)),
.call = parse_vc_conf,
},
[ACTION_MODIFY_FIELD_WIDTH] = {
@@ -8404,6 +8649,122 @@ parse_vc_item_l2tpv2_type(struct context *ctx, const struct token *token,
return len;
}
+/** Parse operation for compare match item. */
+static int
+parse_vc_compare_op(struct context *ctx, const struct token *token,
+ const char *str, unsigned int len, void *buf,
+ unsigned int size)
+{
+ struct rte_flow_item_compare *compare_item;
+ unsigned int i;
+
+ (void)token;
+ (void)buf;
+ (void)size;
+ if (ctx->curr != ITEM_COMPARE_OP_VALUE)
+ return -1;
+ for (i = 0; compare_ops[i]; ++i)
+ if (!strcmp_partial(compare_ops[i], str, len))
+ break;
+ if (!compare_ops[i])
+ return -1;
+ if (!ctx->object)
+ return len;
+ compare_item = ctx->object;
+ compare_item->operation = (enum rte_flow_item_compare_op)i;
+ return len;
+}
+
+/** Parse id for compare match item. */
+static int
+parse_vc_compare_field_id(struct context *ctx, const struct token *token,
+ const char *str, unsigned int len, void *buf,
+ unsigned int size)
+{
+ struct rte_flow_item_compare *compare_item;
+ unsigned int i;
+
+ (void)token;
+ (void)buf;
+ (void)size;
+ if (ctx->curr != ITEM_COMPARE_FIELD_A_TYPE_VALUE &&
+ ctx->curr != ITEM_COMPARE_FIELD_B_TYPE_VALUE)
+ return -1;
+ for (i = 0; flow_field_ids[i]; ++i)
+ if (!strcmp_partial(flow_field_ids[i], str, len))
+ break;
+ if (!flow_field_ids[i])
+ return -1;
+ if (!ctx->object)
+ return len;
+ compare_item = ctx->object;
+ if (ctx->curr == ITEM_COMPARE_FIELD_A_TYPE_VALUE)
+ compare_item->a.field = (enum rte_flow_field_id)i;
+ else
+ compare_item->b.field = (enum rte_flow_field_id)i;
+ return len;
+}
+
+/** Parse level for compare match item. */
+static int
+parse_vc_compare_field_level(struct context *ctx, const struct token *token,
+ const char *str, unsigned int len, void *buf,
+ unsigned int size)
+{
+ struct rte_flow_item_compare *compare_item;
+ struct flex_item *fp = NULL;
+ uint32_t val;
+ struct buffer *out = buf;
+ char *end;
+
+ (void)token;
+ (void)size;
+ if (ctx->curr != ITEM_COMPARE_FIELD_A_LEVEL_VALUE &&
+ ctx->curr != ITEM_COMPARE_FIELD_B_LEVEL_VALUE)
+ return -1;
+ if (!ctx->object)
+ return len;
+ compare_item = ctx->object;
+ errno = 0;
+ val = strtoumax(str, &end, 0);
+ if (errno || (size_t)(end - str) != len)
+ return -1;
+ /* No need to validate action template mask value */
+ if (out->args.vc.masks) {
+ if (ctx->curr == ITEM_COMPARE_FIELD_A_LEVEL_VALUE)
+ compare_item->a.level = val;
+ else
+ compare_item->b.level = val;
+ return len;
+ }
+ if ((ctx->curr == ITEM_COMPARE_FIELD_A_LEVEL_VALUE &&
+ compare_item->a.field == RTE_FLOW_FIELD_FLEX_ITEM) ||
+ (ctx->curr == ITEM_COMPARE_FIELD_B_LEVEL_VALUE &&
+ compare_item->b.field == RTE_FLOW_FIELD_FLEX_ITEM)) {
+ if (val >= FLEX_MAX_PARSERS_NUM) {
+ printf("Bad flex item handle\n");
+ return -1;
+ }
+ fp = flex_items[ctx->port][val];
+ if (!fp) {
+ printf("Bad flex item handle\n");
+ return -1;
+ }
+ }
+ if (ctx->curr == ITEM_COMPARE_FIELD_A_LEVEL_VALUE) {
+ if (compare_item->a.field != RTE_FLOW_FIELD_FLEX_ITEM)
+ compare_item->a.level = val;
+ else
+ compare_item->a.flex_handle = fp->flex_handle;
+ } else if (ctx->curr == ITEM_COMPARE_FIELD_B_LEVEL_VALUE) {
+ if (compare_item->b.field != RTE_FLOW_FIELD_FLEX_ITEM)
+ compare_item->b.level = val;
+ else
+ compare_item->b.flex_handle = fp->flex_handle;
+ }
+ return len;
+}
+
/** Parse meter color action type. */
static int
parse_vc_action_meter_color_type(struct context *ctx, const struct token *token,
@@ -9773,10 +10134,10 @@ parse_vc_modify_field_id(struct context *ctx, const struct token *token,
if (ctx->curr != ACTION_MODIFY_FIELD_DST_TYPE_VALUE &&
ctx->curr != ACTION_MODIFY_FIELD_SRC_TYPE_VALUE)
return -1;
- for (i = 0; modify_field_ids[i]; ++i)
- if (!strcmp_partial(modify_field_ids[i], str, len))
+ for (i = 0; flow_field_ids[i]; ++i)
+ if (!strcmp_partial(flow_field_ids[i], str, len))
break;
- if (!modify_field_ids[i])
+ if (!flow_field_ids[i])
return -1;
if (!ctx->object)
return len;
@@ -11890,6 +12251,39 @@ comp_rule_id(struct context *ctx, const struct token *token,
return i;
}
+/** Complete operation for compare match item. */
+static int
+comp_set_compare_op(struct context *ctx, const struct token *token,
+ unsigned int ent, char *buf, unsigned int size)
+{
+ RTE_SET_USED(ctx);
+ RTE_SET_USED(token);
+ if (!buf)
+ return RTE_DIM(compare_ops);
+ if (ent < RTE_DIM(compare_ops) - 1)
+ return strlcpy(buf, compare_ops[ent], size);
+ return -1;
+}
+
+/** Complete field id for compare match item. */
+static int
+comp_set_compare_field_id(struct context *ctx, const struct token *token,
+ unsigned int ent, char *buf, unsigned int size)
+{
+ const char *name;
+
+ RTE_SET_USED(token);
+ if (!buf)
+ return RTE_DIM(flow_field_ids);
+ if (ent >= RTE_DIM(flow_field_ids) - 1)
+ return -1;
+ name = flow_field_ids[ent];
+ if (ctx->curr == ITEM_COMPARE_FIELD_B_TYPE ||
+ (strcmp(name, "pointer") && strcmp(name, "value")))
+ return strlcpy(buf, name, size);
+ return -1;
+}
+
/** Complete type field for RSS action. */
static int
comp_vc_action_rss_type(struct context *ctx, const struct token *token,
@@ -12003,10 +12397,10 @@ comp_set_modify_field_id(struct context *ctx, const struct token *token,
RTE_SET_USED(token);
if (!buf)
- return RTE_DIM(modify_field_ids);
- if (ent >= RTE_DIM(modify_field_ids) - 1)
+ return RTE_DIM(flow_field_ids);
+ if (ent >= RTE_DIM(flow_field_ids) - 1)
return -1;
- name = modify_field_ids[ent];
+ name = flow_field_ids[ent];
if (ctx->curr == ACTION_MODIFY_FIELD_SRC_TYPE ||
(strcmp(name, "pointer") && strcmp(name, "value")))
return strlcpy(buf, name, size);
@@ -87,6 +87,7 @@ aggr_affinity =
ah =
any =
arp_eth_ipv4 =
+compare =
conntrack =
ecpri =
esp =
@@ -1573,6 +1573,13 @@ Matches the packet type as defined in rte_mbuf_ptype.
- ``packet_type``: L2/L3/L4 and tunnel information.
+Item: ``COMPARE``
+^^^^^^^^^^^^^^^^^
+
+Matches the comparison result between packet fields or value.
+
+- ``compare``: Comparison information.
+
Actions
~~~~~~~
@@ -55,6 +55,11 @@ New Features
Also, make sure to start the actual text at the margin.
=======================================================
+* **Added compare flow matching criteria.**
+
+ Added ``RTE_FLOW_ITEM_TYPE_COMPARE`` to allow matching on compare
+ result between the packet fields or value.
+
* **Updated NVIDIA mlx5 driver.**
* Added support for accumulating from src field to dst field.
@@ -3841,6 +3841,12 @@ This section lists supported pattern items and their attributes, if any.
- ``packet_type {unsigned}``: packet type.
+- ``compare``: match the comparison result between packet fields or value.
+
+ - ``op {string}``: comparison operation type.
+ - ``a_type {string}``: compared field.
+ - ``b_type {string}``: comparator field.
+ - ``width {unsigned}``: comparison width.
Actions list
^^^^^^^^^^^^
@@ -167,6 +167,7 @@ static const struct rte_flow_desc_data rte_flow_desc_item[] = {
MK_FLOW_ITEM(TX_QUEUE, sizeof(struct rte_flow_item_tx_queue)),
MK_FLOW_ITEM(IB_BTH, sizeof(struct rte_flow_item_ib_bth)),
MK_FLOW_ITEM(PTYPE, sizeof(struct rte_flow_item_ptype)),
+ MK_FLOW_ITEM(COMPARE, sizeof(struct rte_flow_item_compare)),
};
/** Generate flow_action[] entry. */
@@ -704,6 +704,13 @@ enum rte_flow_item_type {
*
*/
RTE_FLOW_ITEM_TYPE_PTYPE,
+
+ /**
+ * Matches the packet with compare result.
+ *
+ * See struct rte_flow_item_compare.
+ */
+ RTE_FLOW_ITEM_TYPE_COMPARE,
};
/**
@@ -2336,6 +2343,177 @@ static const struct rte_flow_item_ptype rte_flow_item_ptype_mask = {
};
#endif
+/**
+ * Field IDs for packet field.
+ */
+enum rte_flow_field_id {
+ RTE_FLOW_FIELD_START = 0, /**< Start of a packet. */
+ RTE_FLOW_FIELD_MAC_DST, /**< Destination MAC Address. */
+ RTE_FLOW_FIELD_MAC_SRC, /**< Source MAC Address. */
+ RTE_FLOW_FIELD_VLAN_TYPE, /**< VLAN Tag Identifier. */
+ RTE_FLOW_FIELD_VLAN_ID, /**< VLAN Identifier. */
+ RTE_FLOW_FIELD_MAC_TYPE, /**< EtherType. */
+ RTE_FLOW_FIELD_IPV4_DSCP, /**< IPv4 DSCP. */
+ RTE_FLOW_FIELD_IPV4_TTL, /**< IPv4 Time To Live. */
+ RTE_FLOW_FIELD_IPV4_SRC, /**< IPv4 Source Address. */
+ RTE_FLOW_FIELD_IPV4_DST, /**< IPv4 Destination Address. */
+ RTE_FLOW_FIELD_IPV6_DSCP, /**< IPv6 DSCP. */
+ RTE_FLOW_FIELD_IPV6_HOPLIMIT, /**< IPv6 Hop Limit. */
+ RTE_FLOW_FIELD_IPV6_SRC, /**< IPv6 Source Address. */
+ RTE_FLOW_FIELD_IPV6_DST, /**< IPv6 Destination Address. */
+ RTE_FLOW_FIELD_TCP_PORT_SRC, /**< TCP Source Port Number. */
+ RTE_FLOW_FIELD_TCP_PORT_DST, /**< TCP Destination Port Number. */
+ RTE_FLOW_FIELD_TCP_SEQ_NUM, /**< TCP Sequence Number. */
+ RTE_FLOW_FIELD_TCP_ACK_NUM, /**< TCP Acknowledgment Number. */
+ RTE_FLOW_FIELD_TCP_FLAGS, /**< TCP Flags. */
+ RTE_FLOW_FIELD_UDP_PORT_SRC, /**< UDP Source Port Number. */
+ RTE_FLOW_FIELD_UDP_PORT_DST, /**< UDP Destination Port Number. */
+ RTE_FLOW_FIELD_VXLAN_VNI, /**< VXLAN Network Identifier. */
+ RTE_FLOW_FIELD_GENEVE_VNI, /**< GENEVE Network Identifier. */
+ RTE_FLOW_FIELD_GTP_TEID, /**< GTP Tunnel Endpoint Identifier. */
+ RTE_FLOW_FIELD_TAG, /**< Tag value. */
+ RTE_FLOW_FIELD_MARK, /**< Mark value. */
+ RTE_FLOW_FIELD_META, /**< Metadata value. */
+ RTE_FLOW_FIELD_POINTER, /**< Memory pointer. */
+ RTE_FLOW_FIELD_VALUE, /**< Immediate value. */
+ RTE_FLOW_FIELD_IPV4_ECN, /**< IPv4 ECN. */
+ RTE_FLOW_FIELD_IPV6_ECN, /**< IPv6 ECN. */
+ RTE_FLOW_FIELD_GTP_PSC_QFI, /**< GTP QFI. */
+ RTE_FLOW_FIELD_METER_COLOR, /**< Meter color marker. */
+ RTE_FLOW_FIELD_IPV6_PROTO, /**< IPv6 next header. */
+ RTE_FLOW_FIELD_FLEX_ITEM, /**< Flex item. */
+ RTE_FLOW_FIELD_HASH_RESULT, /**< Hash result. */
+ RTE_FLOW_FIELD_GENEVE_OPT_TYPE, /**< GENEVE option type. */
+ RTE_FLOW_FIELD_GENEVE_OPT_CLASS,/**< GENEVE option class. */
+ RTE_FLOW_FIELD_GENEVE_OPT_DATA, /**< GENEVE option data. */
+ RTE_FLOW_FIELD_MPLS, /**< MPLS header. */
+ RTE_FLOW_FIELD_TCP_DATA_OFFSET, /**< TCP data offset. */
+ RTE_FLOW_FIELD_IPV4_IHL, /**< IPv4 IHL. */
+ RTE_FLOW_FIELD_IPV4_TOTAL_LEN, /**< IPv4 total length. */
+ RTE_FLOW_FIELD_IPV6_PAYLOAD_LEN /**< IPv6 payload length. */
+};
+
+/**
+ * @warning
+ * @b EXPERIMENTAL: this structure may change without prior notice
+ *
+ * Field description for packet field.
+ */
+struct rte_flow_field_data {
+ enum rte_flow_field_id field; /**< Field or memory type ID. */
+ union {
+ struct {
+ /** Encapsulation level and tag index or flex item handle. */
+ union {
+ struct {
+ /**
+ * Packet encapsulation level containing
+ * the field related with.
+ *
+ * - @p 0 requests the default behavior.
+ * Depending on the packet type, it
+ * can mean outermost, innermost or
+ * anything in between.
+ *
+ * It basically stands for the
+ * innermost encapsulation level.
+ * Modification can be performed
+ * according to PMD and device
+ * capabilities.
+ *
+ * - @p 1 requests modification to be
+ * performed on the outermost packet
+ * encapsulation level.
+ *
+ * - @p 2 and subsequent values request
+ * modification to be performed on
+ * the specified inner packet
+ * encapsulation level, from
+ * outermost to innermost (lower to
+ * higher values).
+ *
+ * Values other than @p 0 are not
+ * necessarily supported.
+ *
+ * @note that for MPLS field,
+ * encapsulation level also include
+ * tunnel since MPLS may appear in
+ * outer, inner or tunnel.
+ */
+ uint8_t level;
+ union {
+ /**
+ * Tag index array inside
+ * encapsulation level.
+ * Used for VLAN, MPLS or TAG types.
+ */
+ uint8_t tag_index;
+ /**
+ * Geneve option identifier.
+ * Relevant only for
+ * RTE_FLOW_FIELD_GENEVE_OPT_XXXX
+ * type.
+ */
+ struct {
+ /**
+ * Geneve option type.
+ */
+ uint8_t type;
+ /**
+ * Geneve option class.
+ */
+ rte_be16_t class_id;
+ };
+ };
+ };
+ struct rte_flow_item_flex_handle *flex_handle;
+ };
+ /** Number of bits to skip from a field. */
+ uint32_t offset;
+ };
+ /**
+ * Immediate value for RTE_FLOW_FIELD_VALUE, presented in the
+ * same byte order and length as in relevant rte_flow_item_xxx.
+ * The immediate source bitfield offset is inherited from
+ * the destination's one.
+ */
+ uint8_t value[16];
+ /**
+ * Memory address for RTE_FLOW_FIELD_POINTER, memory layout
+ * should be the same as for relevant field in the
+ * rte_flow_item_xxx structure.
+ */
+ void *pvalue;
+ };
+};
+
+/**
+ * Expected operation types for compare item.
+ */
+enum rte_flow_item_compare_op {
+ RTE_FLOW_ITEM_COMPARE_EQ, /* Compare result equal. */
+ RTE_FLOW_ITEM_COMPARE_NE, /* Compare result not equal. */
+ RTE_FLOW_ITEM_COMPARE_LT, /* Compare result less than. */
+ RTE_FLOW_ITEM_COMPARE_LE, /* Compare result less than or equal. */
+ RTE_FLOW_ITEM_COMPARE_GT, /* Compare result great than. */
+ RTE_FLOW_ITEM_COMPARE_GE, /* Compare result great than or equal. */
+};
+
+/**
+ *
+ * RTE_FLOW_ITEM_TYPE_COMPARE
+ *
+ * Matches the packet with compare result.
+ *
+ * The operation means a compare with b result.
+ */
+struct rte_flow_item_compare {
+ enum rte_flow_item_compare_op operation; /* The compare operation. */
+ struct rte_flow_field_data a; /* Field be compared. */
+ struct rte_flow_field_data b; /* Field as comparator. */
+ uint32_t width; /* Compare width. */
+};
+
/**
* Action types.
*
@@ -3857,56 +4035,8 @@ struct rte_flow_action_ethdev {
};
/**
- * Field IDs for MODIFY_FIELD action.
- */
-enum rte_flow_field_id {
- RTE_FLOW_FIELD_START = 0, /**< Start of a packet. */
- RTE_FLOW_FIELD_MAC_DST, /**< Destination MAC Address. */
- RTE_FLOW_FIELD_MAC_SRC, /**< Source MAC Address. */
- RTE_FLOW_FIELD_VLAN_TYPE, /**< VLAN Tag Identifier. */
- RTE_FLOW_FIELD_VLAN_ID, /**< VLAN Identifier. */
- RTE_FLOW_FIELD_MAC_TYPE, /**< EtherType. */
- RTE_FLOW_FIELD_IPV4_DSCP, /**< IPv4 DSCP. */
- RTE_FLOW_FIELD_IPV4_TTL, /**< IPv4 Time To Live. */
- RTE_FLOW_FIELD_IPV4_SRC, /**< IPv4 Source Address. */
- RTE_FLOW_FIELD_IPV4_DST, /**< IPv4 Destination Address. */
- RTE_FLOW_FIELD_IPV6_DSCP, /**< IPv6 DSCP. */
- RTE_FLOW_FIELD_IPV6_HOPLIMIT, /**< IPv6 Hop Limit. */
- RTE_FLOW_FIELD_IPV6_SRC, /**< IPv6 Source Address. */
- RTE_FLOW_FIELD_IPV6_DST, /**< IPv6 Destination Address. */
- RTE_FLOW_FIELD_TCP_PORT_SRC, /**< TCP Source Port Number. */
- RTE_FLOW_FIELD_TCP_PORT_DST, /**< TCP Destination Port Number. */
- RTE_FLOW_FIELD_TCP_SEQ_NUM, /**< TCP Sequence Number. */
- RTE_FLOW_FIELD_TCP_ACK_NUM, /**< TCP Acknowledgment Number. */
- RTE_FLOW_FIELD_TCP_FLAGS, /**< TCP Flags. */
- RTE_FLOW_FIELD_UDP_PORT_SRC, /**< UDP Source Port Number. */
- RTE_FLOW_FIELD_UDP_PORT_DST, /**< UDP Destination Port Number. */
- RTE_FLOW_FIELD_VXLAN_VNI, /**< VXLAN Network Identifier. */
- RTE_FLOW_FIELD_GENEVE_VNI, /**< GENEVE Network Identifier. */
- RTE_FLOW_FIELD_GTP_TEID, /**< GTP Tunnel Endpoint Identifier. */
- RTE_FLOW_FIELD_TAG, /**< Tag value. */
- RTE_FLOW_FIELD_MARK, /**< Mark value. */
- RTE_FLOW_FIELD_META, /**< Metadata value. */
- RTE_FLOW_FIELD_POINTER, /**< Memory pointer. */
- RTE_FLOW_FIELD_VALUE, /**< Immediate value. */
- RTE_FLOW_FIELD_IPV4_ECN, /**< IPv4 ECN. */
- RTE_FLOW_FIELD_IPV6_ECN, /**< IPv6 ECN. */
- RTE_FLOW_FIELD_GTP_PSC_QFI, /**< GTP QFI. */
- RTE_FLOW_FIELD_METER_COLOR, /**< Meter color marker. */
- RTE_FLOW_FIELD_IPV6_PROTO, /**< IPv6 next header. */
- RTE_FLOW_FIELD_FLEX_ITEM, /**< Flex item. */
- RTE_FLOW_FIELD_HASH_RESULT, /**< Hash result. */
- RTE_FLOW_FIELD_GENEVE_OPT_TYPE, /**< GENEVE option type. */
- RTE_FLOW_FIELD_GENEVE_OPT_CLASS,/**< GENEVE option class. */
- RTE_FLOW_FIELD_GENEVE_OPT_DATA, /**< GENEVE option data. */
- RTE_FLOW_FIELD_MPLS, /**< MPLS header. */
- RTE_FLOW_FIELD_TCP_DATA_OFFSET, /**< TCP data offset. */
- RTE_FLOW_FIELD_IPV4_IHL, /**< IPv4 IHL. */
- RTE_FLOW_FIELD_IPV4_TOTAL_LEN, /**< IPv4 total length. */
- RTE_FLOW_FIELD_IPV6_PAYLOAD_LEN /**< IPv6 payload length. */
-};
-
-/**
+ * @deprecated
+ * @see rte_flow_field_data
* @warning
* @b EXPERIMENTAL: this structure may change without prior notice
*