From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from dpdk.org (dpdk.org [92.243.14.124]) by inbox.dpdk.org (Postfix) with ESMTP id B014DA3160 for ; Thu, 10 Oct 2019 18:02:47 +0200 (CEST) Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id 44EF91E9C9; Thu, 10 Oct 2019 18:02:47 +0200 (CEST) Received: from mellanox.co.il (mail-il-dmz.mellanox.com [193.47.165.129]) by dpdk.org (Postfix) with ESMTP id 539961E9C8 for ; Thu, 10 Oct 2019 18:02:46 +0200 (CEST) Received: from Internal Mail-Server by MTLPINE1 (envelope-from viacheslavo@mellanox.com) with ESMTPS (AES256-SHA encrypted); 10 Oct 2019 18:02:42 +0200 Received: from pegasus11.mtr.labs.mlnx (pegasus11.mtr.labs.mlnx [10.210.16.104]) by labmailer.mlnx (8.13.8/8.13.8) with ESMTP id x9AG2fSN015923; Thu, 10 Oct 2019 19:02:41 +0300 Received: from pegasus11.mtr.labs.mlnx (localhost [127.0.0.1]) by pegasus11.mtr.labs.mlnx (8.14.7/8.14.7) with ESMTP id x9AG2fcJ024813; Thu, 10 Oct 2019 16:02:41 GMT Received: (from viacheslavo@localhost) by pegasus11.mtr.labs.mlnx (8.14.7/8.14.7/Submit) id x9AG2ftK024812; Thu, 10 Oct 2019 16:02:41 GMT X-Authentication-Warning: pegasus11.mtr.labs.mlnx: viacheslavo set sender to viacheslavo@mellanox.com using -f From: Viacheslav Ovsiienko To: dev@dpdk.org Cc: matan@mellanox.com, rasland@mellanox.com, thomas@monjalon.net, olivier.matz@6wind.com, Yongseok Koh Date: Thu, 10 Oct 2019 16:02:39 +0000 Message-Id: <1570723359-24650-1-git-send-email-viacheslavo@mellanox.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <20190704232122.19477-1-yskoh@mellanox.com> References: <20190704232122.19477-1-yskoh@mellanox.com> Subject: [dpdk-dev] [PATCH v2] ethdev: extend flow metadata X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" Currently, metadata can be set on egress path via mbuf tx_metadata field with PKT_TX_METADATA flag and RTE_FLOW_ITEM_TYPE_META matches metadata. This patch extends the metadata feature usability. 1) RTE_FLOW_ACTION_TYPE_SET_META When supporting multiple tables, Tx metadata can also be set by a rule and matched by another rule. This new action allows metadata to be set as a result of flow match. 2) Metadata on ingress There's also need to support metadata on ingress. Metadata can be set by SET_META action and matched by META item like Tx. The final value set by the action will be delivered to application via metadata dynamic field of mbuf which can be accessed by RTE_FLOW_DYNF_METADATA(). PKT_RX_DYNF_METADATA flag will be set along with the data. The mbuf dynamic field must be registered by calling rte_flow_dynf_metadata_register() prior to use SET_META action. The availability of dynamic mbuf metadata field can be checked with rte_flow_dynf_metadata_avail() routine. For loopback/hairpin packet, metadata set on Rx/Tx may or may not be propagated to the other path depending on hardware capability. Signed-off-by: Yongseok Koh Signed-off-by: Viacheslav Ovsiienko --- This patch uses dynamic mbuf field and must be applied after: http://patches.dpdk.org/patch/59343/ "mbuf: support dynamic fields and flags" v2: - rebased - relies on dynamic mbuf field feature v1: http://patches.dpdk.org/patch/56103/ rfc: http://patches.dpdk.org/patch/54270/ app/test-pmd/cmdline_flow.c | 57 ++++++++++++++++++++- app/test-pmd/util.c | 5 ++ doc/guides/prog_guide/rte_flow.rst | 57 +++++++++++++++++++++ doc/guides/rel_notes/release_19_11.rst | 8 +++ lib/librte_ethdev/rte_ethdev.h | 1 - lib/librte_ethdev/rte_ethdev_version.map | 6 +++ lib/librte_ethdev/rte_flow.c | 41 +++++++++++++++ lib/librte_ethdev/rte_flow.h | 87 ++++++++++++++++++++++++++++++-- lib/librte_mbuf/rte_mbuf_dyn.h | 8 +++ 9 files changed, 265 insertions(+), 5 deletions(-) diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c index b26b8bf..078f256 100644 --- a/app/test-pmd/cmdline_flow.c +++ b/app/test-pmd/cmdline_flow.c @@ -305,6 +305,9 @@ enum index { ACTION_DEC_TCP_ACK_VALUE, ACTION_RAW_ENCAP, ACTION_RAW_DECAP, + ACTION_SET_META, + ACTION_SET_META_DATA, + ACTION_SET_META_MASK, }; /** Maximum size for pattern in struct rte_flow_item_raw. */ @@ -994,6 +997,7 @@ struct parse_action_priv { ACTION_DEC_TCP_ACK, ACTION_RAW_ENCAP, ACTION_RAW_DECAP, + ACTION_SET_META, ZERO, }; @@ -1180,6 +1184,13 @@ struct parse_action_priv { ZERO, }; +static const enum index action_set_meta[] = { + ACTION_SET_META_DATA, + ACTION_SET_META_MASK, + ACTION_NEXT, + ZERO, +}; + static int parse_set_raw_encap_decap(struct context *, const struct token *, const char *, unsigned int, void *, unsigned int); @@ -1238,6 +1249,10 @@ static int parse_vc_action_raw_encap(struct context *, static int parse_vc_action_raw_decap(struct context *, const struct token *, const char *, unsigned int, void *, unsigned int); +static int parse_vc_action_set_meta(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); @@ -3222,7 +3237,31 @@ static int comp_vc_action_rss_queue(struct context *, const struct token *, .help = "set raw decap data", .next = NEXT(next_item), .call = parse_set_raw_encap_decap, - } + }, + [ACTION_SET_META] = { + .name = "set_meta", + .help = "set metadata", + .priv = PRIV_ACTION(SET_META, + sizeof(struct rte_flow_action_set_meta)), + .next = NEXT(action_set_meta), + .call = parse_vc_action_set_meta, + }, + [ACTION_SET_META_DATA] = { + .name = "data", + .help = "metadata value", + .next = NEXT(action_set_meta, NEXT_ENTRY(UNSIGNED)), + .args = ARGS(ARGS_ENTRY_HTON + (struct rte_flow_action_set_meta, data)), + .call = parse_vc_conf, + }, + [ACTION_SET_META_MASK] = { + .name = "mask", + .help = "mask for metadata value", + .next = NEXT(action_set_meta, NEXT_ENTRY(UNSIGNED)), + .args = ARGS(ARGS_ENTRY_HTON + (struct rte_flow_action_set_meta, mask)), + .call = parse_vc_conf, + }, }; /** Remove and return last entry from argument stack. */ @@ -4592,6 +4631,22 @@ static int comp_vc_action_rss_queue(struct context *, const struct token *, return ret; } +static int +parse_vc_action_set_meta(struct context *ctx, const struct token *token, + const char *str, unsigned int len, void *buf, + unsigned int size) +{ + int ret; + + ret = parse_vc(ctx, token, str, len, buf, size); + if (ret < 0) + return ret; + ret = rte_flow_dynf_metadata_register(); + if (ret < 0) + return -1; + return len; +} + /** Parse tokens for destroy command. */ static int parse_destroy(struct context *ctx, const struct token *token, diff --git a/app/test-pmd/util.c b/app/test-pmd/util.c index 1570270..39ff07b 100644 --- a/app/test-pmd/util.c +++ b/app/test-pmd/util.c @@ -81,6 +81,11 @@ mb->vlan_tci, mb->vlan_tci_outer); else if (ol_flags & PKT_RX_VLAN) printf(" - VLAN tci=0x%x", mb->vlan_tci); + if (ol_flags & PKT_TX_METADATA) + printf(" - Tx metadata: 0x%x", mb->tx_metadata); + if (ol_flags & PKT_RX_DYNF_METADATA) + printf(" - Rx metadata: 0x%x", + *RTE_FLOW_DYNF_METADATA(mb)); if (mb->packet_type) { rte_get_ptype_name(mb->packet_type, buf, sizeof(buf)); printf(" - hw ptype: %s", buf); diff --git a/doc/guides/prog_guide/rte_flow.rst b/doc/guides/prog_guide/rte_flow.rst index ff6fb11..45fc041 100644 --- a/doc/guides/prog_guide/rte_flow.rst +++ b/doc/guides/prog_guide/rte_flow.rst @@ -658,6 +658,32 @@ the physical device, with virtual groups in the PMD or not at all. | ``mask`` | ``id`` | zeroed to match any value | +----------+----------+---------------------------+ +Item: ``META`` +^^^^^^^^^^^^^^^^^ + +Matches 32 bit metadata item set. + +On egress, metadata can be set either by mbuf metadata field with +PKT_TX_METADATA flag or ``SET_META`` action. On ingress, ``SET_META`` +action sets metadata for a packet and the metadata will be reported via +``metadata`` dynamic field of ``rte_mbuf`` with PKT_RX_DYNF_METADATA flag. + +- Default ``mask`` matches the specified Rx metadata value. + +.. _table_rte_flow_item_meta: + +.. table:: META + + +----------+----------+---------------------------------------+ + | Field | Subfield | Value | + +==========+==========+=======================================+ + | ``spec`` | ``data`` | 32 bit metadata value | + +----------+----------+---------------------------------------+ + | ``last`` | ``data`` | upper range value | + +----------+----------+---------------------------------------+ + | ``mask`` | ``data`` | bit-mask applies to "spec" and "last" | + +----------+----------+---------------------------------------+ + Data matching item types ~~~~~~~~~~~~~~~~~~~~~~~~ @@ -2415,6 +2441,37 @@ 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. +Action: ``SET_META`` +^^^^^^^^^^^^^^^^^^^^^^^ + +Set metadata. Item ``META`` matches metadata. + +Metadata set by mbuf metadata field with PKT_TX_METADATA flag on egress will be +overridden by this action. On ingress, the metadata will be carried by +``metadata`` dynamic field of ``rte_mbuf`` which can be accessed by +``RTE_FLOW_DYNF_METADATA()``. PKT_RX_DYNF_METADATA flag will be set along +with the data. + +The mbuf dynamic field must be registered by calling +``rte_flow_dynf_metadata_register()`` prior to use ``SET_META`` action. + +Altering partial bits is supported with ``mask``. For bits which have never been +set, unpredictable value will be seen depending on driver implementation. For +loopback/hairpin packet, metadata set on Rx/Tx may or may not be propagated to +the other path depending on HW capability. + +.. _table_rte_flow_action_set_meta: + +.. table:: SET_META + + +----------+----------------------------+ + | Field | Value | + +==========+============================+ + | ``data`` | 32 bit metadata value | + +----------+----------------------------+ + | ``mask`` | bit-mask applies to "data" | + +----------+----------------------------+ + Negative types ~~~~~~~~~~~~~~ diff --git a/doc/guides/rel_notes/release_19_11.rst b/doc/guides/rel_notes/release_19_11.rst index 8921cfd..904746e 100644 --- a/doc/guides/rel_notes/release_19_11.rst +++ b/doc/guides/rel_notes/release_19_11.rst @@ -95,6 +95,14 @@ New Features for specific offload features, where adding a static field or flag in the mbuf is not justified. +* **Extended metadata support in rte_flow.** + + Flow metadata is extended to both Rx and Tx. + + * Tx metadata can also be set by SET_META action of rte_flow. + * Rx metadata is delivered to host via a dynamic field of ``rte_mbuf`` with + PKT_RX_DYNF_METADATA. + Removed Items ------------- diff --git a/lib/librte_ethdev/rte_ethdev.h b/lib/librte_ethdev/rte_ethdev.h index d937fb4..9a6432c 100644 --- a/lib/librte_ethdev/rte_ethdev.h +++ b/lib/librte_ethdev/rte_ethdev.h @@ -1013,7 +1013,6 @@ struct rte_eth_conf { #define DEV_RX_OFFLOAD_KEEP_CRC 0x00010000 #define DEV_RX_OFFLOAD_SCTP_CKSUM 0x00020000 #define DEV_RX_OFFLOAD_OUTER_UDP_CKSUM 0x00040000 - #define DEV_RX_OFFLOAD_CHECKSUM (DEV_RX_OFFLOAD_IPV4_CKSUM | \ DEV_RX_OFFLOAD_UDP_CKSUM | \ DEV_RX_OFFLOAD_TCP_CKSUM) diff --git a/lib/librte_ethdev/rte_ethdev_version.map b/lib/librte_ethdev/rte_ethdev_version.map index 6df42a4..3d9cafc 100644 --- a/lib/librte_ethdev/rte_ethdev_version.map +++ b/lib/librte_ethdev/rte_ethdev_version.map @@ -283,4 +283,10 @@ EXPERIMENTAL { # added in 19.08 rte_eth_read_clock; + + # added in 19.11 + rte_flow_dynf_metadata_offs; + rte_flow_dynf_metadata_flag; + rte_flow_dynf_metadata_avail; + rte_flow_dynf_metadata_register; }; diff --git a/lib/librte_ethdev/rte_flow.c b/lib/librte_ethdev/rte_flow.c index cc03b15..9cbda75 100644 --- a/lib/librte_ethdev/rte_flow.c +++ b/lib/librte_ethdev/rte_flow.c @@ -12,10 +12,18 @@ #include #include #include +#include +#include #include "rte_ethdev.h" #include "rte_flow_driver.h" #include "rte_flow.h" +/* Mbuf dynamic field name for metadata. */ +int rte_flow_dynf_metadata_offs = -1; + +/* Mbuf dynamic field flag bit number for metadata. */ +uint64_t rte_flow_dynf_metadata_mask; + /** * Flow elements description tables. */ @@ -153,8 +161,41 @@ struct rte_flow_desc_data { MK_FLOW_ACTION(DEC_TCP_SEQ, 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(SET_META, sizeof(struct rte_flow_action_set_meta)), }; +int +rte_flow_dynf_metadata_register(void) +{ + int offset; + int flag; + + static const struct rte_mbuf_dynfield desc_offs = { + .name = MBUF_DYNF_METADATA_NAME, + .size = MBUF_DYNF_METADATA_SIZE, + .align = MBUF_DYNF_METADATA_ALIGN, + .flags = MBUF_DYNF_METADATA_FLAGS, + }; + static const struct rte_mbuf_dynflag desc_flag = { + .name = MBUF_DYNF_METADATA_NAME, + }; + + offset = rte_mbuf_dynfield_register(&desc_offs); + if (offset < 0) + goto error; + flag = rte_mbuf_dynflag_register(&desc_flag); + if (flag < 0) + goto error; + rte_flow_dynf_metadata_offs = offset; + rte_flow_dynf_metadata_mask = (1ULL << flag); + return 0; + +error: + rte_flow_dynf_metadata_offs = -1; + rte_flow_dynf_metadata_mask = 0ULL; + return -rte_errno; +} + static int flow_err(uint16_t port_id, int ret, struct rte_flow_error *error) { diff --git a/lib/librte_ethdev/rte_flow.h b/lib/librte_ethdev/rte_flow.h index 391a44a..a27e619 100644 --- a/lib/librte_ethdev/rte_flow.h +++ b/lib/librte_ethdev/rte_flow.h @@ -27,6 +27,8 @@ #include #include #include +#include +#include #ifdef __cplusplus extern "C" { @@ -417,7 +419,8 @@ enum rte_flow_item_type { /** * [META] * - * Matches a metadata value specified in mbuf metadata field. + * Matches a metadata value. + * * See struct rte_flow_item_meta. */ RTE_FLOW_ITEM_TYPE_META, @@ -1213,9 +1216,17 @@ struct rte_flow_item_icmp6_nd_opt_tla_eth { #endif /** - * RTE_FLOW_ITEM_TYPE_META. + * @warning + * @b EXPERIMENTAL: this structure may change without prior notice * - * Matches a specified metadata value. + * RTE_FLOW_ITEM_TYPE_META + * + * Matches a specified metadata value. On egress, metadata can be set either by + * mbuf tx_metadata field with PKT_TX_METADATA flag or + * RTE_FLOW_ACTION_TYPE_SET_META. On ingress, RTE_FLOW_ACTION_TYPE_SET_META sets + * metadata for a packet and the metadata will be reported via mbuf metadata + * dynamic field with PKT_RX_DYNF_METADATA flag. The dynamic mbuf field must be + * registered in advance by rte_flow_dynf_metadata_register(). */ struct rte_flow_item_meta { rte_be32_t data; @@ -1813,6 +1824,13 @@ enum rte_flow_action_type { * undefined behavior. */ RTE_FLOW_ACTION_TYPE_DEC_TCP_ACK, + + /** + * Set metadata on ingress or egress path. + * + * See struct rte_flow_action_set_meta. + */ + RTE_FLOW_ACTION_TYPE_SET_META, }; /** @@ -2300,6 +2318,43 @@ struct rte_flow_action_set_mac { uint8_t mac_addr[RTE_ETHER_ADDR_LEN]; }; +/** + * @warning + * @b EXPERIMENTAL: this structure may change without prior notice + * + * RTE_FLOW_ACTION_TYPE_SET_META + * + * Set metadata. Metadata set by mbuf tx_metadata field with + * PKT_TX_METADATA flag on egress will be overridden by this action. On + * ingress, the metadata will be carried by mbuf metadata dynamic field + * with PKT_RX_DYNF_METADATA flag if set. The dynamic mbuf field must be + * registered in advance by rte_flow_dynf_metadata_register(). + * + * Altering partial bits is supported with mask. For bits which have never + * been set, unpredictable value will be seen depending on driver + * implementation. For loopback/hairpin packet, metadata set on Rx/Tx may + * or may not be propagated to the other path depending on HW capability. + * + * RTE_FLOW_ITEM_TYPE_META matches metadata. + */ +struct rte_flow_action_set_meta { + rte_be32_t data; + rte_be32_t mask; +}; + +/* Mbuf dynamic field offset for metadata. */ +extern int rte_flow_dynf_metadata_offs; + +/* Mbuf dynamic field flag mask for metadata. */ +extern uint64_t rte_flow_dynf_metadata_mask; + +/* Mbuf dynamic field pointer for metadata. */ +#define RTE_FLOW_DYNF_METADATA(m) \ + RTE_MBUF_DYNFIELD((m), rte_flow_dynf_metadata_offs, uint32_t *) + +/* Mbuf dynamic flag for metadata. */ +#define PKT_RX_DYNF_METADATA (rte_flow_dynf_metadata_mask) + /* * Definition of a single action. * @@ -2533,6 +2588,32 @@ enum rte_flow_conv_op { }; /** + * Check if mbuf dynamic field for metadata is registered. + * + * @return + * True if registered, false otherwise. + */ +__rte_experimental +static inline int +rte_flow_dynf_metadata_avail(void) { + return !!rte_flow_dynf_metadata_mask; +} + +/** + * Register mbuf dynamic field and flag for metadata. + * + * This function must be called prior to use SET_META action in order to + * register the dynamic mbuf field. Otherwise, the data cannot be delivered to + * application. + * + * @return + * 0 on success, a negative errno value otherwise and rte_errno is set. + */ +__rte_experimental +int +rte_flow_dynf_metadata_register(void); + +/** * Check whether a flow rule can be created on a given port. * * The flow rule is validated for correctness and whether it could be accepted diff --git a/lib/librte_mbuf/rte_mbuf_dyn.h b/lib/librte_mbuf/rte_mbuf_dyn.h index 6e2c816..4ff33ac 100644 --- a/lib/librte_mbuf/rte_mbuf_dyn.h +++ b/lib/librte_mbuf/rte_mbuf_dyn.h @@ -160,4 +160,12 @@ int rte_mbuf_dynflag_lookup(const char *name, */ #define RTE_MBUF_DYNFIELD(m, offset, type) ((type)((uintptr_t)(m) + (offset))) +/** + * Flow metadata dynamic field definitions. + */ +#define MBUF_DYNF_METADATA_NAME "flow-metadata" +#define MBUF_DYNF_METADATA_SIZE sizeof(uint32_t) +#define MBUF_DYNF_METADATA_ALIGN __alignof__(uint32_t) +#define MBUF_DYNF_METADATA_FLAGS 0 + #endif -- 1.8.3.1