From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-wm0-f53.google.com (mail-wm0-f53.google.com [74.125.82.53]) by dpdk.org (Postfix) with ESMTP id 7F2F88DA0 for ; Wed, 25 Apr 2018 17:28:25 +0200 (CEST) Received: by mail-wm0-f53.google.com with SMTP id x12so5000553wmc.0 for ; Wed, 25 Apr 2018 08:28:25 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=6wind-com.20150623.gappssmtp.com; s=20150623; h=date:from:to:cc:subject:message-id:references:mime-version :content-disposition:in-reply-to; bh=tTgcs0gUKY4aXOizcxLFiGCfp4X3vnecSCnir8a5Umo=; b=xj6WaXiI4e000wjfL8CfUuk01N+MhwFZOGEqmDOtm0ltv4XXkliXoz0JgDwfI6rQzB D4P0yA0IdWy0ULdNmmlSa4ONJdymVlC45uLph8lb4HChXZQSNM8MUIdXbXKAjt23dhur W2+XhPQ8OrkcjhNX8uL1CG5kTD69E/qfIKDr4RP/MHQggdpdbT8foW/uZgzm6Gl7KjRb ssqkDR7a0Du86h2RKzqMgLUwuSfauo2TQ3Ev2YGGvDMncTGu7wfV5j5n8p5+Wvz7fD1G QWdzSuPMS6s6i8yLCEh38jqs5mOV5FDtvffwlz7Tzck5Nt/reeo6bVmIjWh+E1/EMqSY VZfQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:from:to:cc:subject:message-id:references :mime-version:content-disposition:in-reply-to; bh=tTgcs0gUKY4aXOizcxLFiGCfp4X3vnecSCnir8a5Umo=; b=szgZ5+0UyZUeOXW/Duwhq9ClDYHFRTghWNi7rUjYowZya7LV7xopaq5KHLEitqZ40A odF6cze1Ctol0ol4dEMRYZqclFqaL384P939c4PYw4dcuqPPrP6mUq+JEKpVdjXaP7Bf JRKsFbNcf9ooO7Sl6cln+orU8xAd/+OYi80jnUVvfd4LpMb15gsPPvEPd5i7JfI2BmQO TDIyOzvNBrYXcMWCL4OQZFjuMQv4LDOre+DgIEcYBWig6nfaUNB5uF5PgGzE81DzuSiK rU8yaG3uvxUEcO1yXhAqRNaxSA59uyR8SJOcrSUtZnouOOKICecIlFEDp8J7fQeiCBK4 SeNw== X-Gm-Message-State: ALQs6tB7P95D3BSuxwJZXARS8py659drw8pgtD3ILEfPt2eIIrnKDITQ 9BaM8izHLZIOHtk9ZHfthRNyEw== X-Google-Smtp-Source: AIpwx48Zz1y2bnEoKwaTGnwBKeBWV+IJ1uBGWEX8p3BMBqQbBn38RtcCIjHLIi3R7nGJj2XBSW5iEg== X-Received: by 10.28.224.68 with SMTP id x65mr12061437wmg.83.1524670104955; Wed, 25 Apr 2018 08:28:24 -0700 (PDT) Received: from 6wind.com (host.78.145.23.62.rev.coltfrance.com. [62.23.145.78]) by smtp.gmail.com with ESMTPSA id y101sm15094855wmh.10.2018.04.25.08.28.24 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 25 Apr 2018 08:28:24 -0700 (PDT) Date: Wed, 25 Apr 2018 17:28:10 +0200 From: Adrien Mazarguil To: Thomas Monjalon , Ferruh Yigit , dev@dpdk.org Cc: "Zhang, Qi Z" , Declan Doherty Message-ID: <20180425151852.7676-17-adrien.mazarguil@6wind.com> References: <20180419100848.6178-1-adrien.mazarguil@6wind.com> <20180425151852.7676-1-adrien.mazarguil@6wind.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20180425151852.7676-1-adrien.mazarguil@6wind.com> X-Mailer: git-send-email 2.11.0 Subject: [dpdk-dev] [PATCH v6 16/16] ethdev: add port ID item and action to flow API 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: , X-List-Received-Date: Wed, 25 Apr 2018 15:28:26 -0000 RTE_FLOW_ACTION_TYPE_PORT_ID brings the ability to inject matching traffic into a different device, as identified by its DPDK port ID. This is normally only supported when the target port ID has some kind of relationship with the port ID the flow rule is created against, such as being exposed by a common physical device (e.g. a different port of an Ethernet switch). The converse pattern item, RTE_FLOW_ITEM_TYPE_PORT_ID, makes the resulting flow rule match traffic whose origin is the specified port ID. Note that specifying a port ID that differs from the one the flow rule is created against is normally meaningless (if even accepted), but can make sense if combined with the transfer attribute. These must not be confused with their PHY_PORT counterparts, which refer to physical ports using device-specific indices, but unlike PORT_ID are not necessarily tied to DPDK port IDs. This breaks ABI compatibility for the following public functions: - rte_flow_copy() - rte_flow_create() - rte_flow_query() - rte_flow_validate() Signed-off-by: Adrien Mazarguil Reviewed-by: Qi Zhang Acked-by: Andrew Rybchenko Cc: "Zhang, Qi Z" Cc: Declan Doherty --- v6 changes: Updated API changes section in release notes. v1: This patch provides the same functionality and supersedes Qi Zhang's "ether: add flow action to redirect packet to a port" [1]. The main differences are: - Action is named PORT_ID instead of PORT. - Addition of a PORT_ID pattern item. - More extensive documentation. - Testpmd support. - rte_flow_copy() support. [1] http://dpdk.org/ml/archives/dev/2018-April/094648.html --- app/test-pmd/cmdline_flow.c | 57 ++++++++++++++++++++++++ app/test-pmd/config.c | 2 + doc/guides/prog_guide/rte_flow.rst | 48 ++++++++++++++++++++ doc/guides/rel_notes/release_18_05.rst | 2 + doc/guides/testpmd_app_ug/testpmd_funcs.rst | 9 ++++ lib/librte_ether/rte_flow.c | 2 + lib/librte_ether/rte_flow.h | 56 +++++++++++++++++++++++ 7 files changed, 176 insertions(+) diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c index 356714801..32fe6645a 100644 --- a/app/test-pmd/cmdline_flow.c +++ b/app/test-pmd/cmdline_flow.c @@ -89,6 +89,8 @@ enum index { ITEM_VF_ID, ITEM_PHY_PORT, ITEM_PHY_PORT_INDEX, + ITEM_PORT_ID, + ITEM_PORT_ID_ID, ITEM_RAW, ITEM_RAW_RELATIVE, ITEM_RAW_SEARCH, @@ -185,6 +187,9 @@ enum index { ACTION_PHY_PORT, ACTION_PHY_PORT_ORIGINAL, ACTION_PHY_PORT_INDEX, + ACTION_PORT_ID, + ACTION_PORT_ID_ORIGINAL, + ACTION_PORT_ID_ID, ACTION_METER, ACTION_METER_ID, }; @@ -445,6 +450,7 @@ static const enum index next_item[] = { ITEM_PF, ITEM_VF, ITEM_PHY_PORT, + ITEM_PORT_ID, ITEM_RAW, ITEM_ETH, ITEM_VLAN, @@ -491,6 +497,12 @@ static const enum index item_phy_port[] = { ZERO, }; +static const enum index item_port_id[] = { + ITEM_PORT_ID_ID, + ITEM_NEXT, + ZERO, +}; + static const enum index item_raw[] = { ITEM_RAW_RELATIVE, ITEM_RAW_SEARCH, @@ -627,6 +639,7 @@ static const enum index next_action[] = { ACTION_PF, ACTION_VF, ACTION_PHY_PORT, + ACTION_PORT_ID, ACTION_METER, ZERO, }; @@ -668,6 +681,13 @@ static const enum index action_phy_port[] = { ZERO, }; +static const enum index action_port_id[] = { + ACTION_PORT_ID_ORIGINAL, + ACTION_PORT_ID_ID, + ACTION_NEXT, + ZERO, +}; + static const enum index action_meter[] = { ACTION_METER_ID, ACTION_NEXT, @@ -1084,6 +1104,20 @@ static const struct token token_list[] = { .next = NEXT(item_phy_port, NEXT_ENTRY(UNSIGNED), item_param), .args = ARGS(ARGS_ENTRY(struct rte_flow_item_phy_port, index)), }, + [ITEM_PORT_ID] = { + .name = "port_id", + .help = "match traffic from/to a given DPDK port ID", + .priv = PRIV_ITEM(PORT_ID, + sizeof(struct rte_flow_item_port_id)), + .next = NEXT(item_port_id), + .call = parse_vc, + }, + [ITEM_PORT_ID_ID] = { + .name = "id", + .help = "DPDK port ID", + .next = NEXT(item_port_id, NEXT_ENTRY(UNSIGNED), item_param), + .args = ARGS(ARGS_ENTRY(struct rte_flow_item_port_id, id)), + }, [ITEM_RAW] = { .name = "raw", .help = "match an arbitrary byte string", @@ -1749,6 +1783,29 @@ static const struct token token_list[] = { index)), .call = parse_vc_conf, }, + [ACTION_PORT_ID] = { + .name = "port_id", + .help = "direct matching traffic to a given DPDK port ID", + .priv = PRIV_ACTION(PORT_ID, + sizeof(struct rte_flow_action_port_id)), + .next = NEXT(action_port_id), + .call = parse_vc, + }, + [ACTION_PORT_ID_ORIGINAL] = { + .name = "original", + .help = "use original DPDK port ID if possible", + .next = NEXT(action_port_id, NEXT_ENTRY(BOOLEAN)), + .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_action_port_id, + original, 1)), + .call = parse_vc_conf, + }, + [ACTION_PORT_ID_ID] = { + .name = "id", + .help = "DPDK port ID", + .next = NEXT(action_port_id, NEXT_ENTRY(UNSIGNED)), + .args = ARGS(ARGS_ENTRY(struct rte_flow_action_port_id, id)), + .call = parse_vc_conf, + }, [ACTION_METER] = { .name = "meter", .help = "meter the directed packets at given id", diff --git a/app/test-pmd/config.c b/app/test-pmd/config.c index 869c6663b..8e56c0668 100644 --- a/app/test-pmd/config.c +++ b/app/test-pmd/config.c @@ -994,6 +994,7 @@ static const struct { MK_FLOW_ITEM(PF, 0), MK_FLOW_ITEM(VF, sizeof(struct rte_flow_item_vf)), MK_FLOW_ITEM(PHY_PORT, sizeof(struct rte_flow_item_phy_port)), + MK_FLOW_ITEM(PORT_ID, sizeof(struct rte_flow_item_port_id)), MK_FLOW_ITEM(RAW, sizeof(struct rte_flow_item_raw)), MK_FLOW_ITEM(ETH, sizeof(struct rte_flow_item_eth)), MK_FLOW_ITEM(VLAN, sizeof(struct rte_flow_item_vlan)), @@ -1092,6 +1093,7 @@ static const struct { MK_FLOW_ACTION(PF, 0), MK_FLOW_ACTION(VF, sizeof(struct rte_flow_action_vf)), MK_FLOW_ACTION(PHY_PORT, sizeof(struct rte_flow_action_phy_port)), + MK_FLOW_ACTION(PORT_ID, sizeof(struct rte_flow_action_port_id)), MK_FLOW_ACTION(METER, sizeof(struct rte_flow_action_meter)), }; diff --git a/doc/guides/prog_guide/rte_flow.rst b/doc/guides/prog_guide/rte_flow.rst index a39c1e1b0..2fb8e9c3f 100644 --- a/doc/guides/prog_guide/rte_flow.rst +++ b/doc/guides/prog_guide/rte_flow.rst @@ -617,6 +617,36 @@ associated with a port_id should be retrieved by other means. | ``mask`` | ``index`` | zeroed to match any port index | +----------+-----------+--------------------------------+ +Item: ``PORT_ID`` +^^^^^^^^^^^^^^^^^ + +Matches traffic originating from (ingress) or going to (egress) a given DPDK +port ID. + +Normally only supported if the port ID in question is known by the +underlying PMD and related to the device the flow rule is created against. + +This must not be confused with `Item: PHY_PORT`_ which refers to the +physical port of a device, whereas `Item: PORT_ID`_ refers to a ``struct +rte_eth_dev`` object on the application side (also known as "port +representor" depending on the kind of underlying device). + +- Default ``mask`` matches the specified DPDK port ID. + +.. _table_rte_flow_item_port_id: + +.. table:: PORT_ID + + +----------+----------+-----------------------------+ + | Field | Subfield | Value | + +==========+==========+=============================+ + | ``spec`` | ``id`` | DPDK port ID | + +----------+----------+-----------------------------+ + | ``last`` | ``id`` | upper range value | + +----------+----------+-----------------------------+ + | ``mask`` | ``id`` | zeroed to match any port ID | + +----------+----------+-----------------------------+ + Data matching item types ~~~~~~~~~~~~~~~~~~~~~~~~ @@ -1453,6 +1483,24 @@ See `Item: PHY_PORT`_. | ``index`` | physical port index | +--------------+-------------------------------------+ +Action: ``PORT_ID`` +^^^^^^^^^^^^^^^^^^^ +Directs matching traffic to a given DPDK port ID. + +See `Item: PORT_ID`_. + +.. _table_rte_flow_action_port_id: + +.. table:: PORT_ID + + +--------------+---------------------------------------+ + | Field | Value | + +==============+=======================================+ + | ``original`` | use original DPDK port ID if possible | + +--------------+---------------------------------------+ + | ``id`` | DPDK port ID | + +--------------+---------------------------------------+ + Action: ``METER`` ^^^^^^^^^^^^^^^^^ diff --git a/doc/guides/rel_notes/release_18_05.rst b/doc/guides/rel_notes/release_18_05.rst index 211f68da1..b1b2fd00e 100644 --- a/doc/guides/rel_notes/release_18_05.rst +++ b/doc/guides/rel_notes/release_18_05.rst @@ -275,6 +275,8 @@ API Changes IDs. * An action counterpart to the PHY_PORT pattern item was added in order to redirect matching traffic to a specific physical port. + * PORT_ID pattern item and actions were added to match and target DPDK + port IDs at a higher level than PHY_PORT. ABI Changes diff --git a/doc/guides/testpmd_app_ug/testpmd_funcs.rst b/doc/guides/testpmd_app_ug/testpmd_funcs.rst index 9733a7262..f5565db29 100644 --- a/doc/guides/testpmd_app_ug/testpmd_funcs.rst +++ b/doc/guides/testpmd_app_ug/testpmd_funcs.rst @@ -3236,6 +3236,10 @@ This section lists supported pattern items and their attributes, if any. - ``index {unsigned}``: physical port index. +- ``port_id``: match traffic from/to a given DPDK port ID. + + - ``id {unsigned}``: DPDK port ID. + - ``raw``: match an arbitrary byte string. - ``relative {boolean}``: look for pattern after the previous item. @@ -3452,6 +3456,11 @@ This section lists supported actions and their attributes, if any. - ``original {boolean}``: use original port index if possible. - ``index {unsigned}``: physical port index. +- ``port_id``: direct matching traffic to a given DPDK port ID. + + - ``original {boolean}``: use original DPDK port ID if possible. + - ``id {unsigned}``: DPDK port ID. + Destroying flow rules ~~~~~~~~~~~~~~~~~~~~~ diff --git a/lib/librte_ether/rte_flow.c b/lib/librte_ether/rte_flow.c index 00989c73b..cecab59f6 100644 --- a/lib/librte_ether/rte_flow.c +++ b/lib/librte_ether/rte_flow.c @@ -39,6 +39,7 @@ static const struct rte_flow_desc_data rte_flow_desc_item[] = { MK_FLOW_ITEM(PF, 0), MK_FLOW_ITEM(VF, sizeof(struct rte_flow_item_vf)), MK_FLOW_ITEM(PHY_PORT, sizeof(struct rte_flow_item_phy_port)), + MK_FLOW_ITEM(PORT_ID, sizeof(struct rte_flow_item_port_id)), MK_FLOW_ITEM(RAW, sizeof(struct rte_flow_item_raw)), MK_FLOW_ITEM(ETH, sizeof(struct rte_flow_item_eth)), MK_FLOW_ITEM(VLAN, sizeof(struct rte_flow_item_vlan)), @@ -77,6 +78,7 @@ static const struct rte_flow_desc_data rte_flow_desc_action[] = { MK_FLOW_ACTION(PF, 0), MK_FLOW_ACTION(VF, sizeof(struct rte_flow_action_vf)), MK_FLOW_ACTION(PHY_PORT, sizeof(struct rte_flow_action_phy_port)), + MK_FLOW_ACTION(PORT_ID, sizeof(struct rte_flow_action_port_id)), }; static int diff --git a/lib/librte_ether/rte_flow.h b/lib/librte_ether/rte_flow.h index 58b75e934..09a21e531 100644 --- a/lib/librte_ether/rte_flow.h +++ b/lib/librte_ether/rte_flow.h @@ -180,6 +180,16 @@ enum rte_flow_item_type { RTE_FLOW_ITEM_TYPE_PHY_PORT, /** + * [META] + * + * Matches traffic originating from (ingress) or going to (egress) a + * given DPDK port ID. + * + * See struct rte_flow_item_port_id. + */ + RTE_FLOW_ITEM_TYPE_PORT_ID, + + /** * Matches a byte string of a given length at a given offset. * * See struct rte_flow_item_raw. @@ -414,6 +424,32 @@ static const struct rte_flow_item_phy_port rte_flow_item_phy_port_mask = { #endif /** + * RTE_FLOW_ITEM_TYPE_PORT_ID + * + * Matches traffic originating from (ingress) or going to (egress) a given + * DPDK port ID. + * + * Normally only supported if the port ID in question is known by the + * underlying PMD and related to the device the flow rule is created + * against. + * + * This must not be confused with @p PHY_PORT which refers to the physical + * port of a device, whereas @p PORT_ID refers to a struct rte_eth_dev + * object on the application side (also known as "port representor" + * depending on the kind of underlying device). + */ +struct rte_flow_item_port_id { + uint32_t id; /**< DPDK port ID. */ +}; + +/** Default mask for RTE_FLOW_ITEM_TYPE_PORT_ID. */ +#ifndef __cplusplus +static const struct rte_flow_item_port_id rte_flow_item_port_id_mask = { + .id = 0xffffffff, +}; +#endif + +/** * RTE_FLOW_ITEM_TYPE_RAW * * Matches a byte string of a given length at a given offset. @@ -997,6 +1033,13 @@ enum rte_flow_action_type { RTE_FLOW_ACTION_TYPE_PHY_PORT, /** + * Directs matching traffic to a given DPDK port ID. + * + * See struct rte_flow_action_port_id. + */ + RTE_FLOW_ACTION_TYPE_PORT_ID, + + /** * Traffic metering and policing (MTR). * * See struct rte_flow_action_meter. @@ -1134,6 +1177,19 @@ struct rte_flow_action_phy_port { }; /** + * RTE_FLOW_ACTION_TYPE_PORT_ID + * + * Directs matching traffic to a given DPDK port ID. + * + * @see RTE_FLOW_ITEM_TYPE_PORT_ID + */ +struct rte_flow_action_port_id { + uint32_t original:1; /**< Use original DPDK port ID if possible. */ + uint32_t reserved:31; /**< Reserved, must be zero. */ + uint32_t id; /**< DPDK port ID. */ +}; + +/** * RTE_FLOW_ACTION_TYPE_METER * * Traffic metering and policing (MTR). -- 2.11.0