ethdev: add flow tag

A tag is a transient data which can be used during flow match. This can be
used to store match result from a previous table so that the same pattern
need not be matched again on the next table. Even if outer header is
decapsulated on the previous match, the match result can be kept.

Some device expose internal registers of its flow processing pipeline and
those registers are quite useful for stateful connection tracking as it
keeps status of flow matching. Multiple tags are supported by specifying
index.

Example testpmd commands are:

  flow create 0 ingress pattern ... / end
    actions set_tag index 2 value 0xaa00bb mask 0xffff00ff /
            set_tag index 3 value 0x123456 mask 0xffffff /
            vxlan_decap / jump group 1 / end

  flow create 0 ingress pattern ... / end
    actions set_tag index 2 value 0xcc00 mask 0xff00 /
            set_tag index 3 value 0x123456 mask 0xffffff /
            vxlan_decap / jump group 1 / end

  flow create 0 ingress group 1
    pattern tag index is 2 value spec 0xaa00bb value mask 0xffff00ff /
            eth ... / end
    actions ... jump group 2 / end

  flow create 0 ingress group 1
    pattern tag index is 2 value spec 0xcc00 value mask 0xff00 /
            tag index is 3 value spec 0x123456 value mask 0xffffff /
            eth ... / end
    actions ... / end

  flow create 0 ingress group 2
    pattern tag index is 3 value spec 0x123456 value mask 0xffffff /
            eth ... / end
    actions ... / end

Signed-off-by: Yongseok Koh <yskoh@mellanox.com>
Signed-off-by: Viacheslav Ovsiienko <viacheslavo@mellanox.com>
Acked-by: Ori Kam <orika@mellanox.com>
This commit is contained in:
Viacheslav Ovsiienko 2019-10-27 18:42:28 +00:00 committed by Ferruh Yigit
parent 2ed50762bd
commit 9a2f44c762
5 changed files with 196 additions and 3 deletions

View File

@ -210,6 +210,9 @@ enum index {
ITEM_HIGIG2, ITEM_HIGIG2,
ITEM_HIGIG2_CLASSIFICATION, ITEM_HIGIG2_CLASSIFICATION,
ITEM_HIGIG2_VID, ITEM_HIGIG2_VID,
ITEM_TAG,
ITEM_TAG_DATA,
ITEM_TAG_INDEX,
/* Validate/create actions. */ /* Validate/create actions. */
ACTIONS, ACTIONS,
@ -316,6 +319,10 @@ enum index {
ACTION_RAW_ENCAP_INDEX_VALUE, ACTION_RAW_ENCAP_INDEX_VALUE,
ACTION_RAW_DECAP_INDEX, ACTION_RAW_DECAP_INDEX,
ACTION_RAW_DECAP_INDEX_VALUE, ACTION_RAW_DECAP_INDEX_VALUE,
ACTION_SET_TAG,
ACTION_SET_TAG_DATA,
ACTION_SET_TAG_INDEX,
ACTION_SET_TAG_MASK,
}; };
/** Maximum size for pattern in struct rte_flow_item_raw. */ /** Maximum size for pattern in struct rte_flow_item_raw. */
@ -735,6 +742,7 @@ static const enum index next_item[] = {
ITEM_PPPOED, ITEM_PPPOED,
ITEM_PPPOE_PROTO_ID, ITEM_PPPOE_PROTO_ID,
ITEM_HIGIG2, ITEM_HIGIG2,
ITEM_TAG,
END_SET, END_SET,
ZERO, ZERO,
}; };
@ -1012,6 +1020,13 @@ static const enum index next_set_raw[] = {
ZERO, ZERO,
}; };
static const enum index item_tag[] = {
ITEM_TAG_DATA,
ITEM_TAG_INDEX,
ITEM_NEXT,
ZERO,
};
static const enum index next_action[] = { static const enum index next_action[] = {
ACTION_END, ACTION_END,
ACTION_VOID, ACTION_VOID,
@ -1067,6 +1082,7 @@ static const enum index next_action[] = {
ACTION_DEC_TCP_ACK, ACTION_DEC_TCP_ACK,
ACTION_RAW_ENCAP, ACTION_RAW_ENCAP,
ACTION_RAW_DECAP, ACTION_RAW_DECAP,
ACTION_SET_TAG,
ZERO, ZERO,
}; };
@ -1265,6 +1281,14 @@ static const enum index action_raw_decap[] = {
ZERO, ZERO,
}; };
static const enum index action_set_tag[] = {
ACTION_SET_TAG_DATA,
ACTION_SET_TAG_INDEX,
ACTION_SET_TAG_MASK,
ACTION_NEXT,
ZERO,
};
static int parse_set_raw_encap_decap(struct context *, const struct token *, static int parse_set_raw_encap_decap(struct context *, const struct token *,
const char *, unsigned int, const char *, unsigned int,
void *, unsigned int); void *, unsigned int);
@ -2534,6 +2558,26 @@ static const struct token token_list[] = {
.args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_higig2_hdr, .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_higig2_hdr,
hdr.ppt1.vid)), hdr.ppt1.vid)),
}, },
[ITEM_TAG] = {
.name = "tag",
.help = "match tag value",
.priv = PRIV_ITEM(TAG, sizeof(struct rte_flow_item_tag)),
.next = NEXT(item_tag),
.call = parse_vc,
},
[ITEM_TAG_DATA] = {
.name = "data",
.help = "tag value to match",
.next = NEXT(item_tag, NEXT_ENTRY(UNSIGNED), item_param),
.args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_tag, data)),
},
[ITEM_TAG_INDEX] = {
.name = "index",
.help = "index of tag array to match",
.next = NEXT(item_tag, NEXT_ENTRY(UNSIGNED),
NEXT_ENTRY(ITEM_PARAM_IS)),
.args = ARGS(ARGS_ENTRY(struct rte_flow_item_tag, index)),
},
/* Validate/create actions. */ /* Validate/create actions. */
[ACTIONS] = { [ACTIONS] = {
.name = "actions", .name = "actions",
@ -3378,7 +3422,38 @@ static const struct token token_list[] = {
.help = "index of raw_encap/raw_decap data", .help = "index of raw_encap/raw_decap data",
.next = NEXT(next_item), .next = NEXT(next_item),
.call = parse_port, .call = parse_port,
} },
[ACTION_SET_TAG] = {
.name = "set_tag",
.help = "set tag",
.priv = PRIV_ACTION(SET_TAG,
sizeof(struct rte_flow_action_set_tag)),
.next = NEXT(action_set_tag),
.call = parse_vc,
},
[ACTION_SET_TAG_INDEX] = {
.name = "index",
.help = "index of tag array",
.next = NEXT(action_set_tag, NEXT_ENTRY(UNSIGNED)),
.args = ARGS(ARGS_ENTRY(struct rte_flow_action_set_tag, index)),
.call = parse_vc_conf,
},
[ACTION_SET_TAG_DATA] = {
.name = "data",
.help = "tag value",
.next = NEXT(action_set_tag, NEXT_ENTRY(UNSIGNED)),
.args = ARGS(ARGS_ENTRY_HTON
(struct rte_flow_action_set_tag, data)),
.call = parse_vc_conf,
},
[ACTION_SET_TAG_MASK] = {
.name = "mask",
.help = "mask for tag value",
.next = NEXT(action_set_tag, NEXT_ENTRY(UNSIGNED)),
.args = ARGS(ARGS_ENTRY_HTON
(struct rte_flow_action_set_tag, mask)),
.call = parse_vc_conf,
},
}; };
/** Remove and return last entry from argument stack. */ /** Remove and return last entry from argument stack. */

View File

@ -658,8 +658,36 @@ the physical device, with virtual groups in the PMD or not at all.
| ``mask`` | ``id`` | zeroed to match any value | | ``mask`` | ``id`` | zeroed to match any value |
+----------+----------+---------------------------+ +----------+----------+---------------------------+
Data matching item types Item: ``TAG``
~~~~~~~~~~~~~~~~~~~~~~~~ ^^^^^^^^^^^^^
Matches tag item set by other flows. Multiple tags are supported by specifying
``index``.
- Default ``mask`` matches the specified tag value and index.
.. _table_rte_flow_item_tag:
.. table:: TAG
+----------+----------+----------------------------------------+
| Field | Subfield | Value |
+==========+===========+=======================================+
| ``spec`` | ``data`` | 32 bit flow tag value |
| +-----------+---------------------------------------+
| | ``index`` | index of flow tag |
+----------+-----------+---------------------------------------+
| ``last`` | ``data`` | upper range value |
| +-----------+---------------------------------------+
| | ``index`` | field is ignored |
+----------+-----------+---------------------------------------+
| ``mask`` | ``data`` | bit-mask applies to "spec" and "last" |
| +-----------+---------------------------------------+
| | ``index`` | field is ignored |
+----------+-----------+---------------------------------------+
ata matching item types
~~~~~~~~~~~~~~~~~~~~~~~
Most of these are basically protocol header definitions with associated Most of these are basically protocol header definitions with associated
bit-masks. They must be specified (stacked) from lowest to highest protocol bit-masks. They must be specified (stacked) from lowest to highest protocol
@ -2466,6 +2494,28 @@ Value to decrease TCP acknowledgment number by is a big-endian 32 bit integer.
Using this action on non-matching traffic will result in undefined behavior. Using this action on non-matching traffic will result in undefined behavior.
Action: ``SET_TAG``
^^^^^^^^^^^^^^^^^^^
Set Tag.
Tag is a transient data used during flow matching. This is not delivered to
application. Multiple tags are supported by specifying index.
.. _table_rte_flow_action_set_tag:
.. table:: SET_TAG
+-----------+----------------------------+
| Field | Value |
+===========+============================+
| ``data`` | 32 bit tag value |
+-----------+----------------------------+
| ``mask`` | bit-mask applies to "data" |
+-----------+----------------------------+
| ``index`` | index of tag to set |
+-----------+----------------------------+
Negative types Negative types
~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~

View File

@ -82,6 +82,10 @@ New Features
On supported NICs, we can now setup haipin queue which will offload packets On supported NICs, we can now setup haipin queue which will offload packets
from the wire, backto the wire. from the wire, backto the wire.
* **Added flow tag in rte_flow.**
SET_TAG action and TAG item have been added to support transient flow tag.
* **Updated the enic driver.** * **Updated the enic driver.**
* Added support for Geneve with options offload. * Added support for Geneve with options offload.

View File

@ -74,6 +74,7 @@ static const struct rte_flow_desc_data rte_flow_desc_item[] = {
sizeof(struct rte_flow_item_icmp6_nd_opt_tla_eth)), sizeof(struct rte_flow_item_icmp6_nd_opt_tla_eth)),
MK_FLOW_ITEM(MARK, sizeof(struct rte_flow_item_mark)), MK_FLOW_ITEM(MARK, sizeof(struct rte_flow_item_mark)),
MK_FLOW_ITEM(META, sizeof(struct rte_flow_item_meta)), MK_FLOW_ITEM(META, sizeof(struct rte_flow_item_meta)),
MK_FLOW_ITEM(TAG, sizeof(struct rte_flow_item_tag)),
MK_FLOW_ITEM(GRE_KEY, sizeof(rte_be32_t)), MK_FLOW_ITEM(GRE_KEY, sizeof(rte_be32_t)),
MK_FLOW_ITEM(GTP_PSC, sizeof(struct rte_flow_item_gtp_psc)), MK_FLOW_ITEM(GTP_PSC, sizeof(struct rte_flow_item_gtp_psc)),
MK_FLOW_ITEM(PPPOES, sizeof(struct rte_flow_item_pppoe)), MK_FLOW_ITEM(PPPOES, sizeof(struct rte_flow_item_pppoe)),
@ -157,6 +158,7 @@ static const struct rte_flow_desc_data rte_flow_desc_action[] = {
MK_FLOW_ACTION(DEC_TCP_SEQ, sizeof(rte_be32_t)), MK_FLOW_ACTION(DEC_TCP_SEQ, sizeof(rte_be32_t)),
MK_FLOW_ACTION(INC_TCP_ACK, sizeof(rte_be32_t)), MK_FLOW_ACTION(INC_TCP_ACK, sizeof(rte_be32_t)),
MK_FLOW_ACTION(DEC_TCP_ACK, sizeof(rte_be32_t)), MK_FLOW_ACTION(DEC_TCP_ACK, sizeof(rte_be32_t)),
MK_FLOW_ACTION(SET_TAG, sizeof(struct rte_flow_action_set_tag)),
}; };
static int static int

View File

@ -498,6 +498,15 @@ enum rte_flow_item_type {
* see struct rte_flow_item_higig2_hdr. * see struct rte_flow_item_higig2_hdr.
*/ */
RTE_FLOW_ITEM_TYPE_HIGIG2, RTE_FLOW_ITEM_TYPE_HIGIG2,
/*
* [META]
*
* Matches a tag value.
*
* See struct rte_flow_item_tag.
*/
RTE_FLOW_ITEM_TYPE_TAG,
}; };
/** /**
@ -1335,6 +1344,27 @@ rte_flow_item_pppoe_proto_id_mask = {
}; };
#endif #endif
/**
* @warning
* @b EXPERIMENTAL: this structure may change without prior notice
*
* RTE_FLOW_ITEM_TYPE_TAG
*
* Matches a specified tag value at the specified index.
*/
struct rte_flow_item_tag {
uint32_t data;
uint8_t index;
};
/** Default mask for RTE_FLOW_ITEM_TYPE_TAG. */
#ifndef __cplusplus
static const struct rte_flow_item_tag rte_flow_item_tag_mask = {
.data = 0xffffffff,
.index = 0xff,
};
#endif
/** /**
* @warning * @warning
* @b EXPERIMENTAL: this structure may change without prior notice * @b EXPERIMENTAL: this structure may change without prior notice
@ -1357,6 +1387,13 @@ struct rte_flow_item_mark {
uint32_t id; /**< Integer value to match against. */ uint32_t id; /**< Integer value to match against. */
}; };
/** Default mask for RTE_FLOW_ITEM_TYPE_MARK. */
#ifndef __cplusplus
static const struct rte_flow_item_mark rte_flow_item_mark_mask = {
.id = 0xffffffff,
};
#endif
/** /**
* @warning * @warning
* @b EXPERIMENTAL: this structure may change without prior notice * @b EXPERIMENTAL: this structure may change without prior notice
@ -1942,6 +1979,16 @@ enum rte_flow_action_type {
* undefined behavior. * undefined behavior.
*/ */
RTE_FLOW_ACTION_TYPE_DEC_TCP_ACK, RTE_FLOW_ACTION_TYPE_DEC_TCP_ACK,
/**
* Set Tag.
*
* Tag is for internal flow usage only and
* is not delivered to the application.
*
* See struct rte_flow_action_set_tag.
*/
RTE_FLOW_ACTION_TYPE_SET_TAG,
}; };
/** /**
@ -2429,6 +2476,21 @@ struct rte_flow_action_set_mac {
uint8_t mac_addr[RTE_ETHER_ADDR_LEN]; uint8_t mac_addr[RTE_ETHER_ADDR_LEN];
}; };
/**
* @warning
* @b EXPERIMENTAL: this structure may change without prior notice
*
* RTE_FLOW_ACTION_TYPE_SET_TAG
*
* Set a tag which is a transient data used during flow matching. This is not
* delivered to application. Multiple tags are supported by specifying index.
*/
struct rte_flow_action_set_tag {
uint32_t data;
uint32_t mask;
uint8_t index;
};
/* /*
* Definition of a single action. * Definition of a single action.
* *