From patchwork Wed Nov 20 15:28:07 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eli Britstein X-Patchwork-Id: 1198271 X-Patchwork-Delegate: i.maximets@samsung.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=openvswitch.org (client-ip=140.211.166.136; helo=silver.osuosl.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=mellanox.com Received: from silver.osuosl.org (smtp3.osuosl.org [140.211.166.136]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 47J6KS1vZbz9sPZ for ; Thu, 21 Nov 2019 02:38:20 +1100 (AEDT) Received: from localhost (localhost [127.0.0.1]) by silver.osuosl.org (Postfix) with ESMTP id AE52025F2A; Wed, 20 Nov 2019 15:38:18 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from silver.osuosl.org ([127.0.0.1]) by localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id ifeCXQygAcnM; Wed, 20 Nov 2019 15:38:02 +0000 (UTC) Received: from lists.linuxfoundation.org (lf-lists.osuosl.org [140.211.9.56]) by silver.osuosl.org (Postfix) with ESMTP id E831C2628C; Wed, 20 Nov 2019 15:35:58 +0000 (UTC) Received: from lf-lists.osuosl.org (localhost [127.0.0.1]) by lists.linuxfoundation.org (Postfix) with ESMTP id BF723C1E5D; Wed, 20 Nov 2019 15:35:58 +0000 (UTC) X-Original-To: dev@openvswitch.org Delivered-To: ovs-dev@lists.linuxfoundation.org Received: from hemlock.osuosl.org (smtp2.osuosl.org [140.211.166.133]) by lists.linuxfoundation.org (Postfix) with ESMTP id 5EF5EC1DDC for ; Wed, 20 Nov 2019 15:35:38 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by hemlock.osuosl.org (Postfix) with ESMTP id 430F2885E8 for ; Wed, 20 Nov 2019 15:35:38 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from hemlock.osuosl.org ([127.0.0.1]) by localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id KTFSySP-vK99 for ; Wed, 20 Nov 2019 15:35:35 +0000 (UTC) X-Greylist: from auto-whitelisted by SQLgrey-1.7.6 Received: from mellanox.co.il (mail-il-dmz.mellanox.com [193.47.165.129]) by hemlock.osuosl.org (Postfix) with ESMTP id 164E586EA5 for ; Wed, 20 Nov 2019 15:35:33 +0000 (UTC) Received: from Internal Mail-Server by MTLPINE1 (envelope-from elibr@mellanox.com) with ESMTPS (AES256-SHA encrypted); 20 Nov 2019 17:28:47 +0200 Received: from dev-r-vrt-215.mtr.labs.mlnx. (dev-r-vrt-215.mtr.labs.mlnx [10.212.215.1]) by labmailer.mlnx (8.13.8/8.13.8) with ESMTP id xAKFSlW7001566; Wed, 20 Nov 2019 17:28:47 +0200 From: Eli Britstein To: dev@openvswitch.org, Ilya Maximets , Ian Stokes Date: Wed, 20 Nov 2019 15:28:07 +0000 Message-Id: <20191120152826.25074-2-elibr@mellanox.com> X-Mailer: git-send-email 2.14.5 In-Reply-To: <20191120152826.25074-1-elibr@mellanox.com> References: <20191120152826.25074-1-elibr@mellanox.com> Cc: Oz Shlomo , Majd Dibbiny , Eli Britstein , Ameer Mahagneh Subject: [ovs-dev] [PATCH 01/20] sparse: rte_flow.h: Adapt according to DPDK 18.11.2 X-BeenThere: ovs-dev@openvswitch.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: ovs-dev-bounces@openvswitch.org Sender: "dev" In dpdk-latest branch, this file was removed. This patch is temporary, should not be merged, and only exist to pass sparse travis tests. Signed-off-by: Eli Britstein --- include/sparse/rte_flow.h | 810 +++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 759 insertions(+), 51 deletions(-) diff --git a/include/sparse/rte_flow.h b/include/sparse/rte_flow.h index 02fa523b4..0c55e68cd 100644 --- a/include/sparse/rte_flow.h +++ b/include/sparse/rte_flow.h @@ -64,18 +64,20 @@ extern "C" { /** * Flow rule attributes. * - * Priorities are set on two levels: per group and per rule within groups. + * Priorities are set on a per rule based within groups. * - * Lower values denote higher priority, the highest priority for both levels - * is 0, so that a rule with priority 0 in group 8 is always matched after a - * rule with priority 8 in group 0. + * Lower values denote higher priority, the highest priority for a flow rule + * is 0, so that a flow that matches for than one rule, the rule with the + * lowest priority value will always be matched. * * Although optional, applications are encouraged to group similar rules as * much as possible to fully take advantage of hardware capabilities * (e.g. optimized matching) and work around limitations (e.g. a single - * pattern type possibly allowed in a given group). + * pattern type possibly allowed in a given group). Applications should be + * aware that groups are not linked by default, and that they must be + * explicitly linked by the application using the JUMP action. * - * Group and priority levels are arbitrary and up to the application, they + * Priority levels are arbitrary and up to the application, they * do not need to be contiguous nor start from 0, however the maximum number * varies between devices and may be affected by existing flow rules. * @@ -98,10 +100,29 @@ extern "C" { */ struct rte_flow_attr { uint32_t group; /**< Priority group. */ - uint32_t priority; /**< Priority level within group. */ + uint32_t priority; /**< Rule priority level within group. */ uint32_t ingress:1; /**< Rule applies to ingress traffic. */ uint32_t egress:1; /**< Rule applies to egress traffic. */ - uint32_t reserved:30; /**< Reserved, must be zero. */ + /** + * Instead of simply matching the properties of traffic as it would + * appear on a given DPDK port ID, enabling this attribute transfers + * a flow rule to the lowest possible level of any device endpoints + * found in the pattern. + * + * When supported, this effectively enables an application to + * re-route traffic not necessarily intended for it (e.g. coming + * from or addressed to different physical ports, VFs or + * applications) at the device level. + * + * It complements the behavior of some pattern items such as + * RTE_FLOW_ITEM_TYPE_PHY_PORT and is meaningless without them. + * + * When transferring flow rules, ingress and egress attributes keep + * their original meaning, as if processing traffic emitted or + * received by the application. + */ + uint32_t transfer:1; + uint32_t reserved:29; /**< Reserved, must be zero. */ }; /** @@ -109,15 +130,13 @@ struct rte_flow_attr { * * Pattern items fall in two categories: * - * - Matching protocol headers and packet data (ANY, RAW, ETH, VLAN, IPV4, - * IPV6, ICMP, UDP, TCP, SCTP, VXLAN and so on), usually associated with a + * - Matching protocol headers and packet data, usually associated with a * specification structure. These must be stacked in the same order as the - * protocol layers to match, starting from the lowest. + * protocol layers to match inside packets, starting from the lowest. * - * - Matching meta-data or affecting pattern processing (END, VOID, INVERT, - * PF, VF, PORT and so on), often without a specification structure. Since - * they do not match packet contents, these can be specified anywhere - * within item lists without affecting others. + * - Matching meta-data or affecting pattern processing, often without a + * specification structure. Since they do not match packet contents, their + * position in the list is usually not relevant. * * See the description of individual types for more information. Those * marked with [META] fall into the second category. @@ -164,13 +183,8 @@ enum rte_flow_item_type { /** * [META] * - * Matches packets addressed to the physical function of the device. - * - * If the underlying device function differs from the one that would - * normally receive the matched traffic, specifying this item - * prevents it from reaching that device unless the flow rule - * contains a PF action. Packets are not duplicated between device - * instances by default. + * Matches traffic originating from (ingress) or going to (egress) + * the physical function of the current device. * * No associated specification structure. */ @@ -179,13 +193,8 @@ enum rte_flow_item_type { /** * [META] * - * Matches packets addressed to a virtual function ID of the device. - * - * If the underlying device function differs from the one that would - * normally receive the matched traffic, specifying this item - * prevents it from reaching that device unless the flow rule - * contains a VF action. Packets are not duplicated between device - * instances by default. + * Matches traffic originating from (ingress) or going to (egress) a + * given virtual function of the current device. * * See struct rte_flow_item_vf. */ @@ -194,17 +203,22 @@ enum rte_flow_item_type { /** * [META] * - * Matches packets coming from the specified physical port of the - * underlying device. + * Matches traffic originating from (ingress) or going to (egress) a + * physical port of the underlying device. * - * The first PORT item overrides the physical port normally - * associated with the specified DPDK input port (port_id). This - * item can be provided several times to match additional physical - * ports. + * See struct rte_flow_item_phy_port. + */ + 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. + * See struct rte_flow_item_port_id. */ - RTE_FLOW_ITEM_TYPE_PORT, + RTE_FLOW_ITEM_TYPE_PORT_ID, /** * Matches a byte string of a given length at a given offset. @@ -349,6 +363,93 @@ enum rte_flow_item_type { * See struct rte_flow_item_esp. */ RTE_FLOW_ITEM_TYPE_ESP, + + /** + * Matches a GENEVE header. + * + * See struct rte_flow_item_geneve. + */ + RTE_FLOW_ITEM_TYPE_GENEVE, + + /** + * Matches a VXLAN-GPE header. + * + * See struct rte_flow_item_vxlan_gpe. + */ + RTE_FLOW_ITEM_TYPE_VXLAN_GPE, + + /** + * Matches an ARP header for Ethernet/IPv4. + * + * See struct rte_flow_item_arp_eth_ipv4. + */ + RTE_FLOW_ITEM_TYPE_ARP_ETH_IPV4, + + /** + * Matches the presence of any IPv6 extension header. + * + * See struct rte_flow_item_ipv6_ext. + */ + RTE_FLOW_ITEM_TYPE_IPV6_EXT, + + /** + * Matches any ICMPv6 header. + * + * See struct rte_flow_item_icmp6. + */ + RTE_FLOW_ITEM_TYPE_ICMP6, + + /** + * Matches an ICMPv6 neighbor discovery solicitation. + * + * See struct rte_flow_item_icmp6_nd_ns. + */ + RTE_FLOW_ITEM_TYPE_ICMP6_ND_NS, + + /** + * Matches an ICMPv6 neighbor discovery advertisement. + * + * See struct rte_flow_item_icmp6_nd_na. + */ + RTE_FLOW_ITEM_TYPE_ICMP6_ND_NA, + + /** + * Matches the presence of any ICMPv6 neighbor discovery option. + * + * See struct rte_flow_item_icmp6_nd_opt. + */ + RTE_FLOW_ITEM_TYPE_ICMP6_ND_OPT, + + /** + * Matches an ICMPv6 neighbor discovery source Ethernet link-layer + * address option. + * + * See struct rte_flow_item_icmp6_nd_opt_sla_eth. + */ + RTE_FLOW_ITEM_TYPE_ICMP6_ND_OPT_SLA_ETH, + + /** + * Matches an ICMPv6 neighbor discovery target Ethernet link-layer + * address option. + * + * See struct rte_flow_item_icmp6_nd_opt_tla_eth. + */ + RTE_FLOW_ITEM_TYPE_ICMP6_ND_OPT_TLA_ETH, + + /** + * Matches specified mark field. + * + * See struct rte_flow_item_mark. + */ + RTE_FLOW_ITEM_TYPE_MARK, + + /** + * [META] + * + * Matches a metadata value specified in mbuf metadata field. + * See struct rte_flow_item_meta. + */ + RTE_FLOW_ITEM_TYPE_META, }; /** @@ -403,13 +504,13 @@ static const struct rte_flow_item_vf rte_flow_item_vf_mask = { #endif /** - * RTE_FLOW_ITEM_TYPE_PORT + * RTE_FLOW_ITEM_TYPE_PHY_PORT * - * Matches packets coming from the specified physical port of the underlying - * device. + * Matches traffic originating from (ingress) or going to (egress) a + * physical port of the underlying device. * - * The first PORT item overrides the physical port normally associated with - * the specified DPDK input port (port_id). This item can be provided + * The first PHY_PORT item overrides the physical port normally associated + * with the specified DPDK input port (port_id). This item can be provided * several times to match additional physical ports. * * Note that physical ports are not necessarily tied to DPDK input ports @@ -422,17 +523,43 @@ static const struct rte_flow_item_vf rte_flow_item_vf_mask = { * * A zeroed mask can be used to match any port index. */ -struct rte_flow_item_port { +struct rte_flow_item_phy_port { uint32_t index; /**< Physical port index. */ }; -/** Default mask for RTE_FLOW_ITEM_TYPE_PORT. */ +/** Default mask for RTE_FLOW_ITEM_TYPE_PHY_PORT. */ #ifndef __cplusplus -static const struct rte_flow_item_port rte_flow_item_port_mask = { +static const struct rte_flow_item_phy_port rte_flow_item_phy_port_mask = { .index = 0x00000000, }; #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 * @@ -458,7 +585,7 @@ struct rte_flow_item_raw { int32_t offset; /**< Absolute or relative offset for pattern. */ uint16_t limit; /**< Search area limit for start of pattern. */ uint16_t length; /**< Pattern length. */ - uint8_t pattern[]; /**< Byte string to look for. */ + const uint8_t *pattern; /**< Byte string to look for. */ }; /** Default mask for RTE_FLOW_ITEM_TYPE_RAW. */ @@ -470,6 +597,7 @@ static const struct rte_flow_item_raw rte_flow_item_raw_mask = { .offset = 0xffffffff, .limit = 0xffff, .length = 0xffff, + .pattern = NULL, }; #endif @@ -477,11 +605,17 @@ static const struct rte_flow_item_raw rte_flow_item_raw_mask = { * RTE_FLOW_ITEM_TYPE_ETH * * Matches an Ethernet header. + * + * The @p type field either stands for "EtherType" or "TPID" when followed + * by so-called layer 2.5 pattern items such as RTE_FLOW_ITEM_TYPE_VLAN. In + * the latter case, @p type refers to that of the outer header, with the + * inner EtherType/TPID provided by the subsequent pattern item. This is the + * same order as on the wire. */ struct rte_flow_item_eth { struct ether_addr dst; /**< Destination MAC. */ struct ether_addr src; /**< Source MAC. */ - rte_be16_t type; /**< EtherType. */ + rte_be16_t type; /**< EtherType or TPID. */ }; /** Default mask for RTE_FLOW_ITEM_TYPE_ETH. */ @@ -1000,6 +1134,21 @@ enum rte_flow_action_type { */ RTE_FLOW_ACTION_TYPE_VF, + /** + * Directs packets to a given physical port index of the underlying + * device. + * + * See struct rte_flow_action_phy_port. + */ + 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). * @@ -1014,7 +1163,260 @@ enum rte_flow_action_type { * * See struct rte_flow_action_security. */ - RTE_FLOW_ACTION_TYPE_SECURITY + RTE_FLOW_ACTION_TYPE_SECURITY, + + /** + * Implements OFPAT_SET_MPLS_TTL ("MPLS TTL") as defined by the + * OpenFlow Switch Specification. + * + * See struct rte_flow_action_of_set_mpls_ttl. + */ + RTE_FLOW_ACTION_TYPE_OF_SET_MPLS_TTL, + + /** + * Implements OFPAT_DEC_MPLS_TTL ("decrement MPLS TTL") as defined + * by the OpenFlow Switch Specification. + * + * No associated configuration structure. + */ + RTE_FLOW_ACTION_TYPE_OF_DEC_MPLS_TTL, + + /** + * Implements OFPAT_SET_NW_TTL ("IP TTL") as defined by the OpenFlow + * Switch Specification. + * + * See struct rte_flow_action_of_set_nw_ttl. + */ + RTE_FLOW_ACTION_TYPE_OF_SET_NW_TTL, + + /** + * Implements OFPAT_DEC_NW_TTL ("decrement IP TTL") as defined by + * the OpenFlow Switch Specification. + * + * No associated configuration structure. + */ + RTE_FLOW_ACTION_TYPE_OF_DEC_NW_TTL, + + /** + * Implements OFPAT_COPY_TTL_OUT ("copy TTL "outwards" -- from + * next-to-outermost to outermost") as defined by the OpenFlow + * Switch Specification. + * + * No associated configuration structure. + */ + RTE_FLOW_ACTION_TYPE_OF_COPY_TTL_OUT, + + /** + * Implements OFPAT_COPY_TTL_IN ("copy TTL "inwards" -- from + * outermost to next-to-outermost") as defined by the OpenFlow + * Switch Specification. + * + * No associated configuration structure. + */ + RTE_FLOW_ACTION_TYPE_OF_COPY_TTL_IN, + + /** + * Implements OFPAT_POP_VLAN ("pop the outer VLAN tag") as defined + * by the OpenFlow Switch Specification. + * + * No associated configuration structure. + */ + RTE_FLOW_ACTION_TYPE_OF_POP_VLAN, + + /** + * Implements OFPAT_PUSH_VLAN ("push a new VLAN tag") as defined by + * the OpenFlow Switch Specification. + * + * See struct rte_flow_action_of_push_vlan. + */ + RTE_FLOW_ACTION_TYPE_OF_PUSH_VLAN, + + /** + * Implements OFPAT_SET_VLAN_VID ("set the 802.1q VLAN id") as + * defined by the OpenFlow Switch Specification. + * + * See struct rte_flow_action_of_set_vlan_vid. + */ + RTE_FLOW_ACTION_TYPE_OF_SET_VLAN_VID, + + /** + * Implements OFPAT_SET_LAN_PCP ("set the 802.1q priority") as + * defined by the OpenFlow Switch Specification. + * + * See struct rte_flow_action_of_set_vlan_pcp. + */ + RTE_FLOW_ACTION_TYPE_OF_SET_VLAN_PCP, + + /** + * Implements OFPAT_POP_MPLS ("pop the outer MPLS tag") as defined + * by the OpenFlow Switch Specification. + * + * See struct rte_flow_action_of_pop_mpls. + */ + RTE_FLOW_ACTION_TYPE_OF_POP_MPLS, + + /** + * Implements OFPAT_PUSH_MPLS ("push a new MPLS tag") as defined by + * the OpenFlow Switch Specification. + * + * See struct rte_flow_action_of_push_mpls. + */ + RTE_FLOW_ACTION_TYPE_OF_PUSH_MPLS, + + /** + * Encapsulate flow in VXLAN tunnel as defined in + * rte_flow_action_vxlan_encap action structure. + * + * See struct rte_flow_action_vxlan_encap. + */ + RTE_FLOW_ACTION_TYPE_VXLAN_ENCAP, + + /** + * Decapsulate outer most VXLAN tunnel from matched flow. + * + * If flow pattern does not define a valid VXLAN tunnel (as specified by + * RFC7348) then the PMD should return a RTE_FLOW_ERROR_TYPE_ACTION + * error. + */ + RTE_FLOW_ACTION_TYPE_VXLAN_DECAP, + + /** + * Encapsulate flow in NVGRE tunnel defined in the + * rte_flow_action_nvgre_encap action structure. + * + * See struct rte_flow_action_nvgre_encap. + */ + RTE_FLOW_ACTION_TYPE_NVGRE_ENCAP, + + /** + * Decapsulate outer most NVGRE tunnel from matched flow. + * + * If flow pattern does not define a valid NVGRE tunnel (as specified by + * RFC7637) then the PMD should return a RTE_FLOW_ERROR_TYPE_ACTION + * error. + */ + RTE_FLOW_ACTION_TYPE_NVGRE_DECAP, + + /** + * Add outer header whose template is provided in its data buffer + * + * See struct rte_flow_action_raw_encap. + */ + RTE_FLOW_ACTION_TYPE_RAW_ENCAP, + + /** + * Remove outer header whose template is provided in its data buffer. + * + * See struct rte_flow_action_raw_decap + */ + RTE_FLOW_ACTION_TYPE_RAW_DECAP, + + /** + * Modify IPv4 source address in the outermost IPv4 header. + * + * If flow pattern does not define a valid RTE_FLOW_ITEM_TYPE_IPV4, + * then the PMD should return a RTE_FLOW_ERROR_TYPE_ACTION error. + * + * See struct rte_flow_action_set_ipv4. + */ + RTE_FLOW_ACTION_TYPE_SET_IPV4_SRC, + + /** + * Modify IPv4 destination address in the outermost IPv4 header. + * + * If flow pattern does not define a valid RTE_FLOW_ITEM_TYPE_IPV4, + * then the PMD should return a RTE_FLOW_ERROR_TYPE_ACTION error. + * + * See struct rte_flow_action_set_ipv4. + */ + RTE_FLOW_ACTION_TYPE_SET_IPV4_DST, + + /** + * Modify IPv6 source address in the outermost IPv6 header. + * + * If flow pattern does not define a valid RTE_FLOW_ITEM_TYPE_IPV6, + * then the PMD should return a RTE_FLOW_ERROR_TYPE_ACTION error. + * + * See struct rte_flow_action_set_ipv6. + */ + RTE_FLOW_ACTION_TYPE_SET_IPV6_SRC, + + /** + * Modify IPv6 destination address in the outermost IPv6 header. + * + * If flow pattern does not define a valid RTE_FLOW_ITEM_TYPE_IPV6, + * then the PMD should return a RTE_FLOW_ERROR_TYPE_ACTION error. + * + * See struct rte_flow_action_set_ipv6. + */ + RTE_FLOW_ACTION_TYPE_SET_IPV6_DST, + + /** + * Modify source port number in the outermost TCP/UDP header. + * + * If flow pattern does not define a valid RTE_FLOW_ITEM_TYPE_TCP + * or RTE_FLOW_ITEM_TYPE_UDP, then the PMD should return a + * RTE_FLOW_ERROR_TYPE_ACTION error. + * + * See struct rte_flow_action_set_tp. + */ + RTE_FLOW_ACTION_TYPE_SET_TP_SRC, + + /** + * Modify destination port number in the outermost TCP/UDP header. + * + * If flow pattern does not define a valid RTE_FLOW_ITEM_TYPE_TCP + * or RTE_FLOW_ITEM_TYPE_UDP, then the PMD should return a + * RTE_FLOW_ERROR_TYPE_ACTION error. + * + * See struct rte_flow_action_set_tp. + */ + RTE_FLOW_ACTION_TYPE_SET_TP_DST, + + /** + * Swap the source and destination MAC addresses in the outermost + * Ethernet header. + * + * If flow pattern does not define a valid RTE_FLOW_ITEM_TYPE_ETH, + * then the PMD should return a RTE_FLOW_ERROR_TYPE_ACTION error. + * + * No associated configuration structure. + */ + RTE_FLOW_ACTION_TYPE_MAC_SWAP, + + /** + * Decrease TTL value directly + * + * No associated configuration structure. + */ + RTE_FLOW_ACTION_TYPE_DEC_TTL, + + /** + * Set TTL value + * + * See struct rte_flow_action_set_ttl + */ + RTE_FLOW_ACTION_TYPE_SET_TTL, + + /** + * Set source MAC address from matched flow. + * + * If flow pattern does not define a valid RTE_FLOW_ITEM_TYPE_ETH, + * the PMD should return a RTE_FLOW_ERROR_TYPE_ACTION error. + * + * See struct rte_flow_action_set_mac. + */ + RTE_FLOW_ACTION_TYPE_SET_MAC_SRC, + + /** + * Set destination MAC address from matched flow. + * + * If flow pattern does not define a valid RTE_FLOW_ITEM_TYPE_ETH, + * the PMD should return a RTE_FLOW_ERROR_TYPE_ACTION error. + * + * See struct rte_flow_action_set_mac. + */ + RTE_FLOW_ACTION_TYPE_SET_MAC_DST, }; /** @@ -1042,6 +1444,38 @@ struct rte_flow_action_queue { uint16_t index; /**< Queue index to use. */ }; + +/** + * @warning + * @b EXPERIMENTAL: this structure may change without prior notice + * + * RTE_FLOW_ACTION_TYPE_COUNT + * + * Adds a counter action to a matched flow. + * + * If more than one count action is specified in a single flow rule, then each + * action must specify a unique id. + * + * Counters can be retrieved and reset through ``rte_flow_query()``, see + * ``struct rte_flow_query_count``. + * + * The shared flag indicates whether the counter is unique to the flow rule the + * action is specified with, or whether it is a shared counter. + * + * For a count action with the shared flag set, then then a global device + * namespace is assumed for the counter id, so that any matched flow rules using + * a count action with the same counter id on the same port will contribute to + * that counter. + * + * For ports within the same switch domain then the counter id namespace extends + * to all ports within that switch domain. + */ +struct rte_flow_action_count { + uint32_t shared:1; /**< Share counter ID with other flow rules. */ + uint32_t reserved:31; /**< Reserved, must be zero. */ + uint32_t id; /**< Counter ID. */ +}; + /** * RTE_FLOW_ACTION_TYPE_COUNT (query) * @@ -1137,7 +1571,34 @@ struct rte_flow_action_rss { struct rte_flow_action_vf { uint32_t original:1; /**< Use original VF ID if possible. */ uint32_t reserved:31; /**< Reserved, must be zero. */ - uint32_t id; /**< VF ID to redirect packets to. */ + uint32_t id; /**< VF ID. */ +}; + +/** + * RTE_FLOW_ACTION_TYPE_PHY_PORT + * + * Directs packets to a given physical port index of the underlying + * device. + * + * @see RTE_FLOW_ITEM_TYPE_PHY_PORT + */ +struct rte_flow_action_phy_port { + uint32_t original:1; /**< Use original port index if possible. */ + uint32_t reserved:31; /**< Reserved, must be zero. */ + uint32_t index; /**< Physical port index. */ +}; + +/** + * 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. */ }; /** @@ -1186,6 +1647,253 @@ struct rte_flow_action_security { }; /** + * RTE_FLOW_ACTION_TYPE_OF_SET_MPLS_TTL + * + * Implements OFPAT_SET_MPLS_TTL ("MPLS TTL") as defined by the OpenFlow + * Switch Specification. + */ +struct rte_flow_action_of_set_mpls_ttl { + uint8_t mpls_ttl; /**< MPLS TTL. */ +}; + +/** + * RTE_FLOW_ACTION_TYPE_OF_SET_NW_TTL + * + * Implements OFPAT_SET_NW_TTL ("IP TTL") as defined by the OpenFlow Switch + * Specification. + */ +struct rte_flow_action_of_set_nw_ttl { + uint8_t nw_ttl; /**< IP TTL. */ +}; + +/** + * RTE_FLOW_ACTION_TYPE_OF_PUSH_VLAN + * + * Implements OFPAT_PUSH_VLAN ("push a new VLAN tag") as defined by the + * OpenFlow Switch Specification. + */ +struct rte_flow_action_of_push_vlan { + rte_be16_t ethertype; /**< EtherType. */ +}; + +/** + * RTE_FLOW_ACTION_TYPE_OF_SET_VLAN_VID + * + * Implements OFPAT_SET_VLAN_VID ("set the 802.1q VLAN id") as defined by + * the OpenFlow Switch Specification. + */ +struct rte_flow_action_of_set_vlan_vid { + rte_be16_t vlan_vid; /**< VLAN id. */ +}; + +/** + * RTE_FLOW_ACTION_TYPE_OF_SET_VLAN_PCP + * + * Implements OFPAT_SET_LAN_PCP ("set the 802.1q priority") as defined by + * the OpenFlow Switch Specification. + */ +struct rte_flow_action_of_set_vlan_pcp { + uint8_t vlan_pcp; /**< VLAN priority. */ +}; + +/** + * RTE_FLOW_ACTION_TYPE_OF_POP_MPLS + * + * Implements OFPAT_POP_MPLS ("pop the outer MPLS tag") as defined by the + * OpenFlow Switch Specification. + */ +struct rte_flow_action_of_pop_mpls { + rte_be16_t ethertype; /**< EtherType. */ +}; + +/** + * RTE_FLOW_ACTION_TYPE_OF_PUSH_MPLS + * + * Implements OFPAT_PUSH_MPLS ("push a new MPLS tag") as defined by the + * OpenFlow Switch Specification. + */ +struct rte_flow_action_of_push_mpls { + rte_be16_t ethertype; /**< EtherType. */ +}; + +/** + * @warning + * @b EXPERIMENTAL: this structure may change without prior notice + * + * RTE_FLOW_ACTION_TYPE_VXLAN_ENCAP + * + * VXLAN tunnel end-point encapsulation data definition + * + * The tunnel definition is provided through the flow item pattern, the + * provided pattern must conform to RFC7348 for the tunnel specified. The flow + * definition must be provided in order from the RTE_FLOW_ITEM_TYPE_ETH + * definition up the end item which is specified by RTE_FLOW_ITEM_TYPE_END. + * + * The mask field allows user to specify which fields in the flow item + * definitions can be ignored and which have valid data and can be used + * verbatim. + * + * Note: the last field is not used in the definition of a tunnel and can be + * ignored. + * + * Valid flow definition for RTE_FLOW_ACTION_TYPE_VXLAN_ENCAP include: + * + * - ETH / IPV4 / UDP / VXLAN / END + * - ETH / IPV6 / UDP / VXLAN / END + * - ETH / VLAN / IPV4 / UDP / VXLAN / END + * + */ +struct rte_flow_action_vxlan_encap { + /** + * Encapsulating vxlan tunnel definition + * (terminated by the END pattern item). + */ + struct rte_flow_item *definition; +}; + +/** + * @warning + * @b EXPERIMENTAL: this structure may change without prior notice + * + * RTE_FLOW_ACTION_TYPE_NVGRE_ENCAP + * + * NVGRE tunnel end-point encapsulation data definition + * + * The tunnel definition is provided through the flow item pattern the + * provided pattern must conform with RFC7637. The flow definition must be + * provided in order from the RTE_FLOW_ITEM_TYPE_ETH definition up the end item + * which is specified by RTE_FLOW_ITEM_TYPE_END. + * + * The mask field allows user to specify which fields in the flow item + * definitions can be ignored and which have valid data and can be used + * verbatim. + * + * Note: the last field is not used in the definition of a tunnel and can be + * ignored. + * + * Valid flow definition for RTE_FLOW_ACTION_TYPE_NVGRE_ENCAP include: + * + * - ETH / IPV4 / NVGRE / END + * - ETH / VLAN / IPV6 / NVGRE / END + * + */ +struct rte_flow_action_nvgre_encap { + /** + * Encapsulating vxlan tunnel definition + * (terminated by the END pattern item). + */ + struct rte_flow_item *definition; +}; + +/** + * @warning + * @b EXPERIMENTAL: this structure may change without prior notice + * + * RTE_FLOW_ACTION_TYPE_RAW_ENCAP + * + * Raw tunnel end-point encapsulation data definition. + * + * The data holds the headers definitions to be applied on the packet. + * The data must start with ETH header up to the tunnel item header itself. + * When used right after RAW_DECAP (for decapsulating L3 tunnel type for + * example MPLSoGRE) the data will just hold layer 2 header. + * + * The preserve parameter holds which bits in the packet the PMD is not allowed + * to change, this parameter can also be NULL and then the PMD is allowed + * to update any field. + * + * size holds the number of bytes in @p data and @p preserve. + */ +struct rte_flow_action_raw_encap { + uint8_t *data; /**< Encapsulation data. */ + uint8_t *preserve; /**< Bit-mask of @p data to preserve on output. */ + size_t size; /**< Size of @p data and @p preserve. */ +}; + +/** + * @warning + * @b EXPERIMENTAL: this structure may change without prior notice + * + * RTE_FLOW_ACTION_TYPE_RAW_DECAP + * + * Raw tunnel end-point decapsulation data definition. + * + * The data holds the headers definitions to be removed from the packet. + * The data must start with ETH header up to the tunnel item header itself. + * When used right before RAW_DECAP (for encapsulating L3 tunnel type for + * example MPLSoGRE) the data will just hold layer 2 header. + * + * size holds the number of bytes in @p data. + */ +struct rte_flow_action_raw_decap { + uint8_t *data; /**< Encapsulation data. */ + size_t size; /**< Size of @p data and @p preserve. */ +}; + +/** + * @warning + * @b EXPERIMENTAL: this structure may change without prior notice + * + * RTE_FLOW_ACTION_TYPE_SET_IPV4_SRC + * RTE_FLOW_ACTION_TYPE_SET_IPV4_DST + * + * Allows modification of IPv4 source (RTE_FLOW_ACTION_TYPE_SET_IPV4_SRC) + * and destination address (RTE_FLOW_ACTION_TYPE_SET_IPV4_DST) in the + * specified outermost IPv4 header. + */ +struct rte_flow_action_set_ipv4 { + rte_be32_t ipv4_addr; +}; + +/** + * @warning + * @b EXPERIMENTAL: this structure may change without prior notice + * + * RTE_FLOW_ACTION_TYPE_SET_IPV6_SRC + * RTE_FLOW_ACTION_TYPE_SET_IPV6_DST + * + * Allows modification of IPv6 source (RTE_FLOW_ACTION_TYPE_SET_IPV6_SRC) + * and destination address (RTE_FLOW_ACTION_TYPE_SET_IPV6_DST) in the + * specified outermost IPv6 header. + */ +struct rte_flow_action_set_ipv6 { + uint8_t ipv6_addr[16]; +}; + +/** + * @warning + * @b EXPERIMENTAL: this structure may change without prior notice + * + * RTE_FLOW_ACTION_TYPE_SET_TP_SRC + * RTE_FLOW_ACTION_TYPE_SET_TP_DST + * + * Allows modification of source (RTE_FLOW_ACTION_TYPE_SET_TP_SRC) + * and destination (RTE_FLOW_ACTION_TYPE_SET_TP_DST) port numbers + * in the specified outermost TCP/UDP header. + */ +struct rte_flow_action_set_tp { + rte_be16_t port; +}; + +/** + * RTE_FLOW_ACTION_TYPE_SET_TTL + * + * Set the TTL value directly for IPv4 or IPv6 + */ +struct rte_flow_action_set_ttl { + uint8_t ttl_value; +}; + +/** + * RTE_FLOW_ACTION_TYPE_SET_MAC + * + * Set MAC address from the matched flow + */ +struct rte_flow_action_set_mac { + uint8_t mac_addr[ETHER_ADDR_LEN]; +}; + +/* * Definition of a single action. * * A list of actions is terminated by a END action. @@ -1386,7 +2094,7 @@ rte_flow_flush(uint16_t port_id, * @param flow * Flow rule handle to query. * @param action - * Action type to query. + * Action definition as defined in original flow rule. * @param[in, out] data * Pointer to storage for the associated query data type. * @param[out] error @@ -1399,7 +2107,7 @@ rte_flow_flush(uint16_t port_id, int rte_flow_query(uint16_t port_id, struct rte_flow *flow, - enum rte_flow_action_type action, + const struct rte_flow_action *action, void *data, struct rte_flow_error *error); From patchwork Wed Nov 20 15:28:08 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eli Britstein X-Patchwork-Id: 1198267 X-Patchwork-Delegate: i.maximets@samsung.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=openvswitch.org (client-ip=140.211.166.136; helo=silver.osuosl.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=mellanox.com Received: from silver.osuosl.org (smtp3.osuosl.org [140.211.166.136]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 47J6Jj2fD5z9sR4 for ; Thu, 21 Nov 2019 02:37:41 +1100 (AEDT) Received: from localhost (localhost [127.0.0.1]) by silver.osuosl.org (Postfix) with ESMTP id 8F226248F6; Wed, 20 Nov 2019 15:37:39 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from silver.osuosl.org ([127.0.0.1]) by localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id Notlp7A+4MTo; Wed, 20 Nov 2019 15:37:23 +0000 (UTC) Received: from lists.linuxfoundation.org (lf-lists.osuosl.org [140.211.9.56]) by silver.osuosl.org (Postfix) with ESMTP id D132D25E8F; Wed, 20 Nov 2019 15:35:54 +0000 (UTC) Received: from lf-lists.osuosl.org (localhost [127.0.0.1]) by lists.linuxfoundation.org (Postfix) with ESMTP id C11EDC1DED; Wed, 20 Nov 2019 15:35:54 +0000 (UTC) X-Original-To: dev@openvswitch.org Delivered-To: ovs-dev@lists.linuxfoundation.org Received: from fraxinus.osuosl.org (smtp4.osuosl.org [140.211.166.137]) by lists.linuxfoundation.org (Postfix) with ESMTP id 34AEEC1DDB for ; Wed, 20 Nov 2019 15:35:37 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by fraxinus.osuosl.org (Postfix) with ESMTP id 29D7486C6C for ; Wed, 20 Nov 2019 15:35:37 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from fraxinus.osuosl.org ([127.0.0.1]) by localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id o2lAs0BYJ6_g for ; Wed, 20 Nov 2019 15:35:35 +0000 (UTC) X-Greylist: from auto-whitelisted by SQLgrey-1.7.6 Received: from mellanox.co.il (mail-il-dmz.mellanox.com [193.47.165.129]) by fraxinus.osuosl.org (Postfix) with ESMTP id 1AED086C51 for ; Wed, 20 Nov 2019 15:35:33 +0000 (UTC) Received: from Internal Mail-Server by MTLPINE1 (envelope-from elibr@mellanox.com) with ESMTPS (AES256-SHA encrypted); 20 Nov 2019 17:28:48 +0200 Received: from dev-r-vrt-215.mtr.labs.mlnx. (dev-r-vrt-215.mtr.labs.mlnx [10.212.215.1]) by labmailer.mlnx (8.13.8/8.13.8) with ESMTP id xAKFSlW8001566; Wed, 20 Nov 2019 17:28:47 +0200 From: Eli Britstein To: dev@openvswitch.org, Ilya Maximets , Ian Stokes Date: Wed, 20 Nov 2019 15:28:08 +0000 Message-Id: <20191120152826.25074-3-elibr@mellanox.com> X-Mailer: git-send-email 2.14.5 In-Reply-To: <20191120152826.25074-1-elibr@mellanox.com> References: <20191120152826.25074-1-elibr@mellanox.com> Cc: Oz Shlomo , Majd Dibbiny , Eli Britstein , Ameer Mahagneh Subject: [ovs-dev] [PATCH 02/20] netdev-offload-dpdk: Refactor flow patterns and actions code X-BeenThere: ovs-dev@openvswitch.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: ovs-dev-bounces@openvswitch.org Sender: "dev" Refactor the flow patterns and actions code to a new source files for better readability and towards adding more code to it. Signed-off-by: Eli Britstein Reviewed-by: Oz Shlomo --- lib/automake.mk | 4 +- lib/netdev-offload-dpdk-flow.c | 479 ++++++++++++++++++++++++++++++++++++++ lib/netdev-offload-dpdk-private.h | 69 ++++++ lib/netdev-offload-dpdk.c | 466 +----------------------------------- 4 files changed, 562 insertions(+), 456 deletions(-) create mode 100644 lib/netdev-offload-dpdk-flow.c create mode 100644 lib/netdev-offload-dpdk-private.h diff --git a/lib/automake.mk b/lib/automake.mk index 17b36b43d..3a813af85 100644 --- a/lib/automake.mk +++ b/lib/automake.mk @@ -142,6 +142,7 @@ lib_libopenvswitch_la_SOURCES = \ lib/netdev-dummy.c \ lib/netdev-offload.c \ lib/netdev-offload.h \ + lib/netdev-offload-dpdk-private.h \ lib/netdev-offload-provider.h \ lib/netdev-provider.h \ lib/netdev-vport.c \ @@ -426,7 +427,8 @@ if DPDK_NETDEV lib_libopenvswitch_la_SOURCES += \ lib/dpdk.c \ lib/netdev-dpdk.c \ - lib/netdev-offload-dpdk.c + lib/netdev-offload-dpdk.c \ + lib/netdev-offload-dpdk-flow.c else lib_libopenvswitch_la_SOURCES += \ lib/dpdk-stub.c diff --git a/lib/netdev-offload-dpdk-flow.c b/lib/netdev-offload-dpdk-flow.c new file mode 100644 index 000000000..d1d5ce2c6 --- /dev/null +++ b/lib/netdev-offload-dpdk-flow.c @@ -0,0 +1,479 @@ +/* + * Copyright (c) 2019 Mellanox Technologies, Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include + +#include + +#include "dpif-netdev.h" +#include "netdev-offload-dpdk-private.h" +#include "openvswitch/match.h" +#include "openvswitch/vlog.h" +#include "packets.h" + +VLOG_DEFINE_THIS_MODULE(netdev_offload_dpdk_flow); + +void +netdev_dpdk_flow_patterns_free(struct flow_patterns *patterns) +{ + /* When calling this function 'patterns' must be valid */ + free(patterns->items); + patterns->items = NULL; + patterns->cnt = 0; +} + +void +netdev_dpdk_flow_actions_free(struct flow_actions *actions) +{ + /* When calling this function 'actions' must be valid */ + int i; + + for (i = 0; i < actions->cnt; i++) { + if (actions->actions[i].conf) { + free((void *)actions->actions[i].conf); + } + } + free(actions->actions); + actions->actions = NULL; + actions->cnt = 0; +} + +static void +dump_flow_pattern(struct rte_flow_item *item) +{ + struct ds s; + + if (!VLOG_IS_DBG_ENABLED() || item->type == RTE_FLOW_ITEM_TYPE_END) { + return; + } + + ds_init(&s); + + if (item->type == RTE_FLOW_ITEM_TYPE_ETH) { + const struct rte_flow_item_eth *eth_spec = item->spec; + const struct rte_flow_item_eth *eth_mask = item->mask; + + ds_put_cstr(&s, "rte flow eth pattern:\n"); + if (eth_spec) { + ds_put_format(&s, + " Spec: src="ETH_ADDR_FMT", dst="ETH_ADDR_FMT", " + "type=0x%04" PRIx16"\n", + ETH_ADDR_BYTES_ARGS(eth_spec->src.addr_bytes), + ETH_ADDR_BYTES_ARGS(eth_spec->dst.addr_bytes), + ntohs(eth_spec->type)); + } else { + ds_put_cstr(&s, " Spec = null\n"); + } + if (eth_mask) { + ds_put_format(&s, + " Mask: src="ETH_ADDR_FMT", dst="ETH_ADDR_FMT", " + "type=0x%04"PRIx16"\n", + ETH_ADDR_BYTES_ARGS(eth_mask->src.addr_bytes), + ETH_ADDR_BYTES_ARGS(eth_mask->dst.addr_bytes), + ntohs(eth_mask->type)); + } else { + ds_put_cstr(&s, " Mask = null\n"); + } + } + + if (item->type == RTE_FLOW_ITEM_TYPE_VLAN) { + const struct rte_flow_item_vlan *vlan_spec = item->spec; + const struct rte_flow_item_vlan *vlan_mask = item->mask; + + ds_put_cstr(&s, "rte flow vlan pattern:\n"); + if (vlan_spec) { + ds_put_format(&s, + " Spec: inner_type=0x%"PRIx16", tci=0x%"PRIx16"\n", + ntohs(vlan_spec->inner_type), ntohs(vlan_spec->tci)); + } else { + ds_put_cstr(&s, " Spec = null\n"); + } + + if (vlan_mask) { + ds_put_format(&s, + " Mask: inner_type=0x%"PRIx16", tci=0x%"PRIx16"\n", + ntohs(vlan_mask->inner_type), ntohs(vlan_mask->tci)); + } else { + ds_put_cstr(&s, " Mask = null\n"); + } + } + + if (item->type == RTE_FLOW_ITEM_TYPE_IPV4) { + const struct rte_flow_item_ipv4 *ipv4_spec = item->spec; + const struct rte_flow_item_ipv4 *ipv4_mask = item->mask; + + ds_put_cstr(&s, "rte flow ipv4 pattern:\n"); + if (ipv4_spec) { + ds_put_format(&s, + " Spec: tos=0x%"PRIx8", ttl=%"PRIx8 + ", proto=0x%"PRIx8 + ", src="IP_FMT", dst="IP_FMT"\n", + ipv4_spec->hdr.type_of_service, + ipv4_spec->hdr.time_to_live, + ipv4_spec->hdr.next_proto_id, + IP_ARGS(ipv4_spec->hdr.src_addr), + IP_ARGS(ipv4_spec->hdr.dst_addr)); + } else { + ds_put_cstr(&s, " Spec = null\n"); + } + if (ipv4_mask) { + ds_put_format(&s, + " Mask: tos=0x%"PRIx8", ttl=%"PRIx8 + ", proto=0x%"PRIx8 + ", src="IP_FMT", dst="IP_FMT"\n", + ipv4_mask->hdr.type_of_service, + ipv4_mask->hdr.time_to_live, + ipv4_mask->hdr.next_proto_id, + IP_ARGS(ipv4_mask->hdr.src_addr), + IP_ARGS(ipv4_mask->hdr.dst_addr)); + } else { + ds_put_cstr(&s, " Mask = null\n"); + } + } + + if (item->type == RTE_FLOW_ITEM_TYPE_UDP) { + const struct rte_flow_item_udp *udp_spec = item->spec; + const struct rte_flow_item_udp *udp_mask = item->mask; + + ds_put_cstr(&s, "rte flow udp pattern:\n"); + if (udp_spec) { + ds_put_format(&s, + " Spec: src_port=%"PRIu16", dst_port=%"PRIu16"\n", + ntohs(udp_spec->hdr.src_port), + ntohs(udp_spec->hdr.dst_port)); + } else { + ds_put_cstr(&s, " Spec = null\n"); + } + if (udp_mask) { + ds_put_format(&s, + " Mask: src_port=0x%"PRIx16 + ", dst_port=0x%"PRIx16"\n", + ntohs(udp_mask->hdr.src_port), + ntohs(udp_mask->hdr.dst_port)); + } else { + ds_put_cstr(&s, " Mask = null\n"); + } + } + + if (item->type == RTE_FLOW_ITEM_TYPE_SCTP) { + const struct rte_flow_item_sctp *sctp_spec = item->spec; + const struct rte_flow_item_sctp *sctp_mask = item->mask; + + ds_put_cstr(&s, "rte flow sctp pattern:\n"); + if (sctp_spec) { + ds_put_format(&s, + " Spec: src_port=%"PRIu16", dst_port=%"PRIu16"\n", + ntohs(sctp_spec->hdr.src_port), + ntohs(sctp_spec->hdr.dst_port)); + } else { + ds_put_cstr(&s, " Spec = null\n"); + } + if (sctp_mask) { + ds_put_format(&s, + " Mask: src_port=0x%"PRIx16 + ", dst_port=0x%"PRIx16"\n", + ntohs(sctp_mask->hdr.src_port), + ntohs(sctp_mask->hdr.dst_port)); + } else { + ds_put_cstr(&s, " Mask = null\n"); + } + } + + if (item->type == RTE_FLOW_ITEM_TYPE_ICMP) { + const struct rte_flow_item_icmp *icmp_spec = item->spec; + const struct rte_flow_item_icmp *icmp_mask = item->mask; + + ds_put_cstr(&s, "rte flow icmp pattern:\n"); + if (icmp_spec) { + ds_put_format(&s, + " Spec: icmp_type=%"PRIu8", icmp_code=%"PRIu8"\n", + icmp_spec->hdr.icmp_type, + icmp_spec->hdr.icmp_code); + } else { + ds_put_cstr(&s, " Spec = null\n"); + } + if (icmp_mask) { + ds_put_format(&s, + " Mask: icmp_type=0x%"PRIx8 + ", icmp_code=0x%"PRIx8"\n", + icmp_spec->hdr.icmp_type, + icmp_spec->hdr.icmp_code); + } else { + ds_put_cstr(&s, " Mask = null\n"); + } + } + + if (item->type == RTE_FLOW_ITEM_TYPE_TCP) { + const struct rte_flow_item_tcp *tcp_spec = item->spec; + const struct rte_flow_item_tcp *tcp_mask = item->mask; + + ds_put_cstr(&s, "rte flow tcp pattern:\n"); + if (tcp_spec) { + ds_put_format(&s, + " Spec: src_port=%"PRIu16", dst_port=%"PRIu16 + ", data_off=0x%"PRIx8", tcp_flags=0x%"PRIx8"\n", + ntohs(tcp_spec->hdr.src_port), + ntohs(tcp_spec->hdr.dst_port), + tcp_spec->hdr.data_off, + tcp_spec->hdr.tcp_flags); + } else { + ds_put_cstr(&s, " Spec = null\n"); + } + if (tcp_mask) { + ds_put_format(&s, + " Mask: src_port=%"PRIx16", dst_port=%"PRIx16 + ", data_off=0x%"PRIx8", tcp_flags=0x%"PRIx8"\n", + ntohs(tcp_mask->hdr.src_port), + ntohs(tcp_mask->hdr.dst_port), + tcp_mask->hdr.data_off, + tcp_mask->hdr.tcp_flags); + } else { + ds_put_cstr(&s, " Mask = null\n"); + } + } + + VLOG_DBG("%s", ds_cstr(&s)); + ds_destroy(&s); +} + +static void +add_flow_pattern(struct flow_patterns *patterns, enum rte_flow_item_type type, + const void *spec, const void *mask) +{ + int cnt = patterns->cnt; + + if (cnt == 0) { + patterns->current_max = 8; + patterns->items = xcalloc(patterns->current_max, + sizeof *patterns->items); + } else if (cnt == patterns->current_max) { + patterns->current_max *= 2; + patterns->items = xrealloc(patterns->items, patterns->current_max * + sizeof *patterns->items); + } + + patterns->items[cnt].type = type; + patterns->items[cnt].spec = spec; + patterns->items[cnt].mask = mask; + patterns->items[cnt].last = NULL; + dump_flow_pattern(&patterns->items[cnt]); + patterns->cnt++; +} + +static void +add_flow_action(struct flow_actions *actions, enum rte_flow_action_type type, + const void *conf) +{ + int cnt = actions->cnt; + + if (cnt == 0) { + actions->current_max = 8; + actions->actions = xcalloc(actions->current_max, + sizeof *actions->actions); + } else if (cnt == actions->current_max) { + actions->current_max *= 2; + actions->actions = xrealloc(actions->actions, actions->current_max * + sizeof *actions->actions); + } + + actions->actions[cnt].type = type; + actions->actions[cnt].conf = conf; + actions->cnt++; +} + +void +netdev_dpdk_flow_actions_add_mark_rss(struct flow_actions *actions, + struct netdev *netdev, + uint32_t mark_id) +{ + struct rte_flow_action_mark *mark; + struct action_rss_data { + struct rte_flow_action_rss conf; + uint16_t queue[0]; + } *rss_data; + int i; + + mark = xmalloc(sizeof *mark); + rss_data = xmalloc(sizeof *rss_data + + netdev_n_rxq(netdev) * sizeof rss_data->queue[0]); + *rss_data = (struct action_rss_data) { + .conf = (struct rte_flow_action_rss) { + .func = RTE_ETH_HASH_FUNCTION_DEFAULT, + .level = 0, + .types = 0, + .queue_num = netdev_n_rxq(netdev), + .queue = rss_data->queue, + .key_len = 0, + .key = NULL + }, + }; + + /* Override queue array with default. */ + for (i = 0; i < netdev_n_rxq(netdev); i++) { + rss_data->queue[i] = i; + } + + mark->id = mark_id; + add_flow_action(actions, RTE_FLOW_ACTION_TYPE_MARK, mark); + add_flow_action(actions, RTE_FLOW_ACTION_TYPE_RSS, &rss_data->conf); + add_flow_action(actions, RTE_FLOW_ACTION_TYPE_END, NULL); +} + +int +netdev_dpdk_flow_patterns_add(struct flow_patterns *patterns, + struct flow_pattern_items *spec, + struct flow_pattern_items *mask, + const struct match *match) +{ + uint8_t proto = 0; + + /* Eth */ + if (!eth_addr_is_zero(match->wc.masks.dl_src) || + !eth_addr_is_zero(match->wc.masks.dl_dst)) { + memcpy(&spec->eth.dst, &match->flow.dl_dst, sizeof spec->eth.dst); + memcpy(&spec->eth.src, &match->flow.dl_src, sizeof spec->eth.src); + spec->eth.type = match->flow.dl_type; + + memcpy(&mask->eth.dst, &match->wc.masks.dl_dst, sizeof mask->eth.dst); + memcpy(&mask->eth.src, &match->wc.masks.dl_src, sizeof mask->eth.src); + mask->eth.type = match->wc.masks.dl_type; + + add_flow_pattern(patterns, RTE_FLOW_ITEM_TYPE_ETH, + &spec->eth, &mask->eth); + } else { + /* + * If user specifies a flow (like UDP flow) without L2 patterns, + * OVS will at least set the dl_type. Normally, it's enough to + * create an eth pattern just with it. Unluckily, some Intel's + * NIC (such as XL710) doesn't support that. Below is a workaround, + * which simply matches any L2 pkts. + */ + add_flow_pattern(patterns, RTE_FLOW_ITEM_TYPE_ETH, NULL, NULL); + } + + /* VLAN */ + if (match->wc.masks.vlans[0].tci && match->flow.vlans[0].tci) { + spec->vlan.tci = match->flow.vlans[0].tci & ~htons(VLAN_CFI); + mask->vlan.tci = match->wc.masks.vlans[0].tci & ~htons(VLAN_CFI); + + /* Match any protocols. */ + mask->vlan.inner_type = 0; + + add_flow_pattern(patterns, RTE_FLOW_ITEM_TYPE_VLAN, + &spec->vlan, &mask->vlan); + } + + /* IP v4 */ + if (match->flow.dl_type == htons(ETH_TYPE_IP)) { + spec->ipv4.hdr.type_of_service = match->flow.nw_tos; + spec->ipv4.hdr.time_to_live = match->flow.nw_ttl; + spec->ipv4.hdr.next_proto_id = match->flow.nw_proto; + spec->ipv4.hdr.src_addr = match->flow.nw_src; + spec->ipv4.hdr.dst_addr = match->flow.nw_dst; + + mask->ipv4.hdr.type_of_service = match->wc.masks.nw_tos; + mask->ipv4.hdr.time_to_live = match->wc.masks.nw_ttl; + mask->ipv4.hdr.next_proto_id = match->wc.masks.nw_proto; + mask->ipv4.hdr.src_addr = match->wc.masks.nw_src; + mask->ipv4.hdr.dst_addr = match->wc.masks.nw_dst; + + add_flow_pattern(patterns, RTE_FLOW_ITEM_TYPE_IPV4, + &spec->ipv4, &mask->ipv4); + + /* Save proto for L4 protocol setup. */ + proto = spec->ipv4.hdr.next_proto_id & + mask->ipv4.hdr.next_proto_id; + } + + if (proto != IPPROTO_ICMP && proto != IPPROTO_UDP && + proto != IPPROTO_SCTP && proto != IPPROTO_TCP && + (match->wc.masks.tp_src || + match->wc.masks.tp_dst || + match->wc.masks.tcp_flags)) { + VLOG_DBG("L4 Protocol (%u) not supported", proto); + return -1; + } + + if ((match->wc.masks.tp_src && match->wc.masks.tp_src != OVS_BE16_MAX) || + (match->wc.masks.tp_dst && match->wc.masks.tp_dst != OVS_BE16_MAX)) { + return -1; + } + + switch (proto) { + case IPPROTO_TCP: + spec->tcp.hdr.src_port = match->flow.tp_src; + spec->tcp.hdr.dst_port = match->flow.tp_dst; + spec->tcp.hdr.data_off = ntohs(match->flow.tcp_flags) >> 8; + spec->tcp.hdr.tcp_flags = ntohs(match->flow.tcp_flags) & 0xff; + + mask->tcp.hdr.src_port = match->wc.masks.tp_src; + mask->tcp.hdr.dst_port = match->wc.masks.tp_dst; + mask->tcp.hdr.data_off = ntohs(match->wc.masks.tcp_flags) >> 8; + mask->tcp.hdr.tcp_flags = ntohs(match->wc.masks.tcp_flags) & 0xff; + + add_flow_pattern(patterns, RTE_FLOW_ITEM_TYPE_TCP, + &spec->tcp, &mask->tcp); + + /* proto == TCP and ITEM_TYPE_TCP, thus no need for proto match. */ + mask->ipv4.hdr.next_proto_id = 0; + break; + + case IPPROTO_UDP: + spec->udp.hdr.src_port = match->flow.tp_src; + spec->udp.hdr.dst_port = match->flow.tp_dst; + + mask->udp.hdr.src_port = match->wc.masks.tp_src; + mask->udp.hdr.dst_port = match->wc.masks.tp_dst; + + add_flow_pattern(patterns, RTE_FLOW_ITEM_TYPE_UDP, + &spec->udp, &mask->udp); + + /* proto == UDP and ITEM_TYPE_UDP, thus no need for proto match. */ + mask->ipv4.hdr.next_proto_id = 0; + break; + + case IPPROTO_SCTP: + spec->sctp.hdr.src_port = match->flow.tp_src; + spec->sctp.hdr.dst_port = match->flow.tp_dst; + + mask->sctp.hdr.src_port = match->wc.masks.tp_src; + mask->sctp.hdr.dst_port = match->wc.masks.tp_dst; + + add_flow_pattern(patterns, RTE_FLOW_ITEM_TYPE_SCTP, + &spec->sctp, &mask->sctp); + + /* proto == SCTP and ITEM_TYPE_SCTP, thus no need for proto match. */ + mask->ipv4.hdr.next_proto_id = 0; + break; + + case IPPROTO_ICMP: + spec->icmp.hdr.icmp_type = (uint8_t) ntohs(match->flow.tp_src); + spec->icmp.hdr.icmp_code = (uint8_t) ntohs(match->flow.tp_dst); + + mask->icmp.hdr.icmp_type = (uint8_t) ntohs(match->wc.masks.tp_src); + mask->icmp.hdr.icmp_code = (uint8_t) ntohs(match->wc.masks.tp_dst); + + add_flow_pattern(patterns, RTE_FLOW_ITEM_TYPE_ICMP, + &spec->icmp, &mask->icmp); + + /* proto == ICMP and ITEM_TYPE_ICMP, thus no need for proto match. */ + mask->ipv4.hdr.next_proto_id = 0; + break; + } + + add_flow_pattern(patterns, RTE_FLOW_ITEM_TYPE_END, NULL, NULL); + return 0; +} + diff --git a/lib/netdev-offload-dpdk-private.h b/lib/netdev-offload-dpdk-private.h new file mode 100644 index 000000000..397384cb0 --- /dev/null +++ b/lib/netdev-offload-dpdk-private.h @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2019 Mellanox Technologies, Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef NETDEV_OFFLOAD_DPDK_PRIVATE_H +#define NETDEV_OFFLOAD_DPDK_PRIVATE_H + +#include "openvswitch/match.h" + +#include + +struct netdev; + +/* + * To avoid individual xrealloc calls for each new element, a 'curent_max' + * is used to keep track of current allocated number of elements. Starts + * by 8 and doubles on each xrealloc call. + */ +struct flow_patterns { + struct rte_flow_item *items; + int cnt; + int current_max; +}; + +struct flow_actions { + struct rte_flow_action *actions; + int cnt; + int current_max; +}; + +struct flow_pattern_items { + struct rte_flow_item_eth eth; + struct rte_flow_item_vlan vlan; + struct rte_flow_item_ipv4 ipv4; + union { + struct rte_flow_item_tcp tcp; + struct rte_flow_item_udp udp; + struct rte_flow_item_sctp sctp; + struct rte_flow_item_icmp icmp; + }; +}; + +void +netdev_dpdk_flow_patterns_free(struct flow_patterns *patterns); +int +netdev_dpdk_flow_patterns_add(struct flow_patterns *patterns, + struct flow_pattern_items *spec, + struct flow_pattern_items *mask, + const struct match *match); +void +netdev_dpdk_flow_actions_free(struct flow_actions *actions); +void +netdev_dpdk_flow_actions_add_mark_rss(struct flow_actions *actions, + struct netdev *netdev, + uint32_t mark_id); + +#endif /* NETDEV_OFFLOAD_DPDK_PRIVATE_H */ diff --git a/lib/netdev-offload-dpdk.c b/lib/netdev-offload-dpdk.c index 96794dc4d..d6bbb7166 100644 --- a/lib/netdev-offload-dpdk.c +++ b/lib/netdev-offload-dpdk.c @@ -26,6 +26,7 @@ #include "openvswitch/vlog.h" #include "packets.h" #include "uuid.h" +#include "netdev-offload-dpdk-private.h" VLOG_DEFINE_THIS_MODULE(netdev_offload_dpdk); @@ -114,302 +115,6 @@ ufid_to_rte_flow_disassociate(const ovs_u128 *ufid) UUID_ARGS((struct uuid *) ufid)); } -/* - * To avoid individual xrealloc calls for each new element, a 'curent_max' - * is used to keep track of current allocated number of elements. Starts - * by 8 and doubles on each xrealloc call. - */ -struct flow_patterns { - struct rte_flow_item *items; - int cnt; - int current_max; -}; - -struct flow_actions { - struct rte_flow_action *actions; - int cnt; - int current_max; -}; - -static void -dump_flow_pattern(struct rte_flow_item *item) -{ - struct ds s; - - if (!VLOG_IS_DBG_ENABLED() || item->type == RTE_FLOW_ITEM_TYPE_END) { - return; - } - - ds_init(&s); - - if (item->type == RTE_FLOW_ITEM_TYPE_ETH) { - const struct rte_flow_item_eth *eth_spec = item->spec; - const struct rte_flow_item_eth *eth_mask = item->mask; - - ds_put_cstr(&s, "rte flow eth pattern:\n"); - if (eth_spec) { - ds_put_format(&s, - " Spec: src="ETH_ADDR_FMT", dst="ETH_ADDR_FMT", " - "type=0x%04" PRIx16"\n", - ETH_ADDR_BYTES_ARGS(eth_spec->src.addr_bytes), - ETH_ADDR_BYTES_ARGS(eth_spec->dst.addr_bytes), - ntohs(eth_spec->type)); - } else { - ds_put_cstr(&s, " Spec = null\n"); - } - if (eth_mask) { - ds_put_format(&s, - " Mask: src="ETH_ADDR_FMT", dst="ETH_ADDR_FMT", " - "type=0x%04"PRIx16"\n", - ETH_ADDR_BYTES_ARGS(eth_mask->src.addr_bytes), - ETH_ADDR_BYTES_ARGS(eth_mask->dst.addr_bytes), - ntohs(eth_mask->type)); - } else { - ds_put_cstr(&s, " Mask = null\n"); - } - } - - if (item->type == RTE_FLOW_ITEM_TYPE_VLAN) { - const struct rte_flow_item_vlan *vlan_spec = item->spec; - const struct rte_flow_item_vlan *vlan_mask = item->mask; - - ds_put_cstr(&s, "rte flow vlan pattern:\n"); - if (vlan_spec) { - ds_put_format(&s, - " Spec: inner_type=0x%"PRIx16", tci=0x%"PRIx16"\n", - ntohs(vlan_spec->inner_type), ntohs(vlan_spec->tci)); - } else { - ds_put_cstr(&s, " Spec = null\n"); - } - - if (vlan_mask) { - ds_put_format(&s, - " Mask: inner_type=0x%"PRIx16", tci=0x%"PRIx16"\n", - ntohs(vlan_mask->inner_type), ntohs(vlan_mask->tci)); - } else { - ds_put_cstr(&s, " Mask = null\n"); - } - } - - if (item->type == RTE_FLOW_ITEM_TYPE_IPV4) { - const struct rte_flow_item_ipv4 *ipv4_spec = item->spec; - const struct rte_flow_item_ipv4 *ipv4_mask = item->mask; - - ds_put_cstr(&s, "rte flow ipv4 pattern:\n"); - if (ipv4_spec) { - ds_put_format(&s, - " Spec: tos=0x%"PRIx8", ttl=%"PRIx8 - ", proto=0x%"PRIx8 - ", src="IP_FMT", dst="IP_FMT"\n", - ipv4_spec->hdr.type_of_service, - ipv4_spec->hdr.time_to_live, - ipv4_spec->hdr.next_proto_id, - IP_ARGS(ipv4_spec->hdr.src_addr), - IP_ARGS(ipv4_spec->hdr.dst_addr)); - } else { - ds_put_cstr(&s, " Spec = null\n"); - } - if (ipv4_mask) { - ds_put_format(&s, - " Mask: tos=0x%"PRIx8", ttl=%"PRIx8 - ", proto=0x%"PRIx8 - ", src="IP_FMT", dst="IP_FMT"\n", - ipv4_mask->hdr.type_of_service, - ipv4_mask->hdr.time_to_live, - ipv4_mask->hdr.next_proto_id, - IP_ARGS(ipv4_mask->hdr.src_addr), - IP_ARGS(ipv4_mask->hdr.dst_addr)); - } else { - ds_put_cstr(&s, " Mask = null\n"); - } - } - - if (item->type == RTE_FLOW_ITEM_TYPE_UDP) { - const struct rte_flow_item_udp *udp_spec = item->spec; - const struct rte_flow_item_udp *udp_mask = item->mask; - - ds_put_cstr(&s, "rte flow udp pattern:\n"); - if (udp_spec) { - ds_put_format(&s, - " Spec: src_port=%"PRIu16", dst_port=%"PRIu16"\n", - ntohs(udp_spec->hdr.src_port), - ntohs(udp_spec->hdr.dst_port)); - } else { - ds_put_cstr(&s, " Spec = null\n"); - } - if (udp_mask) { - ds_put_format(&s, - " Mask: src_port=0x%"PRIx16 - ", dst_port=0x%"PRIx16"\n", - ntohs(udp_mask->hdr.src_port), - ntohs(udp_mask->hdr.dst_port)); - } else { - ds_put_cstr(&s, " Mask = null\n"); - } - } - - if (item->type == RTE_FLOW_ITEM_TYPE_SCTP) { - const struct rte_flow_item_sctp *sctp_spec = item->spec; - const struct rte_flow_item_sctp *sctp_mask = item->mask; - - ds_put_cstr(&s, "rte flow sctp pattern:\n"); - if (sctp_spec) { - ds_put_format(&s, - " Spec: src_port=%"PRIu16", dst_port=%"PRIu16"\n", - ntohs(sctp_spec->hdr.src_port), - ntohs(sctp_spec->hdr.dst_port)); - } else { - ds_put_cstr(&s, " Spec = null\n"); - } - if (sctp_mask) { - ds_put_format(&s, - " Mask: src_port=0x%"PRIx16 - ", dst_port=0x%"PRIx16"\n", - ntohs(sctp_mask->hdr.src_port), - ntohs(sctp_mask->hdr.dst_port)); - } else { - ds_put_cstr(&s, " Mask = null\n"); - } - } - - if (item->type == RTE_FLOW_ITEM_TYPE_ICMP) { - const struct rte_flow_item_icmp *icmp_spec = item->spec; - const struct rte_flow_item_icmp *icmp_mask = item->mask; - - ds_put_cstr(&s, "rte flow icmp pattern:\n"); - if (icmp_spec) { - ds_put_format(&s, - " Spec: icmp_type=%"PRIu8", icmp_code=%"PRIu8"\n", - icmp_spec->hdr.icmp_type, - icmp_spec->hdr.icmp_code); - } else { - ds_put_cstr(&s, " Spec = null\n"); - } - if (icmp_mask) { - ds_put_format(&s, - " Mask: icmp_type=0x%"PRIx8 - ", icmp_code=0x%"PRIx8"\n", - icmp_spec->hdr.icmp_type, - icmp_spec->hdr.icmp_code); - } else { - ds_put_cstr(&s, " Mask = null\n"); - } - } - - if (item->type == RTE_FLOW_ITEM_TYPE_TCP) { - const struct rte_flow_item_tcp *tcp_spec = item->spec; - const struct rte_flow_item_tcp *tcp_mask = item->mask; - - ds_put_cstr(&s, "rte flow tcp pattern:\n"); - if (tcp_spec) { - ds_put_format(&s, - " Spec: src_port=%"PRIu16", dst_port=%"PRIu16 - ", data_off=0x%"PRIx8", tcp_flags=0x%"PRIx8"\n", - ntohs(tcp_spec->hdr.src_port), - ntohs(tcp_spec->hdr.dst_port), - tcp_spec->hdr.data_off, - tcp_spec->hdr.tcp_flags); - } else { - ds_put_cstr(&s, " Spec = null\n"); - } - if (tcp_mask) { - ds_put_format(&s, - " Mask: src_port=%"PRIx16", dst_port=%"PRIx16 - ", data_off=0x%"PRIx8", tcp_flags=0x%"PRIx8"\n", - ntohs(tcp_mask->hdr.src_port), - ntohs(tcp_mask->hdr.dst_port), - tcp_mask->hdr.data_off, - tcp_mask->hdr.tcp_flags); - } else { - ds_put_cstr(&s, " Mask = null\n"); - } - } - - VLOG_DBG("%s", ds_cstr(&s)); - ds_destroy(&s); -} - -static void -add_flow_pattern(struct flow_patterns *patterns, enum rte_flow_item_type type, - const void *spec, const void *mask) -{ - int cnt = patterns->cnt; - - if (cnt == 0) { - patterns->current_max = 8; - patterns->items = xcalloc(patterns->current_max, - sizeof *patterns->items); - } else if (cnt == patterns->current_max) { - patterns->current_max *= 2; - patterns->items = xrealloc(patterns->items, patterns->current_max * - sizeof *patterns->items); - } - - patterns->items[cnt].type = type; - patterns->items[cnt].spec = spec; - patterns->items[cnt].mask = mask; - patterns->items[cnt].last = NULL; - dump_flow_pattern(&patterns->items[cnt]); - patterns->cnt++; -} - -static void -add_flow_action(struct flow_actions *actions, enum rte_flow_action_type type, - const void *conf) -{ - int cnt = actions->cnt; - - if (cnt == 0) { - actions->current_max = 8; - actions->actions = xcalloc(actions->current_max, - sizeof *actions->actions); - } else if (cnt == actions->current_max) { - actions->current_max *= 2; - actions->actions = xrealloc(actions->actions, actions->current_max * - sizeof *actions->actions); - } - - actions->actions[cnt].type = type; - actions->actions[cnt].conf = conf; - actions->cnt++; -} - -struct action_rss_data { - struct rte_flow_action_rss conf; - uint16_t queue[0]; -}; - -static struct action_rss_data * -add_flow_rss_action(struct flow_actions *actions, - struct netdev *netdev) -{ - int i; - struct action_rss_data *rss_data; - - rss_data = xmalloc(sizeof *rss_data + - netdev_n_rxq(netdev) * sizeof rss_data->queue[0]); - *rss_data = (struct action_rss_data) { - .conf = (struct rte_flow_action_rss) { - .func = RTE_ETH_HASH_FUNCTION_DEFAULT, - .level = 0, - .types = 0, - .queue_num = netdev_n_rxq(netdev), - .queue = rss_data->queue, - .key_len = 0, - .key = NULL - }, - }; - - /* Override queue array with default. */ - for (i = 0; i < netdev_n_rxq(netdev); i++) { - rss_data->queue[i] = i; - } - - add_flow_action(actions, RTE_FLOW_ACTION_TYPE_RSS, &rss_data->conf); - - return rss_data; -} - static int netdev_offload_dpdk_add_flow(struct netdev *netdev, const struct match *match, @@ -426,177 +131,28 @@ netdev_offload_dpdk_add_flow(struct netdev *netdev, }; struct flow_patterns patterns = { .items = NULL, .cnt = 0 }; struct flow_actions actions = { .actions = NULL, .cnt = 0 }; - struct rte_flow *flow; + struct flow_pattern_items spec, mask; struct rte_flow_error error; - uint8_t proto = 0; + struct rte_flow *flow; int ret = 0; - struct flow_items { - struct rte_flow_item_eth eth; - struct rte_flow_item_vlan vlan; - struct rte_flow_item_ipv4 ipv4; - union { - struct rte_flow_item_tcp tcp; - struct rte_flow_item_udp udp; - struct rte_flow_item_sctp sctp; - struct rte_flow_item_icmp icmp; - }; - } spec, mask; memset(&spec, 0, sizeof spec); memset(&mask, 0, sizeof mask); - /* Eth */ - if (!eth_addr_is_zero(match->wc.masks.dl_src) || - !eth_addr_is_zero(match->wc.masks.dl_dst)) { - memcpy(&spec.eth.dst, &match->flow.dl_dst, sizeof spec.eth.dst); - memcpy(&spec.eth.src, &match->flow.dl_src, sizeof spec.eth.src); - spec.eth.type = match->flow.dl_type; - - memcpy(&mask.eth.dst, &match->wc.masks.dl_dst, sizeof mask.eth.dst); - memcpy(&mask.eth.src, &match->wc.masks.dl_src, sizeof mask.eth.src); - mask.eth.type = match->wc.masks.dl_type; - - add_flow_pattern(&patterns, RTE_FLOW_ITEM_TYPE_ETH, - &spec.eth, &mask.eth); - } else { - /* - * If user specifies a flow (like UDP flow) without L2 patterns, - * OVS will at least set the dl_type. Normally, it's enough to - * create an eth pattern just with it. Unluckily, some Intel's - * NIC (such as XL710) doesn't support that. Below is a workaround, - * which simply matches any L2 pkts. - */ - add_flow_pattern(&patterns, RTE_FLOW_ITEM_TYPE_ETH, NULL, NULL); - } - - /* VLAN */ - if (match->wc.masks.vlans[0].tci && match->flow.vlans[0].tci) { - spec.vlan.tci = match->flow.vlans[0].tci & ~htons(VLAN_CFI); - mask.vlan.tci = match->wc.masks.vlans[0].tci & ~htons(VLAN_CFI); - - /* Match any protocols. */ - mask.vlan.inner_type = 0; - - add_flow_pattern(&patterns, RTE_FLOW_ITEM_TYPE_VLAN, - &spec.vlan, &mask.vlan); - } - - /* IP v4 */ - if (match->flow.dl_type == htons(ETH_TYPE_IP)) { - spec.ipv4.hdr.type_of_service = match->flow.nw_tos; - spec.ipv4.hdr.time_to_live = match->flow.nw_ttl; - spec.ipv4.hdr.next_proto_id = match->flow.nw_proto; - spec.ipv4.hdr.src_addr = match->flow.nw_src; - spec.ipv4.hdr.dst_addr = match->flow.nw_dst; - - mask.ipv4.hdr.type_of_service = match->wc.masks.nw_tos; - mask.ipv4.hdr.time_to_live = match->wc.masks.nw_ttl; - mask.ipv4.hdr.next_proto_id = match->wc.masks.nw_proto; - mask.ipv4.hdr.src_addr = match->wc.masks.nw_src; - mask.ipv4.hdr.dst_addr = match->wc.masks.nw_dst; - - add_flow_pattern(&patterns, RTE_FLOW_ITEM_TYPE_IPV4, - &spec.ipv4, &mask.ipv4); - - /* Save proto for L4 protocol setup. */ - proto = spec.ipv4.hdr.next_proto_id & - mask.ipv4.hdr.next_proto_id; - } - - if (proto != IPPROTO_ICMP && proto != IPPROTO_UDP && - proto != IPPROTO_SCTP && proto != IPPROTO_TCP && - (match->wc.masks.tp_src || - match->wc.masks.tp_dst || - match->wc.masks.tcp_flags)) { - VLOG_DBG("L4 Protocol (%u) not supported", proto); - ret = -1; + ret = netdev_dpdk_flow_patterns_add(&patterns, &spec, &mask, match); + if (ret) { + VLOG_WARN("Adding rte match patterns for flow ufid"UUID_FMT" failed", + UUID_ARGS((struct uuid *)ufid)); goto out; } - if ((match->wc.masks.tp_src && match->wc.masks.tp_src != OVS_BE16_MAX) || - (match->wc.masks.tp_dst && match->wc.masks.tp_dst != OVS_BE16_MAX)) { - ret = -1; - goto out; - } - - switch (proto) { - case IPPROTO_TCP: - spec.tcp.hdr.src_port = match->flow.tp_src; - spec.tcp.hdr.dst_port = match->flow.tp_dst; - spec.tcp.hdr.data_off = ntohs(match->flow.tcp_flags) >> 8; - spec.tcp.hdr.tcp_flags = ntohs(match->flow.tcp_flags) & 0xff; - - mask.tcp.hdr.src_port = match->wc.masks.tp_src; - mask.tcp.hdr.dst_port = match->wc.masks.tp_dst; - mask.tcp.hdr.data_off = ntohs(match->wc.masks.tcp_flags) >> 8; - mask.tcp.hdr.tcp_flags = ntohs(match->wc.masks.tcp_flags) & 0xff; - - add_flow_pattern(&patterns, RTE_FLOW_ITEM_TYPE_TCP, - &spec.tcp, &mask.tcp); - - /* proto == TCP and ITEM_TYPE_TCP, thus no need for proto match. */ - mask.ipv4.hdr.next_proto_id = 0; - break; - - case IPPROTO_UDP: - spec.udp.hdr.src_port = match->flow.tp_src; - spec.udp.hdr.dst_port = match->flow.tp_dst; - - mask.udp.hdr.src_port = match->wc.masks.tp_src; - mask.udp.hdr.dst_port = match->wc.masks.tp_dst; - - add_flow_pattern(&patterns, RTE_FLOW_ITEM_TYPE_UDP, - &spec.udp, &mask.udp); - - /* proto == UDP and ITEM_TYPE_UDP, thus no need for proto match. */ - mask.ipv4.hdr.next_proto_id = 0; - break; - - case IPPROTO_SCTP: - spec.sctp.hdr.src_port = match->flow.tp_src; - spec.sctp.hdr.dst_port = match->flow.tp_dst; - - mask.sctp.hdr.src_port = match->wc.masks.tp_src; - mask.sctp.hdr.dst_port = match->wc.masks.tp_dst; - - add_flow_pattern(&patterns, RTE_FLOW_ITEM_TYPE_SCTP, - &spec.sctp, &mask.sctp); - - /* proto == SCTP and ITEM_TYPE_SCTP, thus no need for proto match. */ - mask.ipv4.hdr.next_proto_id = 0; - break; - - case IPPROTO_ICMP: - spec.icmp.hdr.icmp_type = (uint8_t) ntohs(match->flow.tp_src); - spec.icmp.hdr.icmp_code = (uint8_t) ntohs(match->flow.tp_dst); - - mask.icmp.hdr.icmp_type = (uint8_t) ntohs(match->wc.masks.tp_src); - mask.icmp.hdr.icmp_code = (uint8_t) ntohs(match->wc.masks.tp_dst); - - add_flow_pattern(&patterns, RTE_FLOW_ITEM_TYPE_ICMP, - &spec.icmp, &mask.icmp); - - /* proto == ICMP and ITEM_TYPE_ICMP, thus no need for proto match. */ - mask.ipv4.hdr.next_proto_id = 0; - break; - } - - add_flow_pattern(&patterns, RTE_FLOW_ITEM_TYPE_END, NULL, NULL); - - struct rte_flow_action_mark mark; - struct action_rss_data *rss; - - mark.id = info->flow_mark; - add_flow_action(&actions, RTE_FLOW_ACTION_TYPE_MARK, &mark); - - rss = add_flow_rss_action(&actions, netdev); - add_flow_action(&actions, RTE_FLOW_ACTION_TYPE_END, NULL); + netdev_dpdk_flow_actions_add_mark_rss(&actions, netdev, + info->flow_mark); flow = netdev_dpdk_rte_flow_create(netdev, &flow_attr, patterns.items, actions.actions, &error); - free(rss); if (!flow) { VLOG_ERR("%s: rte flow creat error: %u : message : %s\n", netdev_get_name(netdev), error.type, error.message); @@ -608,8 +164,8 @@ netdev_offload_dpdk_add_flow(struct netdev *netdev, netdev_get_name(netdev), flow, UUID_ARGS((struct uuid *)ufid)); out: - free(patterns.items); - free(actions.actions); + netdev_dpdk_flow_patterns_free(&patterns); + netdev_dpdk_flow_actions_free(&actions); return ret; } From patchwork Wed Nov 20 15:28:09 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eli Britstein X-Patchwork-Id: 1198269 X-Patchwork-Delegate: i.maximets@samsung.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=openvswitch.org (client-ip=140.211.166.136; helo=silver.osuosl.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=mellanox.com Received: from silver.osuosl.org (smtp3.osuosl.org [140.211.166.136]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 47J6K05XFdz9sPZ for ; Thu, 21 Nov 2019 02:37:56 +1100 (AEDT) Received: from localhost (localhost [127.0.0.1]) by silver.osuosl.org (Postfix) with ESMTP id 0CE1A25E5A; Wed, 20 Nov 2019 15:37:55 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from silver.osuosl.org ([127.0.0.1]) by localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id v5whj8ji2FPO; Wed, 20 Nov 2019 15:37:43 +0000 (UTC) Received: from lists.linuxfoundation.org (lf-lists.osuosl.org [140.211.9.56]) by silver.osuosl.org (Postfix) with ESMTP id 27D7F24AF4; Wed, 20 Nov 2019 15:35:56 +0000 (UTC) Received: from lf-lists.osuosl.org (localhost [127.0.0.1]) by lists.linuxfoundation.org (Postfix) with ESMTP id D5B7FC1DEC; Wed, 20 Nov 2019 15:35:55 +0000 (UTC) X-Original-To: dev@openvswitch.org Delivered-To: ovs-dev@lists.linuxfoundation.org Received: from hemlock.osuosl.org (smtp2.osuosl.org [140.211.166.133]) by lists.linuxfoundation.org (Postfix) with ESMTP id 3A6D0C1DDC for ; Wed, 20 Nov 2019 15:35:37 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by hemlock.osuosl.org (Postfix) with ESMTP id 1A71C885C4 for ; Wed, 20 Nov 2019 15:35:37 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from hemlock.osuosl.org ([127.0.0.1]) by localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id KdE1bW1ovaeA for ; Wed, 20 Nov 2019 15:35:35 +0000 (UTC) X-Greylist: from auto-whitelisted by SQLgrey-1.7.6 Received: from mellanox.co.il (mail-il-dmz.mellanox.com [193.47.165.129]) by hemlock.osuosl.org (Postfix) with ESMTP id 1CCD1885C7 for ; Wed, 20 Nov 2019 15:35:33 +0000 (UTC) Received: from Internal Mail-Server by MTLPINE1 (envelope-from elibr@mellanox.com) with ESMTPS (AES256-SHA encrypted); 20 Nov 2019 17:28:48 +0200 Received: from dev-r-vrt-215.mtr.labs.mlnx. (dev-r-vrt-215.mtr.labs.mlnx [10.212.215.1]) by labmailer.mlnx (8.13.8/8.13.8) with ESMTP id xAKFSlW9001566; Wed, 20 Nov 2019 17:28:47 +0200 From: Eli Britstein To: dev@openvswitch.org, Ilya Maximets , Ian Stokes Date: Wed, 20 Nov 2019 15:28:09 +0000 Message-Id: <20191120152826.25074-4-elibr@mellanox.com> X-Mailer: git-send-email 2.14.5 In-Reply-To: <20191120152826.25074-1-elibr@mellanox.com> References: <20191120152826.25074-1-elibr@mellanox.com> Cc: Oz Shlomo , Majd Dibbiny , Eli Britstein , Ameer Mahagneh Subject: [ovs-dev] [PATCH 03/20] netdev-offload-dpdk-flow: Dynamically allocate pattern items X-BeenThere: ovs-dev@openvswitch.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: ovs-dev-bounces@openvswitch.org Sender: "dev" Instead of statically allocated pattern items on the stack,dynamically allocate only the required items while parsing the required matches. Signed-off-by: Eli Britstein Reviewed-by: Oz Shlomo --- lib/netdev-offload-dpdk-flow.c | 163 +++++++++++++++++++++----------------- lib/netdev-offload-dpdk-private.h | 14 ---- lib/netdev-offload-dpdk.c | 6 +- 3 files changed, 90 insertions(+), 93 deletions(-) diff --git a/lib/netdev-offload-dpdk-flow.c b/lib/netdev-offload-dpdk-flow.c index d1d5ce2c6..c8c3e28ea 100644 --- a/lib/netdev-offload-dpdk-flow.c +++ b/lib/netdev-offload-dpdk-flow.c @@ -29,6 +29,16 @@ void netdev_dpdk_flow_patterns_free(struct flow_patterns *patterns) { /* When calling this function 'patterns' must be valid */ + int i; + + for (i = 0; i < patterns->cnt; i++) { + if (patterns->items[i].spec) { + free((void *)patterns->items[i].spec); + } + if (patterns->items[i].mask) { + free((void *)patterns->items[i].mask); + } + } free(patterns->items); patterns->items = NULL; patterns->cnt = 0; @@ -333,8 +343,6 @@ netdev_dpdk_flow_actions_add_mark_rss(struct flow_actions *actions, int netdev_dpdk_flow_patterns_add(struct flow_patterns *patterns, - struct flow_pattern_items *spec, - struct flow_pattern_items *mask, const struct match *match) { uint8_t proto = 0; @@ -342,16 +350,20 @@ netdev_dpdk_flow_patterns_add(struct flow_patterns *patterns, /* Eth */ if (!eth_addr_is_zero(match->wc.masks.dl_src) || !eth_addr_is_zero(match->wc.masks.dl_dst)) { - memcpy(&spec->eth.dst, &match->flow.dl_dst, sizeof spec->eth.dst); - memcpy(&spec->eth.src, &match->flow.dl_src, sizeof spec->eth.src); - spec->eth.type = match->flow.dl_type; + struct rte_flow_item_eth *spec, *mask; + + spec = xzalloc(sizeof *spec); + mask = xzalloc(sizeof *mask); - memcpy(&mask->eth.dst, &match->wc.masks.dl_dst, sizeof mask->eth.dst); - memcpy(&mask->eth.src, &match->wc.masks.dl_src, sizeof mask->eth.src); - mask->eth.type = match->wc.masks.dl_type; + memcpy(&spec->dst, &match->flow.dl_dst, sizeof spec->dst); + memcpy(&spec->src, &match->flow.dl_src, sizeof spec->src); + spec->type = match->flow.dl_type; - add_flow_pattern(patterns, RTE_FLOW_ITEM_TYPE_ETH, - &spec->eth, &mask->eth); + memcpy(&mask->dst, &match->wc.masks.dl_dst, sizeof mask->dst); + memcpy(&mask->src, &match->wc.masks.dl_src, sizeof mask->src); + mask->type = match->wc.masks.dl_type; + + add_flow_pattern(patterns, RTE_FLOW_ITEM_TYPE_ETH, spec, mask); } else { /* * If user specifies a flow (like UDP flow) without L2 patterns, @@ -365,36 +377,43 @@ netdev_dpdk_flow_patterns_add(struct flow_patterns *patterns, /* VLAN */ if (match->wc.masks.vlans[0].tci && match->flow.vlans[0].tci) { - spec->vlan.tci = match->flow.vlans[0].tci & ~htons(VLAN_CFI); - mask->vlan.tci = match->wc.masks.vlans[0].tci & ~htons(VLAN_CFI); + struct rte_flow_item_vlan *spec, *mask; + + spec = xzalloc(sizeof *spec); + mask = xzalloc(sizeof *mask); + + spec->tci = match->flow.vlans[0].tci & ~htons(VLAN_CFI); + mask->tci = match->wc.masks.vlans[0].tci & ~htons(VLAN_CFI); /* Match any protocols. */ - mask->vlan.inner_type = 0; + mask->inner_type = 0; - add_flow_pattern(patterns, RTE_FLOW_ITEM_TYPE_VLAN, - &spec->vlan, &mask->vlan); + add_flow_pattern(patterns, RTE_FLOW_ITEM_TYPE_VLAN, spec, mask); } /* IP v4 */ if (match->flow.dl_type == htons(ETH_TYPE_IP)) { - spec->ipv4.hdr.type_of_service = match->flow.nw_tos; - spec->ipv4.hdr.time_to_live = match->flow.nw_ttl; - spec->ipv4.hdr.next_proto_id = match->flow.nw_proto; - spec->ipv4.hdr.src_addr = match->flow.nw_src; - spec->ipv4.hdr.dst_addr = match->flow.nw_dst; + struct rte_flow_item_ipv4 *spec, *mask; - mask->ipv4.hdr.type_of_service = match->wc.masks.nw_tos; - mask->ipv4.hdr.time_to_live = match->wc.masks.nw_ttl; - mask->ipv4.hdr.next_proto_id = match->wc.masks.nw_proto; - mask->ipv4.hdr.src_addr = match->wc.masks.nw_src; - mask->ipv4.hdr.dst_addr = match->wc.masks.nw_dst; + spec = xzalloc(sizeof *spec); + mask = xzalloc(sizeof *mask); - add_flow_pattern(patterns, RTE_FLOW_ITEM_TYPE_IPV4, - &spec->ipv4, &mask->ipv4); + spec->hdr.type_of_service = match->flow.nw_tos; + spec->hdr.time_to_live = match->flow.nw_ttl; + spec->hdr.next_proto_id = match->flow.nw_proto; + spec->hdr.src_addr = match->flow.nw_src; + spec->hdr.dst_addr = match->flow.nw_dst; + + mask->hdr.type_of_service = match->wc.masks.nw_tos; + mask->hdr.time_to_live = match->wc.masks.nw_ttl; + mask->hdr.next_proto_id = match->wc.masks.nw_proto; + mask->hdr.src_addr = match->wc.masks.nw_src; + mask->hdr.dst_addr = match->wc.masks.nw_dst; + + add_flow_pattern(patterns, RTE_FLOW_ITEM_TYPE_IPV4, spec, mask); /* Save proto for L4 protocol setup. */ - proto = spec->ipv4.hdr.next_proto_id & - mask->ipv4.hdr.next_proto_id; + proto = spec->hdr.next_proto_id & mask->hdr.next_proto_id; } if (proto != IPPROTO_ICMP && proto != IPPROTO_UDP && @@ -411,66 +430,62 @@ netdev_dpdk_flow_patterns_add(struct flow_patterns *patterns, return -1; } - switch (proto) { - case IPPROTO_TCP: - spec->tcp.hdr.src_port = match->flow.tp_src; - spec->tcp.hdr.dst_port = match->flow.tp_dst; - spec->tcp.hdr.data_off = ntohs(match->flow.tcp_flags) >> 8; - spec->tcp.hdr.tcp_flags = ntohs(match->flow.tcp_flags) & 0xff; + if (proto == IPPROTO_TCP) { + struct rte_flow_item_tcp *spec, *mask; + + spec = xzalloc(sizeof *spec); + mask = xzalloc(sizeof *mask); - mask->tcp.hdr.src_port = match->wc.masks.tp_src; - mask->tcp.hdr.dst_port = match->wc.masks.tp_dst; - mask->tcp.hdr.data_off = ntohs(match->wc.masks.tcp_flags) >> 8; - mask->tcp.hdr.tcp_flags = ntohs(match->wc.masks.tcp_flags) & 0xff; + spec->hdr.src_port = match->flow.tp_src; + spec->hdr.dst_port = match->flow.tp_dst; + spec->hdr.data_off = ntohs(match->flow.tcp_flags) >> 8; + spec->hdr.tcp_flags = ntohs(match->flow.tcp_flags) & 0xff; - add_flow_pattern(patterns, RTE_FLOW_ITEM_TYPE_TCP, - &spec->tcp, &mask->tcp); + mask->hdr.src_port = match->wc.masks.tp_src; + mask->hdr.dst_port = match->wc.masks.tp_dst; + mask->hdr.data_off = ntohs(match->wc.masks.tcp_flags) >> 8; + mask->hdr.tcp_flags = ntohs(match->wc.masks.tcp_flags) & 0xff; - /* proto == TCP and ITEM_TYPE_TCP, thus no need for proto match. */ - mask->ipv4.hdr.next_proto_id = 0; - break; + add_flow_pattern(patterns, RTE_FLOW_ITEM_TYPE_TCP, spec, mask); + } else if (proto == IPPROTO_UDP) { + struct rte_flow_item_udp *spec, *mask; - case IPPROTO_UDP: - spec->udp.hdr.src_port = match->flow.tp_src; - spec->udp.hdr.dst_port = match->flow.tp_dst; + spec = xzalloc(sizeof *spec); + mask = xzalloc(sizeof *mask); - mask->udp.hdr.src_port = match->wc.masks.tp_src; - mask->udp.hdr.dst_port = match->wc.masks.tp_dst; + spec->hdr.src_port = match->flow.tp_src; + spec->hdr.dst_port = match->flow.tp_dst; - add_flow_pattern(patterns, RTE_FLOW_ITEM_TYPE_UDP, - &spec->udp, &mask->udp); + mask->hdr.src_port = match->wc.masks.tp_src; + mask->hdr.dst_port = match->wc.masks.tp_dst; - /* proto == UDP and ITEM_TYPE_UDP, thus no need for proto match. */ - mask->ipv4.hdr.next_proto_id = 0; - break; + add_flow_pattern(patterns, RTE_FLOW_ITEM_TYPE_UDP, spec, mask); + } else if (proto == IPPROTO_SCTP) { + struct rte_flow_item_sctp *spec, *mask; - case IPPROTO_SCTP: - spec->sctp.hdr.src_port = match->flow.tp_src; - spec->sctp.hdr.dst_port = match->flow.tp_dst; + spec = xzalloc(sizeof *spec); + mask = xzalloc(sizeof *mask); - mask->sctp.hdr.src_port = match->wc.masks.tp_src; - mask->sctp.hdr.dst_port = match->wc.masks.tp_dst; + spec->hdr.src_port = match->flow.tp_src; + spec->hdr.dst_port = match->flow.tp_dst; - add_flow_pattern(patterns, RTE_FLOW_ITEM_TYPE_SCTP, - &spec->sctp, &mask->sctp); + mask->hdr.src_port = match->wc.masks.tp_src; + mask->hdr.dst_port = match->wc.masks.tp_dst; - /* proto == SCTP and ITEM_TYPE_SCTP, thus no need for proto match. */ - mask->ipv4.hdr.next_proto_id = 0; - break; + add_flow_pattern(patterns, RTE_FLOW_ITEM_TYPE_SCTP, spec, mask); + } else if (proto == IPPROTO_ICMP) { + struct rte_flow_item_icmp *spec, *mask; - case IPPROTO_ICMP: - spec->icmp.hdr.icmp_type = (uint8_t) ntohs(match->flow.tp_src); - spec->icmp.hdr.icmp_code = (uint8_t) ntohs(match->flow.tp_dst); + spec = xzalloc(sizeof *spec); + mask = xzalloc(sizeof *mask); - mask->icmp.hdr.icmp_type = (uint8_t) ntohs(match->wc.masks.tp_src); - mask->icmp.hdr.icmp_code = (uint8_t) ntohs(match->wc.masks.tp_dst); + spec->hdr.icmp_type = (uint8_t) ntohs(match->flow.tp_src); + spec->hdr.icmp_code = (uint8_t) ntohs(match->flow.tp_dst); - add_flow_pattern(patterns, RTE_FLOW_ITEM_TYPE_ICMP, - &spec->icmp, &mask->icmp); + mask->hdr.icmp_type = (uint8_t) ntohs(match->wc.masks.tp_src); + mask->hdr.icmp_code = (uint8_t) ntohs(match->wc.masks.tp_dst); - /* proto == ICMP and ITEM_TYPE_ICMP, thus no need for proto match. */ - mask->ipv4.hdr.next_proto_id = 0; - break; + add_flow_pattern(patterns, RTE_FLOW_ITEM_TYPE_ICMP, spec, mask); } add_flow_pattern(patterns, RTE_FLOW_ITEM_TYPE_END, NULL, NULL); diff --git a/lib/netdev-offload-dpdk-private.h b/lib/netdev-offload-dpdk-private.h index 397384cb0..e9c9e602a 100644 --- a/lib/netdev-offload-dpdk-private.h +++ b/lib/netdev-offload-dpdk-private.h @@ -40,24 +40,10 @@ struct flow_actions { int current_max; }; -struct flow_pattern_items { - struct rte_flow_item_eth eth; - struct rte_flow_item_vlan vlan; - struct rte_flow_item_ipv4 ipv4; - union { - struct rte_flow_item_tcp tcp; - struct rte_flow_item_udp udp; - struct rte_flow_item_sctp sctp; - struct rte_flow_item_icmp icmp; - }; -}; - void netdev_dpdk_flow_patterns_free(struct flow_patterns *patterns); int netdev_dpdk_flow_patterns_add(struct flow_patterns *patterns, - struct flow_pattern_items *spec, - struct flow_pattern_items *mask, const struct match *match); void netdev_dpdk_flow_actions_free(struct flow_actions *actions); diff --git a/lib/netdev-offload-dpdk.c b/lib/netdev-offload-dpdk.c index d6bbb7166..9882e1d23 100644 --- a/lib/netdev-offload-dpdk.c +++ b/lib/netdev-offload-dpdk.c @@ -131,15 +131,11 @@ netdev_offload_dpdk_add_flow(struct netdev *netdev, }; struct flow_patterns patterns = { .items = NULL, .cnt = 0 }; struct flow_actions actions = { .actions = NULL, .cnt = 0 }; - struct flow_pattern_items spec, mask; struct rte_flow_error error; struct rte_flow *flow; int ret = 0; - memset(&spec, 0, sizeof spec); - memset(&mask, 0, sizeof mask); - - ret = netdev_dpdk_flow_patterns_add(&patterns, &spec, &mask, match); + ret = netdev_dpdk_flow_patterns_add(&patterns, match); if (ret) { VLOG_WARN("Adding rte match patterns for flow ufid"UUID_FMT" failed", UUID_ARGS((struct uuid *)ufid)); From patchwork Wed Nov 20 15:28:10 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eli Britstein X-Patchwork-Id: 1198247 X-Patchwork-Delegate: i.maximets@samsung.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=openvswitch.org (client-ip=140.211.166.137; helo=fraxinus.osuosl.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=mellanox.com Received: from fraxinus.osuosl.org (smtp4.osuosl.org [140.211.166.137]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 47J6GR6CF4z9sR4 for ; Thu, 21 Nov 2019 02:35:43 +1100 (AEDT) Received: from localhost (localhost [127.0.0.1]) by fraxinus.osuosl.org (Postfix) with ESMTP id 4D16D86C8D; Wed, 20 Nov 2019 15:35:40 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from fraxinus.osuosl.org ([127.0.0.1]) by localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id 91PEU7DyWi4l; Wed, 20 Nov 2019 15:35:38 +0000 (UTC) Received: from lists.linuxfoundation.org (lf-lists.osuosl.org [140.211.9.56]) by fraxinus.osuosl.org (Postfix) with ESMTP id 2FCE486D16; Wed, 20 Nov 2019 15:35:38 +0000 (UTC) Received: from lf-lists.osuosl.org (localhost [127.0.0.1]) by lists.linuxfoundation.org (Postfix) with ESMTP id 0AFDBC1DDC; Wed, 20 Nov 2019 15:35:38 +0000 (UTC) X-Original-To: dev@openvswitch.org Delivered-To: ovs-dev@lists.linuxfoundation.org Received: from fraxinus.osuosl.org (smtp4.osuosl.org [140.211.166.137]) by lists.linuxfoundation.org (Postfix) with ESMTP id 6AA2AC1DDB for ; Wed, 20 Nov 2019 15:35:35 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by fraxinus.osuosl.org (Postfix) with ESMTP id 5562086C6D for ; Wed, 20 Nov 2019 15:35:35 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from fraxinus.osuosl.org ([127.0.0.1]) by localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id ZRyVJOIY1LW0 for ; Wed, 20 Nov 2019 15:35:34 +0000 (UTC) X-Greylist: from auto-whitelisted by SQLgrey-1.7.6 Received: from mellanox.co.il (mail-il-dmz.mellanox.com [193.47.165.129]) by fraxinus.osuosl.org (Postfix) with ESMTP id 1C6EF86C6C for ; Wed, 20 Nov 2019 15:35:33 +0000 (UTC) Received: from Internal Mail-Server by MTLPINE1 (envelope-from elibr@mellanox.com) with ESMTPS (AES256-SHA encrypted); 20 Nov 2019 17:28:48 +0200 Received: from dev-r-vrt-215.mtr.labs.mlnx. (dev-r-vrt-215.mtr.labs.mlnx [10.212.215.1]) by labmailer.mlnx (8.13.8/8.13.8) with ESMTP id xAKFSlWA001566; Wed, 20 Nov 2019 17:28:48 +0200 From: Eli Britstein To: dev@openvswitch.org, Ilya Maximets , Ian Stokes Date: Wed, 20 Nov 2019 15:28:10 +0000 Message-Id: <20191120152826.25074-5-elibr@mellanox.com> X-Mailer: git-send-email 2.14.5 In-Reply-To: <20191120152826.25074-1-elibr@mellanox.com> References: <20191120152826.25074-1-elibr@mellanox.com> Cc: Oz Shlomo , Majd Dibbiny , Eli Britstein , Ameer Mahagneh Subject: [ovs-dev] [PATCH 04/20] netdev-offload-dpdk: Fix typo X-BeenThere: ovs-dev@openvswitch.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: ovs-dev-bounces@openvswitch.org Sender: "dev" Fixes: e8a2b5bf92bb ("netdev-dpdk: implement flow offload with rte flow") Signed-off-by: Eli Britstein Reviewed-by: Oz Shlomo --- lib/netdev-offload-dpdk.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/netdev-offload-dpdk.c b/lib/netdev-offload-dpdk.c index 9882e1d23..6e1ca8a0d 100644 --- a/lib/netdev-offload-dpdk.c +++ b/lib/netdev-offload-dpdk.c @@ -150,7 +150,7 @@ netdev_offload_dpdk_add_flow(struct netdev *netdev, actions.actions, &error); if (!flow) { - VLOG_ERR("%s: rte flow creat error: %u : message : %s\n", + VLOG_ERR("%s: rte flow create error: %u : message : %s\n", netdev_get_name(netdev), error.type, error.message); ret = -1; goto out; From patchwork Wed Nov 20 15:28:11 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eli Britstein X-Patchwork-Id: 1198263 X-Patchwork-Delegate: i.maximets@samsung.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=openvswitch.org (client-ip=140.211.166.136; helo=silver.osuosl.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=mellanox.com Received: from silver.osuosl.org (smtp3.osuosl.org [140.211.166.136]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 47J6Hp6Mg3z9sPZ for ; Thu, 21 Nov 2019 02:36:54 +1100 (AEDT) Received: from localhost (localhost [127.0.0.1]) by silver.osuosl.org (Postfix) with ESMTP id 46D2A258FF; Wed, 20 Nov 2019 15:36:53 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from silver.osuosl.org ([127.0.0.1]) by localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id 7i9BZ62wkhzW; Wed, 20 Nov 2019 15:36:44 +0000 (UTC) Received: from lists.linuxfoundation.org (lf-lists.osuosl.org [140.211.9.56]) by silver.osuosl.org (Postfix) with ESMTP id 2225525A0C; Wed, 20 Nov 2019 15:35:50 +0000 (UTC) Received: from lf-lists.osuosl.org (localhost [127.0.0.1]) by lists.linuxfoundation.org (Postfix) with ESMTP id E5EE4C1DED; Wed, 20 Nov 2019 15:35:49 +0000 (UTC) X-Original-To: dev@openvswitch.org Delivered-To: ovs-dev@lists.linuxfoundation.org Received: from silver.osuosl.org (smtp3.osuosl.org [140.211.166.136]) by lists.linuxfoundation.org (Postfix) with ESMTP id 58515C1DDB for ; Wed, 20 Nov 2019 15:35:36 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by silver.osuosl.org (Postfix) with ESMTP id 54C7020017 for ; Wed, 20 Nov 2019 15:35:36 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from silver.osuosl.org ([127.0.0.1]) by localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id UVwRibI85YPd for ; Wed, 20 Nov 2019 15:35:34 +0000 (UTC) X-Greylist: from auto-whitelisted by SQLgrey-1.7.6 Received: from mellanox.co.il (mail-il-dmz.mellanox.com [193.47.165.129]) by silver.osuosl.org (Postfix) with ESMTP id 1859D2045D for ; Wed, 20 Nov 2019 15:35:33 +0000 (UTC) Received: from Internal Mail-Server by MTLPINE1 (envelope-from elibr@mellanox.com) with ESMTPS (AES256-SHA encrypted); 20 Nov 2019 17:28:48 +0200 Received: from dev-r-vrt-215.mtr.labs.mlnx. (dev-r-vrt-215.mtr.labs.mlnx [10.212.215.1]) by labmailer.mlnx (8.13.8/8.13.8) with ESMTP id xAKFSlWB001566; Wed, 20 Nov 2019 17:28:48 +0200 From: Eli Britstein To: dev@openvswitch.org, Ilya Maximets , Ian Stokes Date: Wed, 20 Nov 2019 15:28:11 +0000 Message-Id: <20191120152826.25074-6-elibr@mellanox.com> X-Mailer: git-send-email 2.14.5 In-Reply-To: <20191120152826.25074-1-elibr@mellanox.com> References: <20191120152826.25074-1-elibr@mellanox.com> Cc: Oz Shlomo , Majd Dibbiny , Eli Britstein , Ameer Mahagneh Subject: [ovs-dev] [PATCH 05/20] netdev-dpdk: Improve HW offload flow debuggability X-BeenThere: ovs-dev@openvswitch.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: ovs-dev-bounces@openvswitch.org Sender: "dev" Add debug prints when creating and destroying rte flows. Signed-off-by: Eli Britstein Reviewed-by: Oz Shlomo --- lib/netdev-dpdk.c | 29 +++++++ lib/netdev-offload-dpdk-flow.c | 168 +++++++++++++++++++++++--------------- lib/netdev-offload-dpdk-private.h | 5 ++ 3 files changed, 136 insertions(+), 66 deletions(-) diff --git a/lib/netdev-dpdk.c b/lib/netdev-dpdk.c index 02120a379..673cbfbd6 100644 --- a/lib/netdev-dpdk.c +++ b/lib/netdev-dpdk.c @@ -67,6 +67,7 @@ #include "unixctl.h" #include "util.h" #include "uuid.h" +#include "netdev-offload-dpdk-private.h" enum {VIRTIO_RXQ, VIRTIO_TXQ, VIRTIO_QNUM}; @@ -4452,6 +4453,15 @@ netdev_dpdk_rte_flow_destroy(struct netdev *netdev, ovs_mutex_lock(&dev->mutex); ret = rte_flow_destroy(dev->port_id, rte_flow, error); + if (!ret) { + VLOG_DBG("Destroy rte_flow %p: netdev=%s, port=%d\n", + rte_flow, netdev_get_name(netdev), dev->port_id); + } else { + VLOG_ERR("Destroy rte_flow %p: netdev=%s, port=%d\n" + "FAILED. error %u : message : %s", + rte_flow, netdev_get_name(netdev), dev->port_id, + error->type, error->message); + } ovs_mutex_unlock(&dev->mutex); return ret; } @@ -4465,9 +4475,28 @@ netdev_dpdk_rte_flow_create(struct netdev *netdev, { struct rte_flow *flow; struct netdev_dpdk *dev = netdev_dpdk_cast(netdev); + struct ds s; ovs_mutex_lock(&dev->mutex); flow = rte_flow_create(dev->port_id, attr, items, actions, error); + ds_init(&s); + if (flow) { + VLOG_DBG("Create rte_flow: netdev=%s, port=%d\n" + "%s" + "Flow handle=%p\n", + netdev_get_name(netdev), dev->port_id, + ds_cstr(netdev_dpdk_flow_ds_put_flow(&s, attr, items, + actions)), flow); + } else { + VLOG_ERR("Create rte_flow: netdev=%s, port=%d\n" + "%s" + "FAILED. error %u : message : %s\n", + netdev_get_name(netdev), dev->port_id, + ds_cstr(netdev_dpdk_flow_ds_put_flow(&s, attr, items, + actions)), + error->type, error->message); + } + ds_destroy(&s); ovs_mutex_unlock(&dev->mutex); return flow; } diff --git a/lib/netdev-offload-dpdk-flow.c b/lib/netdev-offload-dpdk-flow.c index c8c3e28ea..19c933932 100644 --- a/lib/netdev-offload-dpdk-flow.c +++ b/lib/netdev-offload-dpdk-flow.c @@ -61,73 +61,71 @@ netdev_dpdk_flow_actions_free(struct flow_actions *actions) } static void -dump_flow_pattern(struct rte_flow_item *item) +ds_put_flow_attr(struct ds *s, const struct rte_flow_attr *attr) { - struct ds s; - - if (!VLOG_IS_DBG_ENABLED() || item->type == RTE_FLOW_ITEM_TYPE_END) { - return; - } - - ds_init(&s); + ds_put_format(s, + " Attributes: " + "ingress=%d, egress=%d, prio=%d, group=%d, transfer=%d\n", + attr->ingress, attr->egress, attr->priority, attr->group, + attr->transfer); +} +static void +ds_put_flow_pattern(struct ds *s, const struct rte_flow_item *item) +{ if (item->type == RTE_FLOW_ITEM_TYPE_ETH) { const struct rte_flow_item_eth *eth_spec = item->spec; const struct rte_flow_item_eth *eth_mask = item->mask; - ds_put_cstr(&s, "rte flow eth pattern:\n"); + ds_put_cstr(s, "rte flow eth pattern:\n"); if (eth_spec) { - ds_put_format(&s, + ds_put_format(s, " Spec: src="ETH_ADDR_FMT", dst="ETH_ADDR_FMT", " "type=0x%04" PRIx16"\n", ETH_ADDR_BYTES_ARGS(eth_spec->src.addr_bytes), ETH_ADDR_BYTES_ARGS(eth_spec->dst.addr_bytes), ntohs(eth_spec->type)); } else { - ds_put_cstr(&s, " Spec = null\n"); + ds_put_cstr(s, " Spec = null\n"); } if (eth_mask) { - ds_put_format(&s, + ds_put_format(s, " Mask: src="ETH_ADDR_FMT", dst="ETH_ADDR_FMT", " "type=0x%04"PRIx16"\n", ETH_ADDR_BYTES_ARGS(eth_mask->src.addr_bytes), ETH_ADDR_BYTES_ARGS(eth_mask->dst.addr_bytes), ntohs(eth_mask->type)); } else { - ds_put_cstr(&s, " Mask = null\n"); + ds_put_cstr(s, " Mask = null\n"); } - } - - if (item->type == RTE_FLOW_ITEM_TYPE_VLAN) { + } else if (item->type == RTE_FLOW_ITEM_TYPE_VLAN) { const struct rte_flow_item_vlan *vlan_spec = item->spec; const struct rte_flow_item_vlan *vlan_mask = item->mask; - ds_put_cstr(&s, "rte flow vlan pattern:\n"); + ds_put_cstr(s, "rte flow vlan pattern:\n"); if (vlan_spec) { - ds_put_format(&s, + ds_put_format(s, " Spec: inner_type=0x%"PRIx16", tci=0x%"PRIx16"\n", ntohs(vlan_spec->inner_type), ntohs(vlan_spec->tci)); } else { - ds_put_cstr(&s, " Spec = null\n"); + ds_put_cstr(s, " Spec = null\n"); } if (vlan_mask) { - ds_put_format(&s, + ds_put_format(s, " Mask: inner_type=0x%"PRIx16", tci=0x%"PRIx16"\n", ntohs(vlan_mask->inner_type), ntohs(vlan_mask->tci)); } else { - ds_put_cstr(&s, " Mask = null\n"); + ds_put_cstr(s, " Mask = null\n"); } - } - - if (item->type == RTE_FLOW_ITEM_TYPE_IPV4) { + } else if (item->type == RTE_FLOW_ITEM_TYPE_IPV4) { const struct rte_flow_item_ipv4 *ipv4_spec = item->spec; const struct rte_flow_item_ipv4 *ipv4_mask = item->mask; - ds_put_cstr(&s, "rte flow ipv4 pattern:\n"); + ds_put_cstr(s, "rte flow ipv4 pattern:\n"); if (ipv4_spec) { - ds_put_format(&s, - " Spec: tos=0x%"PRIx8", ttl=%"PRIx8 + ds_put_format(s, + " Spec: tos=0x%"PRIx8", ttl=%"PRIu8 ", proto=0x%"PRIx8 ", src="IP_FMT", dst="IP_FMT"\n", ipv4_spec->hdr.type_of_service, @@ -136,11 +134,11 @@ dump_flow_pattern(struct rte_flow_item *item) IP_ARGS(ipv4_spec->hdr.src_addr), IP_ARGS(ipv4_spec->hdr.dst_addr)); } else { - ds_put_cstr(&s, " Spec = null\n"); + ds_put_cstr(s, " Spec = null\n"); } if (ipv4_mask) { - ds_put_format(&s, - " Mask: tos=0x%"PRIx8", ttl=%"PRIx8 + ds_put_format(s, + " Mask: tos=0x%"PRIx8", ttl=%"PRIu8 ", proto=0x%"PRIx8 ", src="IP_FMT", dst="IP_FMT"\n", ipv4_mask->hdr.type_of_service, @@ -149,89 +147,81 @@ dump_flow_pattern(struct rte_flow_item *item) IP_ARGS(ipv4_mask->hdr.src_addr), IP_ARGS(ipv4_mask->hdr.dst_addr)); } else { - ds_put_cstr(&s, " Mask = null\n"); + ds_put_cstr(s, " Mask = null\n"); } - } - - if (item->type == RTE_FLOW_ITEM_TYPE_UDP) { + } else if (item->type == RTE_FLOW_ITEM_TYPE_UDP) { const struct rte_flow_item_udp *udp_spec = item->spec; const struct rte_flow_item_udp *udp_mask = item->mask; - ds_put_cstr(&s, "rte flow udp pattern:\n"); + ds_put_cstr(s, "rte flow udp pattern:\n"); if (udp_spec) { - ds_put_format(&s, + ds_put_format(s, " Spec: src_port=%"PRIu16", dst_port=%"PRIu16"\n", ntohs(udp_spec->hdr.src_port), ntohs(udp_spec->hdr.dst_port)); } else { - ds_put_cstr(&s, " Spec = null\n"); + ds_put_cstr(s, " Spec = null\n"); } if (udp_mask) { - ds_put_format(&s, + ds_put_format(s, " Mask: src_port=0x%"PRIx16 ", dst_port=0x%"PRIx16"\n", ntohs(udp_mask->hdr.src_port), ntohs(udp_mask->hdr.dst_port)); } else { - ds_put_cstr(&s, " Mask = null\n"); + ds_put_cstr(s, " Mask = null\n"); } - } - - if (item->type == RTE_FLOW_ITEM_TYPE_SCTP) { + } else if (item->type == RTE_FLOW_ITEM_TYPE_SCTP) { const struct rte_flow_item_sctp *sctp_spec = item->spec; const struct rte_flow_item_sctp *sctp_mask = item->mask; - ds_put_cstr(&s, "rte flow sctp pattern:\n"); + ds_put_cstr(s, "rte flow sctp pattern:\n"); if (sctp_spec) { - ds_put_format(&s, + ds_put_format(s, " Spec: src_port=%"PRIu16", dst_port=%"PRIu16"\n", ntohs(sctp_spec->hdr.src_port), ntohs(sctp_spec->hdr.dst_port)); } else { - ds_put_cstr(&s, " Spec = null\n"); + ds_put_cstr(s, " Spec = null\n"); } if (sctp_mask) { - ds_put_format(&s, + ds_put_format(s, " Mask: src_port=0x%"PRIx16 ", dst_port=0x%"PRIx16"\n", ntohs(sctp_mask->hdr.src_port), ntohs(sctp_mask->hdr.dst_port)); } else { - ds_put_cstr(&s, " Mask = null\n"); + ds_put_cstr(s, " Mask = null\n"); } - } - - if (item->type == RTE_FLOW_ITEM_TYPE_ICMP) { + } else if (item->type == RTE_FLOW_ITEM_TYPE_ICMP) { const struct rte_flow_item_icmp *icmp_spec = item->spec; const struct rte_flow_item_icmp *icmp_mask = item->mask; - ds_put_cstr(&s, "rte flow icmp pattern:\n"); + ds_put_cstr(s, "rte flow icmp pattern:\n"); if (icmp_spec) { - ds_put_format(&s, + ds_put_format(s, " Spec: icmp_type=%"PRIu8", icmp_code=%"PRIu8"\n", icmp_spec->hdr.icmp_type, icmp_spec->hdr.icmp_code); } else { - ds_put_cstr(&s, " Spec = null\n"); + ds_put_cstr(s, " Spec = null\n"); } if (icmp_mask) { - ds_put_format(&s, + ds_put_format(s, " Mask: icmp_type=0x%"PRIx8 ", icmp_code=0x%"PRIx8"\n", icmp_spec->hdr.icmp_type, icmp_spec->hdr.icmp_code); } else { - ds_put_cstr(&s, " Mask = null\n"); + ds_put_cstr(s, " Mask = null\n"); } - } - - if (item->type == RTE_FLOW_ITEM_TYPE_TCP) { + } else if (item->type == RTE_FLOW_ITEM_TYPE_TCP) { const struct rte_flow_item_tcp *tcp_spec = item->spec; const struct rte_flow_item_tcp *tcp_mask = item->mask; - ds_put_cstr(&s, "rte flow tcp pattern:\n"); + ds_put_cstr(s, "rte flow tcp pattern:\n"); if (tcp_spec) { - ds_put_format(&s, + ds_put_format(s, " Spec: src_port=%"PRIu16", dst_port=%"PRIu16 ", data_off=0x%"PRIx8", tcp_flags=0x%"PRIx8"\n", ntohs(tcp_spec->hdr.src_port), @@ -239,10 +229,10 @@ dump_flow_pattern(struct rte_flow_item *item) tcp_spec->hdr.data_off, tcp_spec->hdr.tcp_flags); } else { - ds_put_cstr(&s, " Spec = null\n"); + ds_put_cstr(s, " Spec = null\n"); } if (tcp_mask) { - ds_put_format(&s, + ds_put_format(s, " Mask: src_port=%"PRIx16", dst_port=%"PRIx16 ", data_off=0x%"PRIx8", tcp_flags=0x%"PRIx8"\n", ntohs(tcp_mask->hdr.src_port), @@ -250,12 +240,59 @@ dump_flow_pattern(struct rte_flow_item *item) tcp_mask->hdr.data_off, tcp_mask->hdr.tcp_flags); } else { - ds_put_cstr(&s, " Mask = null\n"); + ds_put_cstr(s, " Mask = null\n"); } + } else { + ds_put_format(s, "unknown rte flow pattern (%d)\n", item->type); + } +} + +static void +ds_put_flow_action(struct ds *s, const struct rte_flow_action *actions) +{ + if (actions->type == RTE_FLOW_ACTION_TYPE_MARK) { + const struct rte_flow_action_mark *mark = actions->conf; + + ds_put_cstr(s, "rte flow mark action:\n"); + if (mark) { + ds_put_format(s, + " Mark: id=%d\n", + mark->id); + } else { + ds_put_cstr(s, " Mark = null\n"); + } + } else if (actions->type == RTE_FLOW_ACTION_TYPE_RSS) { + const struct rte_flow_action_rss *rss = actions->conf; + + ds_put_cstr(s, "rte flow RSS action:\n"); + if (rss) { + ds_put_format(s, + " RSS: queue_num=%d\n", rss->queue_num); + } else { + ds_put_cstr(s, " RSS = null\n"); + } + } else { + ds_put_format(s, "unknown rte flow action (%d)\n", actions->type); + } +} + +struct ds * +netdev_dpdk_flow_ds_put_flow(struct ds *s, + const struct rte_flow_attr *attr, + const struct rte_flow_item *items, + const struct rte_flow_action *actions) +{ + if (attr) { + ds_put_flow_attr(s, attr); + } + while (items && items->type != RTE_FLOW_ITEM_TYPE_END) { + ds_put_flow_pattern(s, items++); + } + while (actions && actions->type != RTE_FLOW_ACTION_TYPE_END) { + ds_put_flow_action(s, actions++); } - VLOG_DBG("%s", ds_cstr(&s)); - ds_destroy(&s); + return s; } static void @@ -278,7 +315,6 @@ add_flow_pattern(struct flow_patterns *patterns, enum rte_flow_item_type type, patterns->items[cnt].spec = spec; patterns->items[cnt].mask = mask; patterns->items[cnt].last = NULL; - dump_flow_pattern(&patterns->items[cnt]); patterns->cnt++; } diff --git a/lib/netdev-offload-dpdk-private.h b/lib/netdev-offload-dpdk-private.h index e9c9e602a..68caa7144 100644 --- a/lib/netdev-offload-dpdk-private.h +++ b/lib/netdev-offload-dpdk-private.h @@ -51,5 +51,10 @@ void netdev_dpdk_flow_actions_add_mark_rss(struct flow_actions *actions, struct netdev *netdev, uint32_t mark_id); +struct ds * +netdev_dpdk_flow_ds_put_flow(struct ds *s, + const struct rte_flow_attr *attr, + const struct rte_flow_item *items, + const struct rte_flow_action *actions); #endif /* NETDEV_OFFLOAD_DPDK_PRIVATE_H */ From patchwork Wed Nov 20 15:28:12 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eli Britstein X-Patchwork-Id: 1198252 X-Patchwork-Delegate: i.maximets@samsung.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=openvswitch.org (client-ip=140.211.166.137; helo=fraxinus.osuosl.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=mellanox.com Received: from fraxinus.osuosl.org (smtp4.osuosl.org [140.211.166.137]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 47J6Gf1TQ7z9sR4 for ; Thu, 21 Nov 2019 02:35:54 +1100 (AEDT) Received: from localhost (localhost [127.0.0.1]) by fraxinus.osuosl.org (Postfix) with ESMTP id 779D886DD1; Wed, 20 Nov 2019 15:35:52 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from fraxinus.osuosl.org ([127.0.0.1]) by localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id zRNUTSLxjJza; Wed, 20 Nov 2019 15:35:50 +0000 (UTC) Received: from lists.linuxfoundation.org (lf-lists.osuosl.org [140.211.9.56]) by fraxinus.osuosl.org (Postfix) with ESMTP id C106686D8C; Wed, 20 Nov 2019 15:35:47 +0000 (UTC) Received: from lf-lists.osuosl.org (localhost [127.0.0.1]) by lists.linuxfoundation.org (Postfix) with ESMTP id 9EBCEC1DE7; Wed, 20 Nov 2019 15:35:47 +0000 (UTC) X-Original-To: dev@openvswitch.org Delivered-To: ovs-dev@lists.linuxfoundation.org Received: from hemlock.osuosl.org (smtp2.osuosl.org [140.211.166.133]) by lists.linuxfoundation.org (Postfix) with ESMTP id 32BCCC18DA for ; Wed, 20 Nov 2019 15:35:36 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by hemlock.osuosl.org (Postfix) with ESMTP id 0A809885B9 for ; Wed, 20 Nov 2019 15:35:36 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from hemlock.osuosl.org ([127.0.0.1]) by localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id GubNFmiCr9Uc for ; Wed, 20 Nov 2019 15:35:34 +0000 (UTC) X-Greylist: from auto-whitelisted by SQLgrey-1.7.6 Received: from mellanox.co.il (mail-il-dmz.mellanox.com [193.47.165.129]) by hemlock.osuosl.org (Postfix) with ESMTP id 1A01186F3F for ; Wed, 20 Nov 2019 15:35:33 +0000 (UTC) Received: from Internal Mail-Server by MTLPINE1 (envelope-from elibr@mellanox.com) with ESMTPS (AES256-SHA encrypted); 20 Nov 2019 17:28:48 +0200 Received: from dev-r-vrt-215.mtr.labs.mlnx. (dev-r-vrt-215.mtr.labs.mlnx [10.212.215.1]) by labmailer.mlnx (8.13.8/8.13.8) with ESMTP id xAKFSlWC001566; Wed, 20 Nov 2019 17:28:48 +0200 From: Eli Britstein To: dev@openvswitch.org, Ilya Maximets , Ian Stokes Date: Wed, 20 Nov 2019 15:28:12 +0000 Message-Id: <20191120152826.25074-7-elibr@mellanox.com> X-Mailer: git-send-email 2.14.5 In-Reply-To: <20191120152826.25074-1-elibr@mellanox.com> References: <20191120152826.25074-1-elibr@mellanox.com> Cc: Oz Shlomo , Majd Dibbiny , Eli Britstein , Ameer Mahagneh Subject: [ovs-dev] [PATCH 06/20] netdev-dpdk: Introduce flow_flush method X-BeenThere: ovs-dev@openvswitch.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: ovs-dev-bounces@openvswitch.org Sender: "dev" Introduce this method to orderly flush the rules when upper layers request it. Signed-off-by: Eli Britstein Reviewed-by: Oz Shlomo --- lib/netdev-dpdk.c | 13 +++++++++++++ lib/netdev-dpdk.h | 3 +++ 2 files changed, 16 insertions(+) diff --git a/lib/netdev-dpdk.c b/lib/netdev-dpdk.c index 673cbfbd6..327fa7698 100644 --- a/lib/netdev-dpdk.c +++ b/lib/netdev-dpdk.c @@ -4501,6 +4501,19 @@ netdev_dpdk_rte_flow_create(struct netdev *netdev, return flow; } +int +netdev_dpdk_rte_flow_flush(struct netdev *netdev, + struct rte_flow_error *error) +{ + struct netdev_dpdk *dev = netdev_dpdk_cast(netdev); + int ret; + + ovs_mutex_lock(&dev->mutex); + ret = rte_flow_flush(dev->port_id, error); + ovs_mutex_unlock(&dev->mutex); + return ret; +} + #define NETDEV_DPDK_CLASS_COMMON \ .is_pmd = true, \ .alloc = netdev_dpdk_alloc, \ diff --git a/lib/netdev-dpdk.h b/lib/netdev-dpdk.h index 60631c4f0..960aec7a8 100644 --- a/lib/netdev-dpdk.h +++ b/lib/netdev-dpdk.h @@ -47,6 +47,9 @@ netdev_dpdk_rte_flow_create(struct netdev *netdev, const struct rte_flow_item *items, const struct rte_flow_action *actions, struct rte_flow_error *error); +int +netdev_dpdk_rte_flow_flush(struct netdev *netdev, + struct rte_flow_error *error); #else From patchwork Wed Nov 20 15:28:13 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eli Britstein X-Patchwork-Id: 1198258 X-Patchwork-Delegate: i.maximets@samsung.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=openvswitch.org (client-ip=140.211.166.136; helo=silver.osuosl.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=mellanox.com Received: from silver.osuosl.org (smtp3.osuosl.org [140.211.166.136]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 47J6Gx5QCVz9sPZ for ; Thu, 21 Nov 2019 02:36:09 +1100 (AEDT) Received: from localhost (localhost [127.0.0.1]) by silver.osuosl.org (Postfix) with ESMTP id 2522426387; Wed, 20 Nov 2019 15:36:08 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from silver.osuosl.org ([127.0.0.1]) by localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id CNOZkHCT6-vi; Wed, 20 Nov 2019 15:36:04 +0000 (UTC) Received: from lists.linuxfoundation.org (lf-lists.osuosl.org [140.211.9.56]) by silver.osuosl.org (Postfix) with ESMTP id 74B7E24CC1; Wed, 20 Nov 2019 15:35:42 +0000 (UTC) Received: from lf-lists.osuosl.org (localhost [127.0.0.1]) by lists.linuxfoundation.org (Postfix) with ESMTP id 2EA39C18DA; Wed, 20 Nov 2019 15:35:42 +0000 (UTC) X-Original-To: dev@openvswitch.org Delivered-To: ovs-dev@lists.linuxfoundation.org Received: from fraxinus.osuosl.org (smtp4.osuosl.org [140.211.166.137]) by lists.linuxfoundation.org (Postfix) with ESMTP id BDA77C18DA for ; Wed, 20 Nov 2019 15:35:35 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by fraxinus.osuosl.org (Postfix) with ESMTP id A317186C3E for ; Wed, 20 Nov 2019 15:35:35 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from fraxinus.osuosl.org ([127.0.0.1]) by localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id xb_YGL6mjt6I for ; Wed, 20 Nov 2019 15:35:34 +0000 (UTC) X-Greylist: from auto-whitelisted by SQLgrey-1.7.6 Received: from mellanox.co.il (mail-il-dmz.mellanox.com [193.47.165.129]) by fraxinus.osuosl.org (Postfix) with ESMTP id 129D886C37 for ; Wed, 20 Nov 2019 15:35:33 +0000 (UTC) Received: from Internal Mail-Server by MTLPINE1 (envelope-from elibr@mellanox.com) with ESMTPS (AES256-SHA encrypted); 20 Nov 2019 17:28:48 +0200 Received: from dev-r-vrt-215.mtr.labs.mlnx. (dev-r-vrt-215.mtr.labs.mlnx [10.212.215.1]) by labmailer.mlnx (8.13.8/8.13.8) with ESMTP id xAKFSlWD001566; Wed, 20 Nov 2019 17:28:48 +0200 From: Eli Britstein To: dev@openvswitch.org, Ilya Maximets , Ian Stokes Date: Wed, 20 Nov 2019 15:28:13 +0000 Message-Id: <20191120152826.25074-8-elibr@mellanox.com> X-Mailer: git-send-email 2.14.5 In-Reply-To: <20191120152826.25074-1-elibr@mellanox.com> References: <20191120152826.25074-1-elibr@mellanox.com> Cc: Oz Shlomo , Majd Dibbiny , Eli Britstein , Ameer Mahagneh Subject: [ovs-dev] [PATCH 07/20] netdev-offload-dpdk: Introduce flow flush callback X-BeenThere: ovs-dev@openvswitch.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: ovs-dev-bounces@openvswitch.org Sender: "dev" Introduce flow flush callback for dpdk offloaded flows. Signed-off-by: Eli Britstein Reviewed-by: Oz Shlomo --- lib/netdev-offload-dpdk.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/lib/netdev-offload-dpdk.c b/lib/netdev-offload-dpdk.c index 6e1ca8a0d..64873759d 100644 --- a/lib/netdev-offload-dpdk.c +++ b/lib/netdev-offload-dpdk.c @@ -307,6 +307,21 @@ netdev_offload_dpdk_flow_del(struct netdev *netdev, const ovs_u128 *ufid, return netdev_offload_dpdk_destroy_flow(netdev, ufid, rte_flow); } +static int +netdev_offload_dpdk_flow_flush(struct netdev *netdev) +{ + struct rte_flow_error error; + int ret; + + ret = netdev_dpdk_rte_flow_flush(netdev, &error); + if (ret) { + VLOG_ERR("%s: rte flow flush error: %u : message : %s\n", + netdev_get_name(netdev), error.type, error.message); + } + + return ret; +} + static int netdev_offload_dpdk_init_flow_api(struct netdev *netdev) { @@ -315,6 +330,7 @@ netdev_offload_dpdk_init_flow_api(struct netdev *netdev) const struct netdev_flow_api netdev_offload_dpdk = { .type = "dpdk_flow_api", + .flow_flush = netdev_offload_dpdk_flow_flush, .flow_put = netdev_offload_dpdk_flow_put, .flow_del = netdev_offload_dpdk_flow_del, .init_flow_api = netdev_offload_dpdk_init_flow_api, From patchwork Wed Nov 20 15:28:14 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eli Britstein X-Patchwork-Id: 1198257 X-Patchwork-Delegate: i.maximets@samsung.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=openvswitch.org (client-ip=140.211.166.137; helo=fraxinus.osuosl.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=mellanox.com Received: from fraxinus.osuosl.org (smtp4.osuosl.org [140.211.166.137]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 47J6Gv1NGxz9sPc for ; Thu, 21 Nov 2019 02:36:07 +1100 (AEDT) Received: from localhost (localhost [127.0.0.1]) by fraxinus.osuosl.org (Postfix) with ESMTP id A969F86DA3; Wed, 20 Nov 2019 15:36:05 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from fraxinus.osuosl.org ([127.0.0.1]) by localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id vBVfIBE4uzuO; Wed, 20 Nov 2019 15:36:03 +0000 (UTC) Received: from lists.linuxfoundation.org (lf-lists.osuosl.org [140.211.9.56]) by fraxinus.osuosl.org (Postfix) with ESMTP id 3E14286E3C; Wed, 20 Nov 2019 15:35:57 +0000 (UTC) Received: from lf-lists.osuosl.org (localhost [127.0.0.1]) by lists.linuxfoundation.org (Postfix) with ESMTP id 21A3BC1DE8; Wed, 20 Nov 2019 15:35:57 +0000 (UTC) X-Original-To: dev@openvswitch.org Delivered-To: ovs-dev@lists.linuxfoundation.org Received: from silver.osuosl.org (smtp3.osuosl.org [140.211.166.136]) by lists.linuxfoundation.org (Postfix) with ESMTP id 58460C1DDB for ; Wed, 20 Nov 2019 15:35:37 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by silver.osuosl.org (Postfix) with ESMTP id 53BF020017 for ; Wed, 20 Nov 2019 15:35:37 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from silver.osuosl.org ([127.0.0.1]) by localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id SW586BYb1tCy for ; Wed, 20 Nov 2019 15:35:34 +0000 (UTC) X-Greylist: from auto-whitelisted by SQLgrey-1.7.6 Received: from mellanox.co.il (mail-il-dmz.mellanox.com [193.47.165.129]) by silver.osuosl.org (Postfix) with ESMTP id 1289F2001A for ; Wed, 20 Nov 2019 15:35:33 +0000 (UTC) Received: from Internal Mail-Server by MTLPINE1 (envelope-from elibr@mellanox.com) with ESMTPS (AES256-SHA encrypted); 20 Nov 2019 17:28:48 +0200 Received: from dev-r-vrt-215.mtr.labs.mlnx. (dev-r-vrt-215.mtr.labs.mlnx [10.212.215.1]) by labmailer.mlnx (8.13.8/8.13.8) with ESMTP id xAKFSlWE001566; Wed, 20 Nov 2019 17:28:48 +0200 From: Eli Britstein To: dev@openvswitch.org, Ilya Maximets , Ian Stokes Date: Wed, 20 Nov 2019 15:28:14 +0000 Message-Id: <20191120152826.25074-9-elibr@mellanox.com> X-Mailer: git-send-email 2.14.5 In-Reply-To: <20191120152826.25074-1-elibr@mellanox.com> References: <20191120152826.25074-1-elibr@mellanox.com> Cc: Oz Shlomo , Majd Dibbiny , Eli Britstein , Ameer Mahagneh Subject: [ovs-dev] [PATCH 08/20] netdev-offload-dpdk: Framework for actions offload X-BeenThere: ovs-dev@openvswitch.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: ovs-dev-bounces@openvswitch.org Sender: "dev" Currently HW offload is only accelerating the rule matching sequence. Introduce a framework for offloading rule actions as a pre-step for processing the rule actions in HW. Note: a flow will be fully offloaded only if it can process all its actions in HW. Signed-off-by: Eli Britstein Reviewed-by: Oz Shlomo --- lib/netdev-offload-dpdk-flow.c | 22 ++++++++++++++++++++++ lib/netdev-offload-dpdk-private.h | 5 +++++ lib/netdev-offload-dpdk.c | 24 ++++++++++++++++++------ lib/netdev-offload.h | 1 + 4 files changed, 46 insertions(+), 6 deletions(-) diff --git a/lib/netdev-offload-dpdk-flow.c b/lib/netdev-offload-dpdk-flow.c index 19c933932..dbbc45e99 100644 --- a/lib/netdev-offload-dpdk-flow.c +++ b/lib/netdev-offload-dpdk-flow.c @@ -18,6 +18,7 @@ #include #include "dpif-netdev.h" +#include "netdev-offload-provider.h" #include "netdev-offload-dpdk-private.h" #include "openvswitch/match.h" #include "openvswitch/vlog.h" @@ -25,6 +26,8 @@ VLOG_DEFINE_THIS_MODULE(netdev_offload_dpdk_flow); +static struct vlog_rate_limit error_rl = VLOG_RATE_LIMIT_INIT(100, 5); + void netdev_dpdk_flow_patterns_free(struct flow_patterns *patterns) { @@ -528,3 +531,22 @@ netdev_dpdk_flow_patterns_add(struct flow_patterns *patterns, return 0; } +int +netdev_dpdk_flow_actions_add(struct flow_actions *actions, + struct nlattr *nl_actions, + size_t nl_actions_len, + struct offload_info *info OVS_UNUSED) +{ + struct nlattr *nla; + size_t left; + + NL_ATTR_FOR_EACH_UNSAFE (nla, left, nl_actions, nl_actions_len) { + VLOG_DBG_RL(&error_rl, + "Unsupported action type %d", nl_attr_type(nla)); + return -1; + } + + add_flow_action(actions, RTE_FLOW_ACTION_TYPE_END, NULL); + return 0; +} + diff --git a/lib/netdev-offload-dpdk-private.h b/lib/netdev-offload-dpdk-private.h index 68caa7144..b69b76dff 100644 --- a/lib/netdev-offload-dpdk-private.h +++ b/lib/netdev-offload-dpdk-private.h @@ -51,6 +51,11 @@ void netdev_dpdk_flow_actions_add_mark_rss(struct flow_actions *actions, struct netdev *netdev, uint32_t mark_id); +int +netdev_dpdk_flow_actions_add(struct flow_actions *actions, + struct nlattr *nl_actions, + size_t nl_actions_len, + struct offload_info *info); struct ds * netdev_dpdk_flow_ds_put_flow(struct ds *s, const struct rte_flow_attr *attr, diff --git a/lib/netdev-offload-dpdk.c b/lib/netdev-offload-dpdk.c index 64873759d..9a166970f 100644 --- a/lib/netdev-offload-dpdk.c +++ b/lib/netdev-offload-dpdk.c @@ -118,16 +118,17 @@ ufid_to_rte_flow_disassociate(const ovs_u128 *ufid) static int netdev_offload_dpdk_add_flow(struct netdev *netdev, const struct match *match, - struct nlattr *nl_actions OVS_UNUSED, - size_t actions_len OVS_UNUSED, + struct nlattr *nl_actions, + size_t actions_len, const ovs_u128 *ufid, struct offload_info *info) { - const struct rte_flow_attr flow_attr = { + struct rte_flow_attr flow_attr = { .group = 0, .priority = 0, .ingress = 1, - .egress = 0 + .egress = 0, + .transfer = 1 }; struct flow_patterns patterns = { .items = NULL, .cnt = 0 }; struct flow_actions actions = { .actions = NULL, .cnt = 0 }; @@ -142,14 +143,25 @@ netdev_offload_dpdk_add_flow(struct netdev *netdev, goto out; } - netdev_dpdk_flow_actions_add_mark_rss(&actions, netdev, - info->flow_mark); + info->actions_offloaded = !netdev_dpdk_flow_actions_add(&actions, + nl_actions, + actions_len, info); + if (!info->actions_offloaded) { + /* if we failed to offload the rule actions fallback to mark rss + * actions. + */ + netdev_dpdk_flow_actions_free(&actions); + netdev_dpdk_flow_actions_add_mark_rss(&actions, netdev, + info->flow_mark); + flow_attr.transfer = 0; + } flow = netdev_dpdk_rte_flow_create(netdev, &flow_attr, patterns.items, actions.actions, &error); if (!flow) { + info->actions_offloaded = 0; VLOG_ERR("%s: rte flow create error: %u : message : %s\n", netdev_get_name(netdev), error.type, error.message); ret = -1; diff --git a/lib/netdev-offload.h b/lib/netdev-offload.h index 97a500647..e27b8782e 100644 --- a/lib/netdev-offload.h +++ b/lib/netdev-offload.h @@ -71,6 +71,7 @@ struct offload_info { * it will be in the pkt meta data. */ uint32_t flow_mark; + bool actions_offloaded; /* true if flow is fully actions_offloaded */ }; int netdev_flow_flush(struct netdev *); From patchwork Wed Nov 20 15:28:15 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eli Britstein X-Patchwork-Id: 1198259 X-Patchwork-Delegate: i.maximets@samsung.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=openvswitch.org (client-ip=140.211.166.136; helo=silver.osuosl.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=mellanox.com Received: from silver.osuosl.org (smtp3.osuosl.org [140.211.166.136]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 47J6H56RcCz9sPc for ; Thu, 21 Nov 2019 02:36:17 +1100 (AEDT) Received: from localhost (localhost [127.0.0.1]) by silver.osuosl.org (Postfix) with ESMTP id 0F9DD241A8; Wed, 20 Nov 2019 15:36:16 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from silver.osuosl.org ([127.0.0.1]) by localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id DxKuewL7OIgY; Wed, 20 Nov 2019 15:36:10 +0000 (UTC) Received: from lists.linuxfoundation.org (lf-lists.osuosl.org [140.211.9.56]) by silver.osuosl.org (Postfix) with ESMTP id 1D69A24F92; Wed, 20 Nov 2019 15:35:44 +0000 (UTC) Received: from lf-lists.osuosl.org (localhost [127.0.0.1]) by lists.linuxfoundation.org (Postfix) with ESMTP id D3C47C1DDC; Wed, 20 Nov 2019 15:35:43 +0000 (UTC) X-Original-To: dev@openvswitch.org Delivered-To: ovs-dev@lists.linuxfoundation.org Received: from hemlock.osuosl.org (smtp2.osuosl.org [140.211.166.133]) by lists.linuxfoundation.org (Postfix) with ESMTP id E73E4C1DDB for ; Wed, 20 Nov 2019 15:35:35 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by hemlock.osuosl.org (Postfix) with ESMTP id D8BFE885D7 for ; Wed, 20 Nov 2019 15:35:35 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from hemlock.osuosl.org ([127.0.0.1]) by localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id vF6nQLzb641a for ; Wed, 20 Nov 2019 15:35:34 +0000 (UTC) X-Greylist: from auto-whitelisted by SQLgrey-1.7.6 Received: from mellanox.co.il (mail-il-dmz.mellanox.com [193.47.165.129]) by hemlock.osuosl.org (Postfix) with ESMTP id 1C954885B9 for ; Wed, 20 Nov 2019 15:35:33 +0000 (UTC) Received: from Internal Mail-Server by MTLPINE1 (envelope-from elibr@mellanox.com) with ESMTPS (AES256-SHA encrypted); 20 Nov 2019 17:28:48 +0200 Received: from dev-r-vrt-215.mtr.labs.mlnx. (dev-r-vrt-215.mtr.labs.mlnx [10.212.215.1]) by labmailer.mlnx (8.13.8/8.13.8) with ESMTP id xAKFSlWF001566; Wed, 20 Nov 2019 17:28:48 +0200 From: Eli Britstein To: dev@openvswitch.org, Ilya Maximets , Ian Stokes Date: Wed, 20 Nov 2019 15:28:15 +0000 Message-Id: <20191120152826.25074-10-elibr@mellanox.com> X-Mailer: git-send-email 2.14.5 In-Reply-To: <20191120152826.25074-1-elibr@mellanox.com> References: <20191120152826.25074-1-elibr@mellanox.com> Cc: Oz Shlomo , Majd Dibbiny , Eli Britstein , Ameer Mahagneh Subject: [ovs-dev] [PATCH 09/20] netdev: Add netdev function: flow_stats_get() X-BeenThere: ovs-dev@openvswitch.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: ovs-dev-bounces@openvswitch.org Sender: "dev" From: Ophir Munk Add flow_stats_get() function to netdev offload class, as a pre-step towards implementation of statistics quering fully offloaded flows. Signed-off-by: Ophir Munk Reviewed-by: Oz Shlomo Signed-off-by: Eli Britstein --- lib/netdev-offload-provider.h | 7 +++++++ lib/netdev-offload.c | 12 ++++++++++++ lib/netdev-offload.h | 2 ++ 3 files changed, 21 insertions(+) diff --git a/lib/netdev-offload-provider.h b/lib/netdev-offload-provider.h index 4e1c4251d..9d275e07a 100644 --- a/lib/netdev-offload-provider.h +++ b/lib/netdev-offload-provider.h @@ -82,6 +82,13 @@ struct netdev_flow_api { int (*flow_del)(struct netdev *, const ovs_u128 *ufid, struct dpif_flow_stats *); + /* Get offloaded flow stats. + * Populate the 'stats' structure with the HW counters values for the + * specified ufid. + * Return 0 if successful, otherwise returns a positive errno value. */ + int (*flow_stats_get)(struct netdev *netdev, const ovs_u128 *ufid, + struct dpif_flow_stats *stats); + /* Initializies the netdev flow api. * Return 0 if successful, otherwise returns a positive errno value. */ int (*init_flow_api)(struct netdev *); diff --git a/lib/netdev-offload.c b/lib/netdev-offload.c index ae01acda6..9726bb19a 100644 --- a/lib/netdev-offload.c +++ b/lib/netdev-offload.c @@ -267,6 +267,18 @@ netdev_flow_del(struct netdev *netdev, const ovs_u128 *ufid, : EOPNOTSUPP; } +int +netdev_flow_stats_get(struct netdev *netdev, const ovs_u128 *ufid, + struct dpif_flow_stats *stats) +{ + const struct netdev_flow_api *flow_api = + ovsrcu_get(const struct netdev_flow_api *, &netdev->flow_api); + + return (flow_api && flow_api->flow_stats_get + ? flow_api->flow_stats_get(netdev, ufid, stats) + : EOPNOTSUPP); +} + int netdev_init_flow_api(struct netdev *netdev) { diff --git a/lib/netdev-offload.h b/lib/netdev-offload.h index e27b8782e..78909a416 100644 --- a/lib/netdev-offload.h +++ b/lib/netdev-offload.h @@ -89,6 +89,8 @@ int netdev_flow_get(struct netdev *, struct match *, struct nlattr **actions, struct dpif_flow_attrs *, struct ofpbuf *wbuffer); int netdev_flow_del(struct netdev *, const ovs_u128 *, struct dpif_flow_stats *); +int netdev_flow_stats_get(struct netdev *, const ovs_u128 *, + struct dpif_flow_stats *); int netdev_init_flow_api(struct netdev *); void netdev_uninit_flow_api(struct netdev *); uint32_t netdev_get_block_id(struct netdev *); From patchwork Wed Nov 20 15:28:16 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eli Britstein X-Patchwork-Id: 1198260 X-Patchwork-Delegate: i.maximets@samsung.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=openvswitch.org (client-ip=140.211.166.136; helo=silver.osuosl.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=mellanox.com Received: from silver.osuosl.org (smtp3.osuosl.org [140.211.166.136]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 47J6HF1LTQz9sPZ for ; Thu, 21 Nov 2019 02:36:25 +1100 (AEDT) Received: from localhost (localhost [127.0.0.1]) by silver.osuosl.org (Postfix) with ESMTP id A521A24FF8; Wed, 20 Nov 2019 15:36:23 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from silver.osuosl.org ([127.0.0.1]) by localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id rtbYB8NKu-jG; Wed, 20 Nov 2019 15:36:20 +0000 (UTC) Received: from lists.linuxfoundation.org (lf-lists.osuosl.org [140.211.9.56]) by silver.osuosl.org (Postfix) with ESMTP id 6DDBD2514E; Wed, 20 Nov 2019 15:35:45 +0000 (UTC) Received: from lf-lists.osuosl.org (localhost [127.0.0.1]) by lists.linuxfoundation.org (Postfix) with ESMTP id 6470EC1DDD; Wed, 20 Nov 2019 15:35:45 +0000 (UTC) X-Original-To: dev@openvswitch.org Delivered-To: ovs-dev@lists.linuxfoundation.org Received: from hemlock.osuosl.org (smtp2.osuosl.org [140.211.166.133]) by lists.linuxfoundation.org (Postfix) with ESMTP id 036BFC1DDC for ; Wed, 20 Nov 2019 15:35:36 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by hemlock.osuosl.org (Postfix) with ESMTP id D30BA885D5 for ; Wed, 20 Nov 2019 15:35:35 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from hemlock.osuosl.org ([127.0.0.1]) by localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id pss5qbhSvyhe for ; Wed, 20 Nov 2019 15:35:34 +0000 (UTC) X-Greylist: from auto-whitelisted by SQLgrey-1.7.6 Received: from mellanox.co.il (mail-il-dmz.mellanox.com [193.47.165.129]) by hemlock.osuosl.org (Postfix) with ESMTP id 1CC02885C4 for ; Wed, 20 Nov 2019 15:35:33 +0000 (UTC) Received: from Internal Mail-Server by MTLPINE1 (envelope-from elibr@mellanox.com) with ESMTPS (AES256-SHA encrypted); 20 Nov 2019 17:28:48 +0200 Received: from dev-r-vrt-215.mtr.labs.mlnx. (dev-r-vrt-215.mtr.labs.mlnx [10.212.215.1]) by labmailer.mlnx (8.13.8/8.13.8) with ESMTP id xAKFSlWG001566; Wed, 20 Nov 2019 17:28:48 +0200 From: Eli Britstein To: dev@openvswitch.org, Ilya Maximets , Ian Stokes Date: Wed, 20 Nov 2019 15:28:16 +0000 Message-Id: <20191120152826.25074-11-elibr@mellanox.com> X-Mailer: git-send-email 2.14.5 In-Reply-To: <20191120152826.25074-1-elibr@mellanox.com> References: <20191120152826.25074-1-elibr@mellanox.com> Cc: Oz Shlomo , Majd Dibbiny , Eli Britstein , Ameer Mahagneh Subject: [ovs-dev] [PATCH 10/20] netdev-dpdk: Introduce rte flow query function X-BeenThere: ovs-dev@openvswitch.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: ovs-dev-bounces@openvswitch.org Sender: "dev" Introduce a rte flow query function as a pre-step towards reading HW statistics of fully offloaded flows. Signed-off-by: Eli Britstein Reviewed-by: Oz Shlomo --- lib/netdev-dpdk.c | 25 +++++++++++++++++++++++++ lib/netdev-dpdk.h | 6 ++++++ 2 files changed, 31 insertions(+) diff --git a/lib/netdev-dpdk.c b/lib/netdev-dpdk.c index 327fa7698..c509ffad3 100644 --- a/lib/netdev-dpdk.c +++ b/lib/netdev-dpdk.c @@ -4501,6 +4501,31 @@ netdev_dpdk_rte_flow_create(struct netdev *netdev, return flow; } +int +netdev_dpdk_rte_flow_query(struct netdev *netdev, + struct rte_flow *rte_flow, + struct rte_flow_query_count *query, + struct rte_flow_error *error) +{ + struct netdev_dpdk *dev = netdev_dpdk_cast(netdev); + struct rte_flow_action_count count = {}; + const struct rte_flow_action actions[] = { + { + .type = RTE_FLOW_ACTION_TYPE_COUNT, + .conf = &count, + }, + { + .type = RTE_FLOW_ACTION_TYPE_END, + }, + }; + int ret; + + ovs_mutex_lock(&dev->mutex); + ret = rte_flow_query(dev->port_id, rte_flow, actions, query, error); + ovs_mutex_unlock(&dev->mutex); + return ret; +} + int netdev_dpdk_rte_flow_flush(struct netdev *netdev, struct rte_flow_error *error) diff --git a/lib/netdev-dpdk.h b/lib/netdev-dpdk.h index 960aec7a8..8e79bcdf8 100644 --- a/lib/netdev-dpdk.h +++ b/lib/netdev-dpdk.h @@ -31,6 +31,7 @@ struct rte_flow_error; struct rte_flow_attr; struct rte_flow_item; struct rte_flow_action; +struct rte_flow_query_count; void netdev_dpdk_register(void); void free_dpdk_buf(struct dp_packet *); @@ -50,6 +51,11 @@ netdev_dpdk_rte_flow_create(struct netdev *netdev, int netdev_dpdk_rte_flow_flush(struct netdev *netdev, struct rte_flow_error *error); +int +netdev_dpdk_rte_flow_query(struct netdev *netdev, + struct rte_flow *rte_flow, + struct rte_flow_query_count *query, + struct rte_flow_error *error); #else From patchwork Wed Nov 20 15:28:17 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eli Britstein X-Patchwork-Id: 1198246 X-Patchwork-Delegate: i.maximets@samsung.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=openvswitch.org (client-ip=140.211.166.133; helo=hemlock.osuosl.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=mellanox.com Received: from hemlock.osuosl.org (smtp2.osuosl.org [140.211.166.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 47J6GP1bnCz9sPc for ; Thu, 21 Nov 2019 02:35:41 +1100 (AEDT) Received: from localhost (localhost [127.0.0.1]) by hemlock.osuosl.org (Postfix) with ESMTP id CEEFB88600; Wed, 20 Nov 2019 15:35:38 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from hemlock.osuosl.org ([127.0.0.1]) by localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id YuDDi18Simbs; Wed, 20 Nov 2019 15:35:36 +0000 (UTC) Received: from lists.linuxfoundation.org (lf-lists.osuosl.org [140.211.9.56]) by hemlock.osuosl.org (Postfix) with ESMTP id B8FFC86F3F; Wed, 20 Nov 2019 15:35:36 +0000 (UTC) Received: from lf-lists.osuosl.org (localhost [127.0.0.1]) by lists.linuxfoundation.org (Postfix) with ESMTP id 7AE82C1DDD; Wed, 20 Nov 2019 15:35:36 +0000 (UTC) X-Original-To: dev@openvswitch.org Delivered-To: ovs-dev@lists.linuxfoundation.org Received: from whitealder.osuosl.org (smtp1.osuosl.org [140.211.166.138]) by lists.linuxfoundation.org (Postfix) with ESMTP id 5FD8AC18DA for ; Wed, 20 Nov 2019 15:35:35 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by whitealder.osuosl.org (Postfix) with ESMTP id 4B4A18794A for ; Wed, 20 Nov 2019 15:35:35 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from whitealder.osuosl.org ([127.0.0.1]) by localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id 1vzjn71esz5D for ; Wed, 20 Nov 2019 15:35:34 +0000 (UTC) X-Greylist: from auto-whitelisted by SQLgrey-1.7.6 Received: from mellanox.co.il (mail-il-dmz.mellanox.com [193.47.165.129]) by whitealder.osuosl.org (Postfix) with ESMTP id 0FF7A87927 for ; Wed, 20 Nov 2019 15:35:33 +0000 (UTC) Received: from Internal Mail-Server by MTLPINE1 (envelope-from elibr@mellanox.com) with ESMTPS (AES256-SHA encrypted); 20 Nov 2019 17:28:48 +0200 Received: from dev-r-vrt-215.mtr.labs.mlnx. (dev-r-vrt-215.mtr.labs.mlnx [10.212.215.1]) by labmailer.mlnx (8.13.8/8.13.8) with ESMTP id xAKFSlWH001566; Wed, 20 Nov 2019 17:28:48 +0200 From: Eli Britstein To: dev@openvswitch.org, Ilya Maximets , Ian Stokes Date: Wed, 20 Nov 2019 15:28:17 +0000 Message-Id: <20191120152826.25074-12-elibr@mellanox.com> X-Mailer: git-send-email 2.14.5 In-Reply-To: <20191120152826.25074-1-elibr@mellanox.com> References: <20191120152826.25074-1-elibr@mellanox.com> Cc: Oz Shlomo , Majd Dibbiny , Eli Britstein , Ameer Mahagneh Subject: [ovs-dev] [PATCH 11/20] netdev-offload-dpdk: Implement flow stats get X-BeenThere: ovs-dev@openvswitch.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: ovs-dev-bounces@openvswitch.org Sender: "dev" Implement the flow stats method for DPDK, towards reading statistics of fully offloaded flows. Signed-off-by: Eli Britstein Reviewed-by: Oz Shlomo --- lib/netdev-offload-dpdk.c | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/lib/netdev-offload-dpdk.c b/lib/netdev-offload-dpdk.c index 9a166970f..ad050f015 100644 --- a/lib/netdev-offload-dpdk.c +++ b/lib/netdev-offload-dpdk.c @@ -334,6 +334,36 @@ netdev_offload_dpdk_flow_flush(struct netdev *netdev) return ret; } +static int +netdev_offload_dpdk_flow_stats_get(struct netdev *netdev, + const ovs_u128 *ufid, + struct dpif_flow_stats *stats) +{ + struct rte_flow_query_count query = { .reset = 1 }; + struct rte_flow_error error; + struct rte_flow *rte_flow; + int ret; + + rte_flow = ufid_to_rte_flow_find(ufid); + if (!rte_flow) { + return -1; + } + + memset(stats, 0, sizeof *stats); + ret = netdev_dpdk_rte_flow_query(netdev, rte_flow, &query, &error); + if (ret) { + VLOG_DBG("ufid "UUID_FMT + " flow %p query for '%s' failed\n", + UUID_ARGS((struct uuid *)ufid), rte_flow, + netdev_get_name(netdev)); + return -1; + } + stats->n_packets += (query.hits_set) ? query.hits : 0; + stats->n_bytes += (query.bytes_set) ? query.bytes : 0; + + return 0; +} + static int netdev_offload_dpdk_init_flow_api(struct netdev *netdev) { @@ -345,5 +375,6 @@ const struct netdev_flow_api netdev_offload_dpdk = { .flow_flush = netdev_offload_dpdk_flow_flush, .flow_put = netdev_offload_dpdk_flow_put, .flow_del = netdev_offload_dpdk_flow_del, + .flow_stats_get = netdev_offload_dpdk_flow_stats_get, .init_flow_api = netdev_offload_dpdk_init_flow_api, }; From patchwork Wed Nov 20 15:28:18 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eli Britstein X-Patchwork-Id: 1198250 X-Patchwork-Delegate: i.maximets@samsung.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=openvswitch.org (client-ip=140.211.166.137; helo=fraxinus.osuosl.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=mellanox.com Received: from fraxinus.osuosl.org (smtp4.osuosl.org [140.211.166.137]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 47J6GW1sL4z9sR4 for ; Thu, 21 Nov 2019 02:35:46 +1100 (AEDT) Received: from localhost (localhost [127.0.0.1]) by fraxinus.osuosl.org (Postfix) with ESMTP id 4CA3386D50; Wed, 20 Nov 2019 15:35:44 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from fraxinus.osuosl.org ([127.0.0.1]) by localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id 5Q_ib4gWMtog; Wed, 20 Nov 2019 15:35:40 +0000 (UTC) Received: from lists.linuxfoundation.org (lf-lists.osuosl.org [140.211.9.56]) by fraxinus.osuosl.org (Postfix) with ESMTP id 6C62586D4C; Wed, 20 Nov 2019 15:35:39 +0000 (UTC) Received: from lf-lists.osuosl.org (localhost [127.0.0.1]) by lists.linuxfoundation.org (Postfix) with ESMTP id 61A5AC1DDC; Wed, 20 Nov 2019 15:35:39 +0000 (UTC) X-Original-To: dev@openvswitch.org Delivered-To: ovs-dev@lists.linuxfoundation.org Received: from whitealder.osuosl.org (smtp1.osuosl.org [140.211.166.138]) by lists.linuxfoundation.org (Postfix) with ESMTP id 74BFDC1DDD for ; Wed, 20 Nov 2019 15:35:35 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by whitealder.osuosl.org (Postfix) with ESMTP id 5D4C187927 for ; Wed, 20 Nov 2019 15:35:35 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from whitealder.osuosl.org ([127.0.0.1]) by localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id myZQLPE8DyuS for ; Wed, 20 Nov 2019 15:35:34 +0000 (UTC) X-Greylist: delayed 00:06:41 by SQLgrey-1.7.6 Received: from mellanox.co.il (mail-il-dmz.mellanox.com [193.47.165.129]) by whitealder.osuosl.org (Postfix) with ESMTP id 0DBE5878EA for ; Wed, 20 Nov 2019 15:35:33 +0000 (UTC) Received: from Internal Mail-Server by MTLPINE1 (envelope-from elibr@mellanox.com) with ESMTPS (AES256-SHA encrypted); 20 Nov 2019 17:28:48 +0200 Received: from dev-r-vrt-215.mtr.labs.mlnx. (dev-r-vrt-215.mtr.labs.mlnx [10.212.215.1]) by labmailer.mlnx (8.13.8/8.13.8) with ESMTP id xAKFSlWI001566; Wed, 20 Nov 2019 17:28:48 +0200 From: Eli Britstein To: dev@openvswitch.org, Ilya Maximets , Ian Stokes Date: Wed, 20 Nov 2019 15:28:18 +0000 Message-Id: <20191120152826.25074-13-elibr@mellanox.com> X-Mailer: git-send-email 2.14.5 In-Reply-To: <20191120152826.25074-1-elibr@mellanox.com> References: <20191120152826.25074-1-elibr@mellanox.com> Cc: Oz Shlomo , Majd Dibbiny , Eli Britstein , Ameer Mahagneh Subject: [ovs-dev] [PATCH 12/20] dpif-netdev: Read hw stats during flow_dump_next() call X-BeenThere: ovs-dev@openvswitch.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: ovs-dev-bounces@openvswitch.org Sender: "dev" From: Ophir Munk Flow stats are retrieved by revalidator threads. Specifically for dpif-netdev the function dpif_netdev_flow_dump_next() is called. When the flow is fully offloaded reading the PMD SW stats alone will result in no updates and will cause the revalidator to falsely delete the flow after some aging time. This commit adds a new function called dp_netdev_offload_used() which reads the hw counters during the flow_dump_next() call. The new function calls netdev_flow_stats_get() which in turn reads the hardware stats by calling DPDK rte_flow_query() API. Signed-off-by: Ophir Munk Reviewed-by: Oz Shlomo Signed-off-by: Eli Britstein --- lib/dpif-netdev.c | 40 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 39 insertions(+), 1 deletion(-) diff --git a/lib/dpif-netdev.c b/lib/dpif-netdev.c index 4720ba1ab..d9f28cfcd 100644 --- a/lib/dpif-netdev.c +++ b/lib/dpif-netdev.c @@ -527,6 +527,7 @@ struct dp_netdev_flow { bool dead; uint32_t mark; /* Unique flow mark assigned to a flow */ + bool actions_offloaded; /* true if flow is fully offloaded */ /* Statistics. */ struct dp_netdev_flow_stats stats; @@ -2422,6 +2423,7 @@ dp_netdev_flow_offload_put(struct dp_flow_offload_item *offload) offload->actions_len, &flow->mega_ufid, &info, NULL); ovs_mutex_unlock(&pmd->dp->port_mutex); + flow->actions_offloaded = info.actions_offloaded; if (ret) { goto err_free; @@ -3073,7 +3075,7 @@ dp_netdev_flow_to_dpif_flow(const struct dp_netdev_flow *netdev_flow, flow->pmd_id = netdev_flow->pmd_id; get_dpif_flow_stats(netdev_flow, &flow->stats); - flow->attrs.offloaded = false; + flow->attrs.offloaded = netdev_flow->actions_offloaded; flow->attrs.dp_layer = "ovs"; } @@ -3244,6 +3246,7 @@ dp_netdev_flow_add(struct dp_netdev_pmd_thread *pmd, flow->dead = false; flow->batch = NULL; flow->mark = INVALID_FLOW_MARK; + flow->actions_offloaded = false; *CONST_CAST(unsigned *, &flow->pmd_id) = pmd->core_id; *CONST_CAST(struct flow *, &flow->flow) = match->flow; *CONST_CAST(ovs_u128 *, &flow->ufid) = *ufid; @@ -3598,6 +3601,37 @@ dpif_netdev_flow_dump_thread_destroy(struct dpif_flow_dump_thread *thread_) free(thread); } +static int +dpif_netdev_offload_used(struct dp_netdev_flow *netdev_flow, + struct dp_netdev_pmd_thread *pmd) +{ + int ret; + struct dp_netdev_port *port; + struct dpif_flow_stats stats; + + odp_port_t in_port = netdev_flow->flow.in_port.odp_port; + + ovs_mutex_lock(&pmd->dp->port_mutex); + port = dp_netdev_lookup_port(pmd->dp, in_port); + if (!port) { + ovs_mutex_unlock(&pmd->dp->port_mutex); + return -1; + } + /* get offloaded stats */ + ret = netdev_flow_stats_get(port->netdev, &netdev_flow->mega_ufid, &stats); + ovs_mutex_unlock(&pmd->dp->port_mutex); + if (ret) { + return -1; + } + if (stats.n_packets) { + atomic_store_relaxed(&netdev_flow->stats.used, pmd->ctx.now / 1000); + non_atomic_ullong_add(&netdev_flow->stats.packet_count, stats.n_packets); + non_atomic_ullong_add(&netdev_flow->stats.byte_count, stats.n_bytes); + } + + return 0; +} + static int dpif_netdev_flow_dump_next(struct dpif_flow_dump_thread *thread_, struct dpif_flow *flows, int max_flows) @@ -3638,6 +3672,10 @@ dpif_netdev_flow_dump_next(struct dpif_flow_dump_thread *thread_, netdev_flows[n_flows] = CONTAINER_OF(node, struct dp_netdev_flow, node); + /* Read hardware stats in case of hardware offload */ + if (netdev_flows[n_flows]->actions_offloaded) { + dpif_netdev_offload_used(netdev_flows[n_flows], pmd); + } } /* When finishing dumping the current pmd thread, moves to * the next. */ From patchwork Wed Nov 20 15:28:19 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eli Britstein X-Patchwork-Id: 1198261 X-Patchwork-Delegate: i.maximets@samsung.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=openvswitch.org (client-ip=140.211.166.136; helo=silver.osuosl.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=mellanox.com Received: from silver.osuosl.org (smtp3.osuosl.org [140.211.166.136]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 47J6Hc284xz9sPc for ; Thu, 21 Nov 2019 02:36:44 +1100 (AEDT) Received: from localhost (localhost [127.0.0.1]) by silver.osuosl.org (Postfix) with ESMTP id 972502547E; Wed, 20 Nov 2019 15:36:42 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from silver.osuosl.org ([127.0.0.1]) by localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id hBpmS5J8w-ND; Wed, 20 Nov 2019 15:36:39 +0000 (UTC) Received: from lists.linuxfoundation.org (lf-lists.osuosl.org [140.211.9.56]) by silver.osuosl.org (Postfix) with ESMTP id 10FD02582B; Wed, 20 Nov 2019 15:35:49 +0000 (UTC) Received: from lf-lists.osuosl.org (localhost [127.0.0.1]) by lists.linuxfoundation.org (Postfix) with ESMTP id BBEABC1DE8; Wed, 20 Nov 2019 15:35:48 +0000 (UTC) X-Original-To: dev@openvswitch.org Delivered-To: ovs-dev@lists.linuxfoundation.org Received: from silver.osuosl.org (smtp3.osuosl.org [140.211.166.136]) by lists.linuxfoundation.org (Postfix) with ESMTP id 42D4EC1DD8 for ; Wed, 20 Nov 2019 15:35:36 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by silver.osuosl.org (Postfix) with ESMTP id 1362420017 for ; Wed, 20 Nov 2019 15:35:36 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from silver.osuosl.org ([127.0.0.1]) by localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id PSw1Z1DYiLFR for ; Wed, 20 Nov 2019 15:35:34 +0000 (UTC) X-Greylist: from auto-whitelisted by SQLgrey-1.7.6 Received: from mellanox.co.il (mail-il-dmz.mellanox.com [193.47.165.129]) by silver.osuosl.org (Postfix) with ESMTP id 191B2204D9 for ; Wed, 20 Nov 2019 15:35:33 +0000 (UTC) Received: from Internal Mail-Server by MTLPINE1 (envelope-from elibr@mellanox.com) with ESMTPS (AES256-SHA encrypted); 20 Nov 2019 17:28:49 +0200 Received: from dev-r-vrt-215.mtr.labs.mlnx. (dev-r-vrt-215.mtr.labs.mlnx [10.212.215.1]) by labmailer.mlnx (8.13.8/8.13.8) with ESMTP id xAKFSlWJ001566; Wed, 20 Nov 2019 17:28:48 +0200 From: Eli Britstein To: dev@openvswitch.org, Ilya Maximets , Ian Stokes Date: Wed, 20 Nov 2019 15:28:19 +0000 Message-Id: <20191120152826.25074-14-elibr@mellanox.com> X-Mailer: git-send-email 2.14.5 In-Reply-To: <20191120152826.25074-1-elibr@mellanox.com> References: <20191120152826.25074-1-elibr@mellanox.com> Cc: Oz Shlomo , Majd Dibbiny , Eli Britstein , Ameer Mahagneh Subject: [ovs-dev] [PATCH 13/20] dpif-netdev: Populate dpif class field in offload struct X-BeenThere: ovs-dev@openvswitch.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: ovs-dev-bounces@openvswitch.org Sender: "dev" Populate dpif class field in offload struct to be used in offloading flow put. Signed-off-by: Eli Britstein Reviewed-by: Oz Shlomo --- lib/dpif-netdev.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/dpif-netdev.c b/lib/dpif-netdev.c index d9f28cfcd..76784c9d4 100644 --- a/lib/dpif-netdev.c +++ b/lib/dpif-netdev.c @@ -2375,6 +2375,7 @@ dp_netdev_flow_offload_put(struct dp_flow_offload_item *offload) { struct dp_netdev_port *port; struct dp_netdev_pmd_thread *pmd = offload->pmd; + const struct dpif_class *dpif_class = pmd->dp->class; struct dp_netdev_flow *flow = offload->flow; odp_port_t in_port = flow->flow.in_port.odp_port; bool modification = offload->op == DP_NETDEV_FLOW_OFFLOAD_OP_MOD; @@ -2411,6 +2412,7 @@ dp_netdev_flow_offload_put(struct dp_flow_offload_item *offload) } } info.flow_mark = mark; + info.dpif_class = dpif_class; ovs_mutex_lock(&pmd->dp->port_mutex); port = dp_netdev_lookup_port(pmd->dp, in_port); From patchwork Wed Nov 20 15:28:20 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eli Britstein X-Patchwork-Id: 1198253 X-Patchwork-Delegate: i.maximets@samsung.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=openvswitch.org (client-ip=140.211.166.136; helo=silver.osuosl.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=mellanox.com Received: from silver.osuosl.org (smtp3.osuosl.org [140.211.166.136]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 47J6Gh3hTvz9sR5 for ; Thu, 21 Nov 2019 02:35:56 +1100 (AEDT) Received: from localhost (localhost [127.0.0.1]) by silver.osuosl.org (Postfix) with ESMTP id 958BA25E31; Wed, 20 Nov 2019 15:35:54 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from silver.osuosl.org ([127.0.0.1]) by localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id 5aR1Dh-QG7mY; Wed, 20 Nov 2019 15:35:44 +0000 (UTC) Received: from lists.linuxfoundation.org (lf-lists.osuosl.org [140.211.9.56]) by silver.osuosl.org (Postfix) with ESMTP id BBAD3246FD; Wed, 20 Nov 2019 15:35:38 +0000 (UTC) Received: from lf-lists.osuosl.org (localhost [127.0.0.1]) by lists.linuxfoundation.org (Postfix) with ESMTP id A07ADC1DDC; Wed, 20 Nov 2019 15:35:38 +0000 (UTC) X-Original-To: dev@openvswitch.org Delivered-To: ovs-dev@lists.linuxfoundation.org Received: from fraxinus.osuosl.org (smtp4.osuosl.org [140.211.166.137]) by lists.linuxfoundation.org (Postfix) with ESMTP id 6D70FC1DDC for ; Wed, 20 Nov 2019 15:35:35 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by fraxinus.osuosl.org (Postfix) with ESMTP id 5AF0A86C6C for ; Wed, 20 Nov 2019 15:35:35 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from fraxinus.osuosl.org ([127.0.0.1]) by localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id NeYBPcgO_TfB for ; Wed, 20 Nov 2019 15:35:34 +0000 (UTC) X-Greylist: from auto-whitelisted by SQLgrey-1.7.6 Received: from mellanox.co.il (mail-il-dmz.mellanox.com [193.47.165.129]) by fraxinus.osuosl.org (Postfix) with ESMTP id 1A41486C40 for ; Wed, 20 Nov 2019 15:35:33 +0000 (UTC) Received: from Internal Mail-Server by MTLPINE1 (envelope-from elibr@mellanox.com) with ESMTPS (AES256-SHA encrypted); 20 Nov 2019 17:28:49 +0200 Received: from dev-r-vrt-215.mtr.labs.mlnx. (dev-r-vrt-215.mtr.labs.mlnx [10.212.215.1]) by labmailer.mlnx (8.13.8/8.13.8) with ESMTP id xAKFSlWK001566; Wed, 20 Nov 2019 17:28:49 +0200 From: Eli Britstein To: dev@openvswitch.org, Ilya Maximets , Ian Stokes Date: Wed, 20 Nov 2019 15:28:20 +0000 Message-Id: <20191120152826.25074-15-elibr@mellanox.com> X-Mailer: git-send-email 2.14.5 In-Reply-To: <20191120152826.25074-1-elibr@mellanox.com> References: <20191120152826.25074-1-elibr@mellanox.com> Cc: Oz Shlomo , Majd Dibbiny , Eli Britstein , Ameer Mahagneh Subject: [ovs-dev] [PATCH 14/20] netdev-dpdk: Getter function for dpdk port id API X-BeenThere: ovs-dev@openvswitch.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: ovs-dev-bounces@openvswitch.org Sender: "dev" Add a getter function for using the dpdk port id outside the scope of netdev-dpdk.c. Signed-off-by: Eli Britstein Reviewed-by: Oz Shlomo --- lib/netdev-dpdk.c | 9 +++++++++ lib/netdev-dpdk.h | 2 ++ 2 files changed, 11 insertions(+) diff --git a/lib/netdev-dpdk.c b/lib/netdev-dpdk.c index c509ffad3..ed8d99f1a 100644 --- a/lib/netdev-dpdk.c +++ b/lib/netdev-dpdk.c @@ -4422,6 +4422,15 @@ unlock: return err; } +int +netdev_dpdk_get_port_id(const struct netdev *netdev) +{ + if (!is_dpdk_class(netdev->netdev_class)) { + return -1; + } + return CONTAINER_OF(netdev, struct netdev_dpdk, up)->port_id; +} + bool netdev_dpdk_flow_api_supported(struct netdev *netdev) { diff --git a/lib/netdev-dpdk.h b/lib/netdev-dpdk.h index 8e79bcdf8..54582ed90 100644 --- a/lib/netdev-dpdk.h +++ b/lib/netdev-dpdk.h @@ -56,6 +56,8 @@ netdev_dpdk_rte_flow_query(struct netdev *netdev, struct rte_flow *rte_flow, struct rte_flow_query_count *query, struct rte_flow_error *error); +int +netdev_dpdk_get_port_id(const struct netdev *netdev); #else From patchwork Wed Nov 20 15:28:21 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eli Britstein X-Patchwork-Id: 1198264 X-Patchwork-Delegate: i.maximets@samsung.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=openvswitch.org (client-ip=140.211.166.136; helo=silver.osuosl.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=mellanox.com Received: from silver.osuosl.org (smtp3.osuosl.org [140.211.166.136]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 47J6Hz1dlbz9sPZ for ; Thu, 21 Nov 2019 02:37:03 +1100 (AEDT) Received: from localhost (localhost [127.0.0.1]) by silver.osuosl.org (Postfix) with ESMTP id A151C25435; Wed, 20 Nov 2019 15:37:01 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from silver.osuosl.org ([127.0.0.1]) by localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id y4T9TfddLKXf; Wed, 20 Nov 2019 15:36:57 +0000 (UTC) Received: from lists.linuxfoundation.org (lf-lists.osuosl.org [140.211.9.56]) by silver.osuosl.org (Postfix) with ESMTP id CDD0123DB4; Wed, 20 Nov 2019 15:35:51 +0000 (UTC) Received: from lf-lists.osuosl.org (localhost [127.0.0.1]) by lists.linuxfoundation.org (Postfix) with ESMTP id 321E3C1DF5; Wed, 20 Nov 2019 15:35:51 +0000 (UTC) X-Original-To: dev@openvswitch.org Delivered-To: ovs-dev@lists.linuxfoundation.org Received: from whitealder.osuosl.org (smtp1.osuosl.org [140.211.166.138]) by lists.linuxfoundation.org (Postfix) with ESMTP id 7EB39C1DD8 for ; Wed, 20 Nov 2019 15:35:36 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by whitealder.osuosl.org (Postfix) with ESMTP id 63DA0878EA for ; Wed, 20 Nov 2019 15:35:36 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from whitealder.osuosl.org ([127.0.0.1]) by localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id u2ayglVx1DaJ for ; Wed, 20 Nov 2019 15:35:34 +0000 (UTC) X-Greylist: from auto-whitelisted by SQLgrey-1.7.6 Received: from mellanox.co.il (mail-il-dmz.mellanox.com [193.47.165.129]) by whitealder.osuosl.org (Postfix) with ESMTP id 13934879F8 for ; Wed, 20 Nov 2019 15:35:33 +0000 (UTC) Received: from Internal Mail-Server by MTLPINE1 (envelope-from elibr@mellanox.com) with ESMTPS (AES256-SHA encrypted); 20 Nov 2019 17:28:49 +0200 Received: from dev-r-vrt-215.mtr.labs.mlnx. (dev-r-vrt-215.mtr.labs.mlnx [10.212.215.1]) by labmailer.mlnx (8.13.8/8.13.8) with ESMTP id xAKFSlWL001566; Wed, 20 Nov 2019 17:28:49 +0200 From: Eli Britstein To: dev@openvswitch.org, Ilya Maximets , Ian Stokes Date: Wed, 20 Nov 2019 15:28:21 +0000 Message-Id: <20191120152826.25074-16-elibr@mellanox.com> X-Mailer: git-send-email 2.14.5 In-Reply-To: <20191120152826.25074-1-elibr@mellanox.com> References: <20191120152826.25074-1-elibr@mellanox.com> Cc: Oz Shlomo , Majd Dibbiny , Eli Britstein , Ameer Mahagneh Subject: [ovs-dev] [PATCH 15/20] netdev-offload-dpdk-flow: Support offload of output action X-BeenThere: ovs-dev@openvswitch.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: ovs-dev-bounces@openvswitch.org Sender: "dev" Signed-off-by: Eli Britstein Reviewed-by: Oz Shlomo --- NEWS | 2 + lib/netdev-offload-dpdk-flow.c | 87 ++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 85 insertions(+), 4 deletions(-) diff --git a/NEWS b/NEWS index 88b818948..ca9c2b230 100644 --- a/NEWS +++ b/NEWS @@ -10,6 +10,8 @@ Post-v2.12.0 if supported by libbpf. * Add option to enable, disable and query TCP sequence checking in conntrack. + - DPDK: + * Add hardware offload support for output actions. v2.12.0 - 03 Sep 2019 --------------------- diff --git a/lib/netdev-offload-dpdk-flow.c b/lib/netdev-offload-dpdk-flow.c index dbbc45e99..6e7efb315 100644 --- a/lib/netdev-offload-dpdk-flow.c +++ b/lib/netdev-offload-dpdk-flow.c @@ -274,6 +274,28 @@ ds_put_flow_action(struct ds *s, const struct rte_flow_action *actions) } else { ds_put_cstr(s, " RSS = null\n"); } + } else if (actions->type == RTE_FLOW_ACTION_TYPE_COUNT) { + const struct rte_flow_action_count *count = actions->conf; + + ds_put_cstr(s, "rte flow count action:\n"); + if (count) { + ds_put_format(s, + " Count: shared=%d, id=%d\n", + count->shared, count->id); + } else { + ds_put_cstr(s, " Count = null\n"); + } + } else if (actions->type == RTE_FLOW_ACTION_TYPE_PORT_ID) { + const struct rte_flow_action_port_id *port_id = actions->conf; + + ds_put_cstr(s, "rte flow port-id action:\n"); + if (port_id) { + ds_put_format(s, + " Port-id: original=%d, id=%d\n", + port_id->original, port_id->id); + } else { + ds_put_cstr(s, " Port-id = null\n"); + } } else { ds_put_format(s, "unknown rte flow action (%d)\n", actions->type); } @@ -531,19 +553,76 @@ netdev_dpdk_flow_patterns_add(struct flow_patterns *patterns, return 0; } +static void +netdev_dpdk_flow_add_count_action(struct flow_actions *actions) +{ + struct rte_flow_action_count *count = xzalloc(sizeof *count); + + count->shared = 0; + /* Each flow has a single count action, so no need of id */ + count->id = 0; + add_flow_action(actions, RTE_FLOW_ACTION_TYPE_COUNT, count); +} + +static void +netdev_dpdk_flow_add_port_id_action(struct flow_actions *actions, + struct netdev *outdev) +{ + struct rte_flow_action_port_id *port_id = xzalloc(sizeof *port_id); + + port_id->id = netdev_dpdk_get_port_id(outdev); + add_flow_action(actions, RTE_FLOW_ACTION_TYPE_PORT_ID, port_id); +} + +static int +netdev_dpdk_flow_add_output_action(struct flow_actions *actions, + const struct nlattr *nla, + struct offload_info *info) +{ + struct netdev *outdev; + odp_port_t port; + + port = nl_attr_get_odp_port(nla); + outdev = netdev_ports_get(port, info->dpif_class); + if (outdev == NULL) { + VLOG_DBG_RL(&error_rl, + "Cannot find netdev for odp port %d", port); + return -1; + } + if (!netdev_dpdk_flow_api_supported(outdev)) { + VLOG_DBG_RL(&error_rl, + "Output to %s cannot be offloaded", + netdev_get_name(outdev)); + return -1; + } + + netdev_dpdk_flow_add_count_action(actions); + netdev_dpdk_flow_add_port_id_action(actions, outdev); + netdev_close(outdev); + + return 0; +} + int netdev_dpdk_flow_actions_add(struct flow_actions *actions, struct nlattr *nl_actions, size_t nl_actions_len, - struct offload_info *info OVS_UNUSED) + struct offload_info *info) { struct nlattr *nla; size_t left; NL_ATTR_FOR_EACH_UNSAFE (nla, left, nl_actions, nl_actions_len) { - VLOG_DBG_RL(&error_rl, - "Unsupported action type %d", nl_attr_type(nla)); - return -1; + if (nl_attr_type(nla) == OVS_ACTION_ATTR_OUTPUT && + left <= NLA_ALIGN(nla->nla_len)) { + if (netdev_dpdk_flow_add_output_action(actions, nla, info )) { + return -1; + } + } else { + VLOG_DBG_RL(&error_rl, + "Unsupported action type %d", nl_attr_type(nla)); + return -1; + } } add_flow_action(actions, RTE_FLOW_ACTION_TYPE_END, NULL); From patchwork Wed Nov 20 15:28:22 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eli Britstein X-Patchwork-Id: 1198249 X-Patchwork-Delegate: i.maximets@samsung.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=openvswitch.org (client-ip=140.211.166.136; helo=silver.osuosl.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=mellanox.com Received: from silver.osuosl.org (smtp3.osuosl.org [140.211.166.136]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 47J6GT5YMYz9sR7 for ; Thu, 21 Nov 2019 02:35:45 +1100 (AEDT) Received: from localhost (localhost [127.0.0.1]) by silver.osuosl.org (Postfix) with ESMTP id CB56520017; Wed, 20 Nov 2019 15:35:41 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from silver.osuosl.org ([127.0.0.1]) by localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id i8Q0Kgb20hKZ; Wed, 20 Nov 2019 15:35:37 +0000 (UTC) Received: from lists.linuxfoundation.org (lf-lists.osuosl.org [140.211.9.56]) by silver.osuosl.org (Postfix) with ESMTP id 7C3BB2285E; Wed, 20 Nov 2019 15:35:37 +0000 (UTC) Received: from lf-lists.osuosl.org (localhost [127.0.0.1]) by lists.linuxfoundation.org (Postfix) with ESMTP id 61020C1DDD; Wed, 20 Nov 2019 15:35:37 +0000 (UTC) X-Original-To: dev@openvswitch.org Delivered-To: ovs-dev@lists.linuxfoundation.org Received: from whitealder.osuosl.org (smtp1.osuosl.org [140.211.166.138]) by lists.linuxfoundation.org (Postfix) with ESMTP id 6186DC1DD8 for ; Wed, 20 Nov 2019 15:35:35 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by whitealder.osuosl.org (Postfix) with ESMTP id 4FAD787C93 for ; Wed, 20 Nov 2019 15:35:35 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from whitealder.osuosl.org ([127.0.0.1]) by localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id MmXkYGPpm5zV for ; Wed, 20 Nov 2019 15:35:34 +0000 (UTC) X-Greylist: from auto-whitelisted by SQLgrey-1.7.6 Received: from mellanox.co.il (mail-il-dmz.mellanox.com [193.47.165.129]) by whitealder.osuosl.org (Postfix) with ESMTP id 12B0E87954 for ; Wed, 20 Nov 2019 15:35:33 +0000 (UTC) Received: from Internal Mail-Server by MTLPINE1 (envelope-from elibr@mellanox.com) with ESMTPS (AES256-SHA encrypted); 20 Nov 2019 17:28:49 +0200 Received: from dev-r-vrt-215.mtr.labs.mlnx. (dev-r-vrt-215.mtr.labs.mlnx [10.212.215.1]) by labmailer.mlnx (8.13.8/8.13.8) with ESMTP id xAKFSlWM001566; Wed, 20 Nov 2019 17:28:49 +0200 From: Eli Britstein To: dev@openvswitch.org, Ilya Maximets , Ian Stokes Date: Wed, 20 Nov 2019 15:28:22 +0000 Message-Id: <20191120152826.25074-17-elibr@mellanox.com> X-Mailer: git-send-email 2.14.5 In-Reply-To: <20191120152826.25074-1-elibr@mellanox.com> References: <20191120152826.25074-1-elibr@mellanox.com> Cc: Oz Shlomo , Majd Dibbiny , Eli Britstein , Ameer Mahagneh Subject: [ovs-dev] [PATCH 16/20] netdev-offload-dpdk-flow: Support offload of drop action X-BeenThere: ovs-dev@openvswitch.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: ovs-dev-bounces@openvswitch.org Sender: "dev" Signed-off-by: Eli Britstein Reviewed-by: Oz Shlomo --- NEWS | 2 +- lib/netdev-offload-dpdk-flow.c | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/NEWS b/NEWS index ca9c2b230..08aa6e03b 100644 --- a/NEWS +++ b/NEWS @@ -11,7 +11,7 @@ Post-v2.12.0 * Add option to enable, disable and query TCP sequence checking in conntrack. - DPDK: - * Add hardware offload support for output actions. + * Add hardware offload support for output and drop actions. v2.12.0 - 03 Sep 2019 --------------------- diff --git a/lib/netdev-offload-dpdk-flow.c b/lib/netdev-offload-dpdk-flow.c index 6e7efb315..a1cf6f129 100644 --- a/lib/netdev-offload-dpdk-flow.c +++ b/lib/netdev-offload-dpdk-flow.c @@ -296,6 +296,8 @@ ds_put_flow_action(struct ds *s, const struct rte_flow_action *actions) } else { ds_put_cstr(s, " Port-id = null\n"); } + } else if (actions->type == RTE_FLOW_ACTION_TYPE_DROP) { + ds_put_cstr(s, "rte flow drop action\n"); } else { ds_put_format(s, "unknown rte flow action (%d)\n", actions->type); } @@ -625,6 +627,9 @@ netdev_dpdk_flow_actions_add(struct flow_actions *actions, } } + if (nl_actions_len == 0) { + add_flow_action(actions, RTE_FLOW_ACTION_TYPE_DROP, NULL); + } add_flow_action(actions, RTE_FLOW_ACTION_TYPE_END, NULL); return 0; } From patchwork Wed Nov 20 15:28:23 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eli Britstein X-Patchwork-Id: 1198265 X-Patchwork-Delegate: i.maximets@samsung.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=openvswitch.org (client-ip=140.211.166.136; helo=silver.osuosl.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=mellanox.com Received: from silver.osuosl.org (smtp3.osuosl.org [140.211.166.136]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 47J6J567Jbz9sPZ for ; Thu, 21 Nov 2019 02:37:09 +1100 (AEDT) Received: from localhost (localhost [127.0.0.1]) by silver.osuosl.org (Postfix) with ESMTP id 4E74C25AA5; Wed, 20 Nov 2019 15:37:08 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from silver.osuosl.org ([127.0.0.1]) by localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id kkyAk0-+cg2E; Wed, 20 Nov 2019 15:37:03 +0000 (UTC) Received: from lists.linuxfoundation.org (lf-lists.osuosl.org [140.211.9.56]) by silver.osuosl.org (Postfix) with ESMTP id C4A3125CA8; Wed, 20 Nov 2019 15:35:52 +0000 (UTC) Received: from lf-lists.osuosl.org (localhost [127.0.0.1]) by lists.linuxfoundation.org (Postfix) with ESMTP id 927F8C1DE5; Wed, 20 Nov 2019 15:35:52 +0000 (UTC) X-Original-To: dev@openvswitch.org Delivered-To: ovs-dev@lists.linuxfoundation.org Received: from hemlock.osuosl.org (smtp2.osuosl.org [140.211.166.133]) by lists.linuxfoundation.org (Postfix) with ESMTP id 78B88C1DDC for ; Wed, 20 Nov 2019 15:35:36 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by hemlock.osuosl.org (Postfix) with ESMTP id 571F486F3F for ; Wed, 20 Nov 2019 15:35:36 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from hemlock.osuosl.org ([127.0.0.1]) by localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id QPGaGL9iol8X for ; Wed, 20 Nov 2019 15:35:34 +0000 (UTC) X-Greylist: from auto-whitelisted by SQLgrey-1.7.6 Received: from mellanox.co.il (mail-il-dmz.mellanox.com [193.47.165.129]) by hemlock.osuosl.org (Postfix) with ESMTP id 1D7F1885C8 for ; Wed, 20 Nov 2019 15:35:33 +0000 (UTC) Received: from Internal Mail-Server by MTLPINE1 (envelope-from elibr@mellanox.com) with ESMTPS (AES256-SHA encrypted); 20 Nov 2019 17:28:49 +0200 Received: from dev-r-vrt-215.mtr.labs.mlnx. (dev-r-vrt-215.mtr.labs.mlnx [10.212.215.1]) by labmailer.mlnx (8.13.8/8.13.8) with ESMTP id xAKFSlWN001566; Wed, 20 Nov 2019 17:28:49 +0200 From: Eli Britstein To: dev@openvswitch.org, Ilya Maximets , Ian Stokes Date: Wed, 20 Nov 2019 15:28:23 +0000 Message-Id: <20191120152826.25074-18-elibr@mellanox.com> X-Mailer: git-send-email 2.14.5 In-Reply-To: <20191120152826.25074-1-elibr@mellanox.com> References: <20191120152826.25074-1-elibr@mellanox.com> Cc: Oz Shlomo , Majd Dibbiny , Eli Britstein , Ameer Mahagneh Subject: [ovs-dev] [PATCH 17/20] netdev-offload-dpdk-flow: Support offload of set MAC actions X-BeenThere: ovs-dev@openvswitch.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: ovs-dev-bounces@openvswitch.org Sender: "dev" Signed-off-by: Eli Britstein Reviewed-by: Oz Shlomo --- NEWS | 2 +- lib/netdev-offload-dpdk-flow.c | 122 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 123 insertions(+), 1 deletion(-) diff --git a/NEWS b/NEWS index 08aa6e03b..8c3ffc2c4 100644 --- a/NEWS +++ b/NEWS @@ -11,7 +11,7 @@ Post-v2.12.0 * Add option to enable, disable and query TCP sequence checking in conntrack. - DPDK: - * Add hardware offload support for output and drop actions. + * Add hardware offload support for output, drop and set MAC actions. v2.12.0 - 03 Sep 2019 --------------------- diff --git a/lib/netdev-offload-dpdk-flow.c b/lib/netdev-offload-dpdk-flow.c index a1cf6f129..cf6e91c93 100644 --- a/lib/netdev-offload-dpdk-flow.c +++ b/lib/netdev-offload-dpdk-flow.c @@ -298,6 +298,21 @@ ds_put_flow_action(struct ds *s, const struct rte_flow_action *actions) } } else if (actions->type == RTE_FLOW_ACTION_TYPE_DROP) { ds_put_cstr(s, "rte flow drop action\n"); + } else if (actions->type == RTE_FLOW_ACTION_TYPE_SET_MAC_SRC || + actions->type == RTE_FLOW_ACTION_TYPE_SET_MAC_DST) { + const struct rte_flow_action_set_mac *set_mac = actions->conf; + + char *dirstr = actions->type == RTE_FLOW_ACTION_TYPE_SET_MAC_DST + ? "dst" : "src"; + + ds_put_format(s, "rte flow set-mac-%s action:\n", dirstr); + if (set_mac) { + ds_put_format(s, + " Set-mac-%s: "ETH_ADDR_FMT"\n", + dirstr, ETH_ADDR_BYTES_ARGS(set_mac->mac_addr)); + } else { + ds_put_format(s, " Set-mac-%s = null\n", dirstr); + } } else { ds_put_format(s, "unknown rte flow action (%d)\n", actions->type); } @@ -605,6 +620,103 @@ netdev_dpdk_flow_add_output_action(struct flow_actions *actions, return 0; } +struct set_action_info { + const uint8_t *value, *mask; + const uint8_t size; + uint8_t *spec; + const int attr; +}; + +static int +add_set_flow_action(struct flow_actions *actions, + struct set_action_info *sa_info_arr, + size_t sa_info_arr_size) +{ + int field, i; + + for (field = 0; field < sa_info_arr_size; field++) { + if (sa_info_arr[field].mask) { + /* DPDK does not support partially masked set actions. In such + * case, fail the offload. + */ + if (sa_info_arr[field].mask[0] != 0x00 && + sa_info_arr[field].mask[0] != 0xFF) { + VLOG_DBG_RL(&error_rl, + "Partial mask is not supported"); + return -1; + } + + for (i = 1; i < sa_info_arr[field].size; i++) { + if (sa_info_arr[field].mask[i] != + sa_info_arr[field].mask[i - 1]) { + VLOG_DBG_RL(&error_rl, + "Partial mask is not supported"); + return -1; + } + } + + if (sa_info_arr[field].mask[0] == 0x00) { + /* mask bytes are all 0 - no rewrite action required */ + continue; + } + } + + memcpy(sa_info_arr[field].spec, sa_info_arr[field].value, + sa_info_arr[field].size); + add_flow_action(actions, sa_info_arr[field].attr, + sa_info_arr[field].spec); + } + + return 0; +} + +/* Mask is at the midpoint of the data. */ +#define get_mask(a, type) ((const type *)(const void *)(a + 1) + 1) + +#define SA_INFO(_field, _spec, _attr) { \ + .value = (uint8_t *)&key->_field, \ + .mask = (masked) ? (uint8_t *)&mask->_field : NULL, \ + .size = sizeof key->_field, \ + .spec = (uint8_t *)&_spec, \ + .attr = _attr } + +static int +netdev_dpdk_flow_add_set_actions(struct flow_actions *actions, + const struct nlattr *set_actions, + const size_t set_actions_len, + bool masked) +{ + const struct nlattr *sa; + unsigned int sleft; + + NL_ATTR_FOR_EACH_UNSAFE (sa, sleft, set_actions, set_actions_len) { + if (nl_attr_type(sa) == OVS_KEY_ATTR_ETHERNET) { + const struct ovs_key_ethernet *key = nl_attr_get(sa); + const struct ovs_key_ethernet *mask = masked ? + get_mask(sa, struct ovs_key_ethernet) : NULL; + struct rte_flow_action_set_mac *src = xzalloc(sizeof *src); + struct rte_flow_action_set_mac *dst = xzalloc(sizeof *dst); + struct set_action_info sa_info_arr[] = { + SA_INFO(eth_src, src->mac_addr[0], + RTE_FLOW_ACTION_TYPE_SET_MAC_SRC), + SA_INFO(eth_dst, dst->mac_addr[0], + RTE_FLOW_ACTION_TYPE_SET_MAC_DST), + }; + + if (add_set_flow_action(actions, sa_info_arr, + ARRAY_SIZE(sa_info_arr))) { + return -1; + } + } else { + VLOG_DBG_RL(&error_rl, + "Unsupported set action type=%d", nl_attr_type(sa)); + return -1; + } + } + + return 0; +} + int netdev_dpdk_flow_actions_add(struct flow_actions *actions, struct nlattr *nl_actions, @@ -620,6 +732,16 @@ netdev_dpdk_flow_actions_add(struct flow_actions *actions, if (netdev_dpdk_flow_add_output_action(actions, nla, info )) { return -1; } + } else if (nl_attr_type(nla) == OVS_ACTION_ATTR_SET || + nl_attr_type(nla) == OVS_ACTION_ATTR_SET_MASKED) { + const struct nlattr *set_actions = nl_attr_get(nla); + const size_t set_actions_len = nl_attr_get_size(nla); + bool masked = nl_attr_type(nla) == OVS_ACTION_ATTR_SET_MASKED; + + if (netdev_dpdk_flow_add_set_actions(actions, set_actions, + set_actions_len, masked)) { + return -1; + } } else { VLOG_DBG_RL(&error_rl, "Unsupported action type %d", nl_attr_type(nla)); From patchwork Wed Nov 20 15:28:24 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eli Britstein X-Patchwork-Id: 1198254 X-Patchwork-Delegate: i.maximets@samsung.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=openvswitch.org (client-ip=140.211.166.137; helo=fraxinus.osuosl.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=mellanox.com Received: from fraxinus.osuosl.org (smtp4.osuosl.org [140.211.166.137]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 47J6Gh3hT0z9sR4 for ; Thu, 21 Nov 2019 02:35:56 +1100 (AEDT) Received: from localhost (localhost [127.0.0.1]) by fraxinus.osuosl.org (Postfix) with ESMTP id 4F3AA86DF0; Wed, 20 Nov 2019 15:35:54 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from fraxinus.osuosl.org ([127.0.0.1]) by localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id FI1c4ri8i82l; Wed, 20 Nov 2019 15:35:48 +0000 (UTC) Received: from lists.linuxfoundation.org (lf-lists.osuosl.org [140.211.9.56]) by fraxinus.osuosl.org (Postfix) with ESMTP id 982B586DD3; Wed, 20 Nov 2019 15:35:46 +0000 (UTC) Received: from lf-lists.osuosl.org (localhost [127.0.0.1]) by lists.linuxfoundation.org (Postfix) with ESMTP id 7DE93C1DD8; Wed, 20 Nov 2019 15:35:46 +0000 (UTC) X-Original-To: dev@openvswitch.org Delivered-To: ovs-dev@lists.linuxfoundation.org Received: from hemlock.osuosl.org (smtp2.osuosl.org [140.211.166.133]) by lists.linuxfoundation.org (Postfix) with ESMTP id 03773C1DDD for ; Wed, 20 Nov 2019 15:35:36 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by hemlock.osuosl.org (Postfix) with ESMTP id CB54E885CA for ; Wed, 20 Nov 2019 15:35:35 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from hemlock.osuosl.org ([127.0.0.1]) by localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id uF1YcGQ5wCek for ; Wed, 20 Nov 2019 15:35:34 +0000 (UTC) X-Greylist: from auto-whitelisted by SQLgrey-1.7.6 Received: from mellanox.co.il (mail-il-dmz.mellanox.com [193.47.165.129]) by hemlock.osuosl.org (Postfix) with ESMTP id 1CB04885BA for ; Wed, 20 Nov 2019 15:35:33 +0000 (UTC) Received: from Internal Mail-Server by MTLPINE1 (envelope-from elibr@mellanox.com) with ESMTPS (AES256-SHA encrypted); 20 Nov 2019 17:28:49 +0200 Received: from dev-r-vrt-215.mtr.labs.mlnx. (dev-r-vrt-215.mtr.labs.mlnx [10.212.215.1]) by labmailer.mlnx (8.13.8/8.13.8) with ESMTP id xAKFSlWO001566; Wed, 20 Nov 2019 17:28:49 +0200 From: Eli Britstein To: dev@openvswitch.org, Ilya Maximets , Ian Stokes Date: Wed, 20 Nov 2019 15:28:24 +0000 Message-Id: <20191120152826.25074-19-elibr@mellanox.com> X-Mailer: git-send-email 2.14.5 In-Reply-To: <20191120152826.25074-1-elibr@mellanox.com> References: <20191120152826.25074-1-elibr@mellanox.com> Cc: Oz Shlomo , Majd Dibbiny , Eli Britstein , Ameer Mahagneh Subject: [ovs-dev] [PATCH 18/20] netdev-offload-dpdk-flow: Support offload of set IPv4 actions X-BeenThere: ovs-dev@openvswitch.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: ovs-dev-bounces@openvswitch.org Sender: "dev" Signed-off-by: Eli Britstein Reviewed-by: Oz Shlomo --- NEWS | 3 ++- lib/netdev-offload-dpdk-flow.c | 50 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 52 insertions(+), 1 deletion(-) diff --git a/NEWS b/NEWS index 8c3ffc2c4..2fb3e1357 100644 --- a/NEWS +++ b/NEWS @@ -11,7 +11,8 @@ Post-v2.12.0 * Add option to enable, disable and query TCP sequence checking in conntrack. - DPDK: - * Add hardware offload support for output, drop and set MAC actions. + * Add hardware offload support for output, drop and set actions of + MAC and IPv4. v2.12.0 - 03 Sep 2019 --------------------- diff --git a/lib/netdev-offload-dpdk-flow.c b/lib/netdev-offload-dpdk-flow.c index cf6e91c93..c57548e99 100644 --- a/lib/netdev-offload-dpdk-flow.c +++ b/lib/netdev-offload-dpdk-flow.c @@ -313,6 +313,30 @@ ds_put_flow_action(struct ds *s, const struct rte_flow_action *actions) } else { ds_put_format(s, " Set-mac-%s = null\n", dirstr); } + } else if (actions->type == RTE_FLOW_ACTION_TYPE_SET_IPV4_SRC || + actions->type == RTE_FLOW_ACTION_TYPE_SET_IPV4_DST) { + const struct rte_flow_action_set_ipv4 *set_ipv4 = actions->conf; + char *dirstr = actions->type == RTE_FLOW_ACTION_TYPE_SET_IPV4_DST + ? "dst" : "src"; + + ds_put_format(s, "rte flow set-ipv4-%s action:\n", dirstr); + if (set_ipv4) { + ds_put_format(s, + " Set-ipv4-%s: "IP_FMT"\n", + dirstr, IP_ARGS(set_ipv4->ipv4_addr)); + } else { + ds_put_format(s, " Set-ipv4-%s = null\n", dirstr); + } + } else if (actions->type == RTE_FLOW_ACTION_TYPE_SET_TTL) { + const struct rte_flow_action_set_ttl *set_ttl = actions->conf; + + ds_put_cstr(s, "rte flow set-ttl action:\n"); + if (set_ttl) { + ds_put_format(s, + " Set-ttl: %d\n", set_ttl->ttl_value); + } else { + ds_put_cstr(s, " Set-ttl = null\n"); + } } else { ds_put_format(s, "unknown rte flow action (%d)\n", actions->type); } @@ -703,6 +727,32 @@ netdev_dpdk_flow_add_set_actions(struct flow_actions *actions, RTE_FLOW_ACTION_TYPE_SET_MAC_DST), }; + if (add_set_flow_action(actions, sa_info_arr, + ARRAY_SIZE(sa_info_arr))) { + return -1; + } + } else if (nl_attr_type(sa) == OVS_KEY_ATTR_IPV4) { + const struct ovs_key_ipv4 *key = nl_attr_get(sa); + const struct ovs_key_ipv4 *mask = masked ? + get_mask(sa, struct ovs_key_ipv4) : NULL; + struct rte_flow_action_set_ipv4 *src = xzalloc(sizeof *src); + struct rte_flow_action_set_ipv4 *dst = xzalloc(sizeof *dst); + struct rte_flow_action_set_ttl *ttl = xzalloc(sizeof *ttl); + struct set_action_info sa_info_arr[] = { + SA_INFO(ipv4_src, src->ipv4_addr, + RTE_FLOW_ACTION_TYPE_SET_IPV4_SRC), + SA_INFO(ipv4_dst, dst->ipv4_addr, + RTE_FLOW_ACTION_TYPE_SET_IPV4_DST), + SA_INFO(ipv4_ttl, ttl->ttl_value, + RTE_FLOW_ACTION_TYPE_SET_TTL), + }; + + if (mask && (mask->ipv4_proto || mask->ipv4_tos || + mask->ipv4_frag)) { + VLOG_DBG_RL(&error_rl, "Unsupported IPv4 set action"); + return -1; + } + if (add_set_flow_action(actions, sa_info_arr, ARRAY_SIZE(sa_info_arr))) { return -1; From patchwork Wed Nov 20 15:28:25 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eli Britstein X-Patchwork-Id: 1198248 X-Patchwork-Delegate: i.maximets@samsung.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=openvswitch.org (client-ip=140.211.166.137; helo=fraxinus.osuosl.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=mellanox.com Received: from fraxinus.osuosl.org (smtp4.osuosl.org [140.211.166.137]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 47J6GT4TtXz9sR4 for ; Thu, 21 Nov 2019 02:35:45 +1100 (AEDT) Received: from localhost (localhost [127.0.0.1]) by fraxinus.osuosl.org (Postfix) with ESMTP id 8020986D9B; Wed, 20 Nov 2019 15:35:43 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from fraxinus.osuosl.org ([127.0.0.1]) by localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id 8wH6a1egiqzG; Wed, 20 Nov 2019 15:35:41 +0000 (UTC) Received: from lists.linuxfoundation.org (lf-lists.osuosl.org [140.211.9.56]) by fraxinus.osuosl.org (Postfix) with ESMTP id 7C97F86D16; Wed, 20 Nov 2019 15:35:40 +0000 (UTC) Received: from lf-lists.osuosl.org (localhost [127.0.0.1]) by lists.linuxfoundation.org (Postfix) with ESMTP id 551C7C1DDC; Wed, 20 Nov 2019 15:35:40 +0000 (UTC) X-Original-To: dev@openvswitch.org Delivered-To: ovs-dev@lists.linuxfoundation.org Received: from fraxinus.osuosl.org (smtp4.osuosl.org [140.211.166.137]) by lists.linuxfoundation.org (Postfix) with ESMTP id 82A58C1DE1 for ; Wed, 20 Nov 2019 15:35:35 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by fraxinus.osuosl.org (Postfix) with ESMTP id 7399F86C3E for ; Wed, 20 Nov 2019 15:35:35 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from fraxinus.osuosl.org ([127.0.0.1]) by localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id 3cOBUyF76vVm for ; Wed, 20 Nov 2019 15:35:34 +0000 (UTC) X-Greylist: from auto-whitelisted by SQLgrey-1.7.6 Received: from mellanox.co.il (mail-il-dmz.mellanox.com [193.47.165.129]) by fraxinus.osuosl.org (Postfix) with ESMTP id 1BB8686C67 for ; Wed, 20 Nov 2019 15:35:33 +0000 (UTC) Received: from Internal Mail-Server by MTLPINE1 (envelope-from elibr@mellanox.com) with ESMTPS (AES256-SHA encrypted); 20 Nov 2019 17:28:49 +0200 Received: from dev-r-vrt-215.mtr.labs.mlnx. (dev-r-vrt-215.mtr.labs.mlnx [10.212.215.1]) by labmailer.mlnx (8.13.8/8.13.8) with ESMTP id xAKFSlWP001566; Wed, 20 Nov 2019 17:28:49 +0200 From: Eli Britstein To: dev@openvswitch.org, Ilya Maximets , Ian Stokes Date: Wed, 20 Nov 2019 15:28:25 +0000 Message-Id: <20191120152826.25074-20-elibr@mellanox.com> X-Mailer: git-send-email 2.14.5 In-Reply-To: <20191120152826.25074-1-elibr@mellanox.com> References: <20191120152826.25074-1-elibr@mellanox.com> Cc: Oz Shlomo , Majd Dibbiny , Eli Britstein , Ameer Mahagneh Subject: [ovs-dev] [PATCH 19/20] netdev-offload-dpdk-flow: Support offload of clone tnl_push/output actions X-BeenThere: ovs-dev@openvswitch.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: ovs-dev-bounces@openvswitch.org Sender: "dev" Signed-off-by: Eli Britstein Reviewed-by: Oz Shlomo --- NEWS | 4 +-- lib/netdev-offload-dpdk-flow.c | 60 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 62 insertions(+), 2 deletions(-) diff --git a/NEWS b/NEWS index 2fb3e1357..ef947234d 100644 --- a/NEWS +++ b/NEWS @@ -11,8 +11,8 @@ Post-v2.12.0 * Add option to enable, disable and query TCP sequence checking in conntrack. - DPDK: - * Add hardware offload support for output, drop and set actions of - MAC and IPv4. + * Add hardware offload support for output, drop, set of MAC, IPv4 + and tunnel push-output actions. v2.12.0 - 03 Sep 2019 --------------------- diff --git a/lib/netdev-offload-dpdk-flow.c b/lib/netdev-offload-dpdk-flow.c index c57548e99..b50fee312 100644 --- a/lib/netdev-offload-dpdk-flow.c +++ b/lib/netdev-offload-dpdk-flow.c @@ -337,6 +337,20 @@ ds_put_flow_action(struct ds *s, const struct rte_flow_action *actions) } else { ds_put_cstr(s, " Set-ttl = null\n"); } + } else if (actions->type == RTE_FLOW_ACTION_TYPE_RAW_ENCAP) { + const struct rte_flow_action_raw_encap *raw_encap = actions->conf; + + ds_put_cstr(s, "rte flow raw-encap action:\n"); + if (raw_encap) { + ds_put_format(s, + " Raw-encap: size=%ld\n", + raw_encap->size); + ds_put_format(s, + " Raw-encap: encap=\n"); + ds_put_hex_dump(s, raw_encap->data, raw_encap->size, 0, false); + } else { + ds_put_cstr(s, " Raw-encap = null\n"); + } } else { ds_put_format(s, "unknown rte flow action (%d)\n", actions->type); } @@ -767,6 +781,44 @@ netdev_dpdk_flow_add_set_actions(struct flow_actions *actions, return 0; } +static int +netdev_dpdk_flow_add_clone_actions(struct flow_actions *actions, + const struct nlattr *clone_actions, + const size_t clone_actions_len, + struct offload_info *info) +{ + const struct nlattr *ca; + unsigned int cleft; + + NL_ATTR_FOR_EACH_UNSAFE (ca, cleft, clone_actions, clone_actions_len) { + int clone_type = nl_attr_type(ca); + + if (clone_type == OVS_ACTION_ATTR_TUNNEL_PUSH) { + const struct ovs_action_push_tnl *tnl_push = nl_attr_get(ca); + struct rte_flow_action_raw_encap *raw_encap = + xzalloc(sizeof *raw_encap); + + raw_encap->data = (uint8_t *)tnl_push->header; + raw_encap->preserve = NULL; + raw_encap->size = tnl_push->header_len; + + add_flow_action(actions, RTE_FLOW_ACTION_TYPE_RAW_ENCAP, + raw_encap); + } else if (clone_type == OVS_ACTION_ATTR_OUTPUT && + cleft <= NLA_ALIGN(ca->nla_len)) { + if (netdev_dpdk_flow_add_output_action(actions, ca, info)) { + return -1; + } + } else { + VLOG_DBG_RL(&error_rl, + "Unsupported clone action. clone_type=%d", clone_type); + return -1; + } + } + + return 0; +} + int netdev_dpdk_flow_actions_add(struct flow_actions *actions, struct nlattr *nl_actions, @@ -792,6 +844,14 @@ netdev_dpdk_flow_actions_add(struct flow_actions *actions, set_actions_len, masked)) { return -1; } + } else if (nl_attr_type(nla) == OVS_ACTION_ATTR_CLONE) { + const struct nlattr *clone_actions = nl_attr_get(nla); + size_t clone_actions_len = nl_attr_get_size(nla); + + if (netdev_dpdk_flow_add_clone_actions(actions, clone_actions, + clone_actions_len, info)) { + return -1; + } } else { VLOG_DBG_RL(&error_rl, "Unsupported action type %d", nl_attr_type(nla)); From patchwork Wed Nov 20 15:28:26 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eli Britstein X-Patchwork-Id: 1198256 X-Patchwork-Delegate: i.maximets@samsung.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=openvswitch.org (client-ip=140.211.166.136; helo=silver.osuosl.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=mellanox.com Received: from silver.osuosl.org (smtp3.osuosl.org [140.211.166.136]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 47J6Gq6fGMz9sR4 for ; Thu, 21 Nov 2019 02:36:03 +1100 (AEDT) Received: from localhost (localhost [127.0.0.1]) by silver.osuosl.org (Postfix) with ESMTP id 15AB82635F; Wed, 20 Nov 2019 15:36:02 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from silver.osuosl.org ([127.0.0.1]) by localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id nQVHgcWpAC98; Wed, 20 Nov 2019 15:35:58 +0000 (UTC) Received: from lists.linuxfoundation.org (lf-lists.osuosl.org [140.211.9.56]) by silver.osuosl.org (Postfix) with ESMTP id 33C7224BE8; Wed, 20 Nov 2019 15:35:41 +0000 (UTC) Received: from lf-lists.osuosl.org (localhost [127.0.0.1]) by lists.linuxfoundation.org (Postfix) with ESMTP id 15369C1DE2; Wed, 20 Nov 2019 15:35:41 +0000 (UTC) X-Original-To: dev@openvswitch.org Delivered-To: ovs-dev@lists.linuxfoundation.org Received: from fraxinus.osuosl.org (smtp4.osuosl.org [140.211.166.137]) by lists.linuxfoundation.org (Postfix) with ESMTP id 8839FC1DE2 for ; Wed, 20 Nov 2019 15:35:35 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by fraxinus.osuosl.org (Postfix) with ESMTP id 6D68C86C40 for ; Wed, 20 Nov 2019 15:35:35 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from fraxinus.osuosl.org ([127.0.0.1]) by localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id pauUr1Zb6MhQ for ; Wed, 20 Nov 2019 15:35:34 +0000 (UTC) X-Greylist: from auto-whitelisted by SQLgrey-1.7.6 Received: from mellanox.co.il (mail-il-dmz.mellanox.com [193.47.165.129]) by fraxinus.osuosl.org (Postfix) with ESMTP id 1935E86C3E for ; Wed, 20 Nov 2019 15:35:33 +0000 (UTC) Received: from Internal Mail-Server by MTLPINE1 (envelope-from elibr@mellanox.com) with ESMTPS (AES256-SHA encrypted); 20 Nov 2019 17:28:49 +0200 Received: from dev-r-vrt-215.mtr.labs.mlnx. (dev-r-vrt-215.mtr.labs.mlnx [10.212.215.1]) by labmailer.mlnx (8.13.8/8.13.8) with ESMTP id xAKFSlWQ001566; Wed, 20 Nov 2019 17:28:49 +0200 From: Eli Britstein To: dev@openvswitch.org, Ilya Maximets , Ian Stokes Date: Wed, 20 Nov 2019 15:28:26 +0000 Message-Id: <20191120152826.25074-21-elibr@mellanox.com> X-Mailer: git-send-email 2.14.5 In-Reply-To: <20191120152826.25074-1-elibr@mellanox.com> References: <20191120152826.25074-1-elibr@mellanox.com> Cc: Oz Shlomo , Majd Dibbiny , Eli Britstein , Ameer Mahagneh Subject: [ovs-dev] [PATCH 20/20] netdev-offload-dpdk-flow: Support offload of set TCP/UDP ports actions X-BeenThere: ovs-dev@openvswitch.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: ovs-dev-bounces@openvswitch.org Sender: "dev" Signed-off-by: Eli Britstein Reviewed-by: Oz Shlomo --- NEWS | 4 ++-- lib/netdev-offload-dpdk-flow.c | 48 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 50 insertions(+), 2 deletions(-) diff --git a/NEWS b/NEWS index ef947234d..60f950ace 100644 --- a/NEWS +++ b/NEWS @@ -11,8 +11,8 @@ Post-v2.12.0 * Add option to enable, disable and query TCP sequence checking in conntrack. - DPDK: - * Add hardware offload support for output, drop, set of MAC, IPv4 - and tunnel push-output actions. + * Add hardware offload support for output, drop, set of MAC, IPv4, + TCP/UDP ports and tunnel push-output actions. v2.12.0 - 03 Sep 2019 --------------------- diff --git a/lib/netdev-offload-dpdk-flow.c b/lib/netdev-offload-dpdk-flow.c index b50fee312..958ea5cc2 100644 --- a/lib/netdev-offload-dpdk-flow.c +++ b/lib/netdev-offload-dpdk-flow.c @@ -351,6 +351,20 @@ ds_put_flow_action(struct ds *s, const struct rte_flow_action *actions) } else { ds_put_cstr(s, " Raw-encap = null\n"); } + } else if (actions->type == RTE_FLOW_ACTION_TYPE_SET_TP_SRC || + actions->type == RTE_FLOW_ACTION_TYPE_SET_TP_DST) { + const struct rte_flow_action_set_tp *set_tp = actions->conf; + char *dirstr = actions->type == RTE_FLOW_ACTION_TYPE_SET_TP_DST + ? "dst" : "src"; + + ds_put_format(s, "rte flow set-tcp/udp-port-%s action:\n", dirstr); + if (set_tp) { + ds_put_format(s, + " Set-%s-tcp/udp-port: %"PRIu16"\n", + dirstr, ntohs(set_tp->port)); + } else { + ds_put_format(s, " Set-%s-tcp/udp-port = null\n", dirstr); + } } else { ds_put_format(s, "unknown rte flow action (%d)\n", actions->type); } @@ -767,6 +781,40 @@ netdev_dpdk_flow_add_set_actions(struct flow_actions *actions, return -1; } + if (add_set_flow_action(actions, sa_info_arr, + ARRAY_SIZE(sa_info_arr))) { + return -1; + } + } else if (nl_attr_type(sa) == OVS_KEY_ATTR_TCP) { + const struct ovs_key_tcp *key = nl_attr_get(sa); + const struct ovs_key_tcp *mask = masked ? + get_mask(sa, struct ovs_key_tcp) : NULL; + struct rte_flow_action_set_tp *src = xzalloc(sizeof *src); + struct rte_flow_action_set_tp *dst = xzalloc(sizeof *dst); + struct set_action_info sa_info_arr[] = { + SA_INFO(tcp_src, src->port, + RTE_FLOW_ACTION_TYPE_SET_TP_SRC), + SA_INFO(tcp_dst, dst->port, + RTE_FLOW_ACTION_TYPE_SET_TP_DST), + }; + + if (add_set_flow_action(actions, sa_info_arr, + ARRAY_SIZE(sa_info_arr))) { + return -1; + } + } else if (nl_attr_type(sa) == OVS_KEY_ATTR_UDP) { + const struct ovs_key_udp *key = nl_attr_get(sa); + const struct ovs_key_udp *mask = masked ? + get_mask(sa, struct ovs_key_udp) : NULL; + struct rte_flow_action_set_tp *src = xzalloc(sizeof *src); + struct rte_flow_action_set_tp *dst = xzalloc(sizeof *dst); + struct set_action_info sa_info_arr[] = { + SA_INFO(udp_src, src->port, + RTE_FLOW_ACTION_TYPE_SET_TP_SRC), + SA_INFO(udp_dst, dst->port, + RTE_FLOW_ACTION_TYPE_SET_TP_DST), + }; + if (add_set_flow_action(actions, sa_info_arr, ARRAY_SIZE(sa_info_arr))) { return -1;