From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from EUR02-HE1-obe.outbound.protection.outlook.com (mail-eopbgr10089.outbound.protection.outlook.com [40.107.1.89]) by dpdk.org (Postfix) with ESMTP id 9B5961B689 for ; Sun, 24 Dec 2017 18:30:53 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=Mellanox.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version; bh=/Wc/kxC7ZojePEb23BAr1/4SV5NGmq+zjNBlKBbYHjY=; b=lFry7Zd0ZCTcFCnR/GvAvhjUOdpcwUZzPXLlQcki6A5M8556DQKQ6VVI1U5llIwzG3wWENfkrxcJXmVvlH1MWVsiBlakdrk/oV+5SIXL9D1JykWGKZNXk89+CesNVki9OfMPfWEXumc/89dp42vfg9Y5/oC3Zn+kUF9E880egz0= Received: from VI1PR05MB3149.eurprd05.prod.outlook.com (10.170.237.142) by VI1PR05MB3150.eurprd05.prod.outlook.com (10.170.237.143) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384_P256) id 15.20.345.14; Sun, 24 Dec 2017 17:30:51 +0000 Received: from VI1PR05MB3149.eurprd05.prod.outlook.com ([fe80::355f:857b:fdfd:afd9]) by VI1PR05MB3149.eurprd05.prod.outlook.com ([fe80::355f:857b:fdfd:afd9%13]) with mapi id 15.20.0345.013; Sun, 24 Dec 2017 17:30:51 +0000 From: Shahaf Shuler To: "Doherty, Declan" , "dev@dpdk.org" Thread-Topic: [dpdk-dev] [RFC] tunnel endpoint hw acceleration enablement Thread-Index: AdN6qTnlxEdgGpD8Qpa520sLsCebsACC5V+A Date: Sun, 24 Dec 2017 17:30:51 +0000 Message-ID: References: <345C63BAECC1AD42A2EC8C63AFFC3ADCC488E501@IRSMSX102.ger.corp.intel.com> In-Reply-To: <345C63BAECC1AD42A2EC8C63AFFC3ADCC488E501@IRSMSX102.ger.corp.intel.com> Accept-Language: en-US Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: authentication-results: spf=none (sender IP is ) smtp.mailfrom=shahafs@mellanox.com; x-originating-ip: [31.154.10.107] x-ms-publictraffictype: Email x-microsoft-exchange-diagnostics: 1; VI1PR05MB3150; 6:7T9j20zKlbh6v69BgKeq6K/vjP2UuP6zDqoyNgqKodJZ5NAjQE1kfd5Pe3D5wJBdzS9kAlBPo94aFojszCBa/7g4jaRYm/GFkDK/EQbvcK8FXscizlYEiOJ/MbxwyWG6XqmyJ/CzaxasgevjXZzh7ncHtw05Kb3vyVqBIeHq7sbdELmp998jbsi448S2rhZPFpeVRSIzd+33H3jNQgHqvA+dl9ZjH/d/FqXvk+afckZgx/OLMnpsWitd/CqH95W3P86OQfDgW5X2kkjkz8EGnz1yzOMwr8dV14b+T5WMMeOirXXZasuJspL84jnvFfXUBAi8r62IK3eDrw8i8U/dWY2ngfmu2MzDZuXj5ALfgwvRnFT8AUwWbGix8UF6JeaG; 5:w9OzgMlheyRrsIlfaRKU8yG3k0RtCQ9uu65bQHdCnLgxH9/JzZ45CXCJHhIKUdfTdaQgY7FAjluzyHYrOdVAzi6eeBjJOW57BB4MaqkD/U1+6Jj+t3HTjD3iy8cLsl7wUoAzN3i+UPEAHdTviwWaRVWjKL0nhtuU8suZoQdHiUk=; 24:yimY4aLzPzkVX71OidA/Mq4pttDsJwv0X3h/ggkiIe1gWZYRnfSzus4olTALiH/VLKyz/4x6e18/4+DL2nSCsZv5nROuDXyK9WrNcbbS0HU=; 7:p6qjEXuCruiFI1eA72qmzNWMypbZCGQbKwXMRh0iYXyvxOXLnuib8gZnH0ylu3zoCjt35E/a9GiQj1kvOQdSpt4ASSfNlLJOFhXUU6ywbyMBHX0cBGwzqshpXdsCgiFp6yz6bgW2jLhJfzg+a2LBRen79sgYEcdkMtp8qUEIagHQo3KEO8c6d5YHPUFkyiwWuerPW5522lSg+FDBFvcnLctaMnKvErsMV3/Aluadpb/ekAA3iAodmgMZpLlPb7Z1 x-ms-exchange-antispam-srfa-diagnostics: SSOS; x-ms-office365-filtering-correlation-id: ff6bd66b-00f9-4ef7-9c44-08d54af41423 x-ms-office365-filtering-ht: Tenant x-microsoft-antispam: UriScan:; BCL:0; PCL:0; RULEID:(4534020)(4602075)(4627115)(201703031133081)(201702281549075)(5600026)(4604075)(3008032)(48565401081)(2017052603307)(7153060); SRVR:VI1PR05MB3150; x-ms-traffictypediagnostic: VI1PR05MB3150: x-microsoft-antispam-prvs: x-exchange-antispam-report-test: UriScan:(72170088055959)(192374486261705)(131327999870524); x-exchange-antispam-report-cfa-test: BCL:0; PCL:0; RULEID:(6040470)(2401047)(5005006)(8121501046)(10201501046)(3231023)(944501075)(93006095)(93001095)(3002001)(6055026)(6041268)(20161123562045)(201703131423095)(201702281528075)(20161123555045)(201703061421075)(201703061406153)(20161123560045)(20161123564045)(20161123558120)(6072148)(201708071742011); SRVR:VI1PR05MB3150; BCL:0; PCL:0; RULEID:(100000803101)(100110400095); SRVR:VI1PR05MB3150; x-forefront-prvs: 05315CBE52 x-forefront-antispam-report: SFV:NSPM; SFS:(10009020)(376002)(39860400002)(39380400002)(346002)(366004)(396003)(199004)(189003)(51234002)(33656002)(6506007)(561944003)(59450400001)(6436002)(99286004)(7696005)(55016002)(8936002)(76176011)(81166006)(9686003)(68736007)(3846002)(6116002)(229853002)(316002)(110136005)(6246003)(81156014)(102836004)(8676002)(5250100002)(2501003)(53946003)(53936002)(2906002)(25786009)(2900100001)(3660700001)(3280700002)(2950100002)(5660300001)(86362001)(478600001)(97736004)(14454004)(7736002)(305945005)(66066001)(106356001)(74316002)(105586002); DIR:OUT; SFP:1101; SCL:1; SRVR:VI1PR05MB3150; H:VI1PR05MB3149.eurprd05.prod.outlook.com; FPR:; SPF:None; PTR:InfoNoRecords; A:1; MX:1; LANG:en; received-spf: None (protection.outlook.com: mellanox.com does not designate permitted sender hosts) x-microsoft-antispam-message-info: J6a4CyY83IGfof3voGs+abqZchypHlqGT7cxwftjh6l5c9f3/Gr6twOw6wKX9W0YCC9Wv4PGz9jjwPMHfZIwvQ== spamdiagnosticoutput: 1:99 spamdiagnosticmetadata: NSPM Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 X-OriginatorOrg: Mellanox.com X-MS-Exchange-CrossTenant-Network-Message-Id: ff6bd66b-00f9-4ef7-9c44-08d54af41423 X-MS-Exchange-CrossTenant-originalarrivaltime: 24 Dec 2017 17:30:51.1428 (UTC) X-MS-Exchange-CrossTenant-fromentityheader: Hosted X-MS-Exchange-CrossTenant-id: a652971c-7d2e-4d9b-a6a4-d149256f461b X-MS-Exchange-Transport-CrossTenantHeadersStamped: VI1PR05MB3150 Subject: Re: [dpdk-dev] [RFC] tunnel endpoint hw acceleration enablement X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 24 Dec 2017 17:30:54 -0000 Hi Declan, Friday, December 22, 2017 12:21 AM, Doherty, Declan: > This RFC contains a proposal to add a new tunnel endpoint API to DPDK tha= t > when used in conjunction with rte_flow enables the configuration of inlin= e > data path encapsulation and decapsulation of tunnel endpoint network > overlays on accelerated IO devices. >=20 > The proposed new API would provide for the creation, destruction, and > monitoring of a tunnel endpoint in supporting hw, as well as capabilities= APIs > to allow the acceleration features to be discovered by applications. >=20 > /** Tunnel Endpoint context, opaque structure */ struct rte_tep; >=20 > enum rte_tep_type { > RTE_TEP_TYPE_VXLAN =3D 1, /**< VXLAN Protocol */ > RTE_TEP_TYPE_NVGRE, /**< NVGRE Protocol */ > ... > }; >=20 > /** Tunnel Endpoint Attributes */ > struct rte_tep_attr { > enum rte_type_type type; >=20 > /* other endpoint attributes here */ } >=20 > /** > * Create a tunnel end-point context as specified by the flow attribute an= d > pattern > * > * @param port_id Port identifier of Ethernet device. > * @param attr Flow rule attributes. > * @param pattern Pattern specification by list of rte_flow_items. > * @return > * - On success returns pointer to TEP context > * - On failure returns NULL > */ > struct rte_tep *rte_tep_create(uint16_t port_id, > struct rte_tep_attr *attr, struct rte_flow_= item pattern[]) >=20 > /** > * Destroy an existing tunnel end-point context. All the end-points contex= t > * will be destroyed, so all active flows using tep should be freed before > * destroying context. > * @param port_id Port identifier of Ethernet device. > * @param tep Tunnel endpoint context > * @return > * - On success returns 0 > * - On failure returns 1 > */ > int rte_tep_destroy(uint16_t port_id, struct rte_tep *tep) >=20 > /** > * Get tunnel endpoint statistics > * > * @param port_id Port identifier of Ethernet device. > * @param tep Tunnel endpoint context > * @param stats Tunnel endpoint statistics > * > * @return > * - On success returns 0 > * - On failure returns 1 > */ > Int > rte_tep_stats_get(uint16_t port_id, struct rte_tep *tep, > struct rte_tep_stats *stats) >=20 > /** > * Get ports tunnel endpoint capabilities > * > * @param port_id Port identifier of Ethernet device. > * @param capabilities Tunnel endpoint capabilities > * > * @return > * - On success returns 0 > * - On failure returns 1 > */ > int > rte_tep_capabilities_get(uint16_t port_id, > struct rte_tep_capabilities *capabilities) Am not sure I understand why there is a need for the above control methods.= =20 Are you introducing a new "tep device" ?=20 As the tunnel endpoint is sending and receiving Ethernet packets from the n= etwork I think it should still be counted as Ethernet device but with more = capabilities (for example it supported encap/decap etc..), therefore it sho= uld use the Ethdev layer API to query statistics (for example).=20 As for the capabilities - what specifically you had in mind? The current us= age you show with tep is with rte_flow rules. There are no capabilities cur= rently for rte_flow supported actions/pattern. To check such capabilities a= pplication uses rte_flow_validate.=20 Regarding the creation/destroy of tep. Why not simply use rte_flow API and = avoid this extra control?=20 For example - with 17.11 APIs, application can put the port in isolate mode= , and insert a flow_rule to catch only IPv4 VXLAN traffic and direct to som= e queue/do RSS. Such operation, per my understanding, will create a tunnel = endpoint. What are the down sides of doing it with the current APIs?=20 >=20 >=20 > To direct traffic flows to hw terminated tunnel endpoint the rte_flow API= is > enhanced to add a new flow item type. This contains a pointer to the TEP > context as well as the overlay flow id to which the traffic flow is assoc= iated. >=20 > struct rte_flow_item_tep { > struct rte_tep *tep; > uint32_t flow_id; > } Can you provide more detailed definition about the flow id ? to which field= from the packet headers it refers to?=20 On your below examples it looks like it is to match the VXLAN vni in case o= f VXLAN, what about the other protocols? And also, why not using the alread= y exists VXLAN item?=20 Generally I like the idea of separating the encap/decap context from the ac= tion. However looks like the rte_flow_item has double meaning on this RFC, = once for the classification and once for the action. >>From the top of my head I would think of an API which separate those, and r= e-use the existing flow items. Something like: struct rte_flow_item pattern[] =3D { { set of already exists pattern }, { ... }, { .type =3D RTE_FLOW_ITEM_TYPE_END } }; encap_ctx =3D create_enacap_context(pattern) rte_flow_action actions[] =3D { { .type RTE_FLOW_ITEM_ENCAP, .conf =3D encap_ctx} } =20 > Also 2 new generic actions types are added encapsulation and decapsulatio= n. >=20 > RTE_FLOW_ACTION_TYPE_ENCAP > RTE_FLOW_ACTION_TYPE_DECAP >=20 > struct rte_flow_action_encap { > struct rte_flow_item *item; } >=20 > struct rte_flow_action_decap { > struct rte_flow_item *item; } >=20 > The following section outlines the intended usage of the new APIs and the= n > how they are combined with the existing rte_flow APIs. >=20 > Tunnel endpoints are created on logical ports which support the capabilit= y > using rte_tep_create() using a combination of TEP attributes and > rte_flow_items. In the example below a new IPv4 VxLAN endpoint is being > defined. > The attrs parameter sets the TEP type, and could be used for other possib= le > attributes. >=20 > struct rte_tep_attr attrs =3D { .type =3D RTE_TEP_TYPE_VXLAN }; >=20 > The values for the headers which make up the tunnel endpointr are then > defined using spec parameter in the rte flow items (IPv4, UDP and VxLAN i= n > this case) >=20 > struct rte_flow_item_ipv4 ipv4_item =3D { > .hdr =3D { .src_addr =3D saddr, .dst_addr =3D daddr } }; >=20 > struct rte_flow_item_udp udp_item =3D { > .hdr =3D { .src_port =3D sport, .dst_port =3D dport } }; >=20 > struct rte_flow_item_vxlan vxlan_item =3D { .flags =3D vxlan_flags }; >=20 > struct rte_flow_item pattern[] =3D { > { .type =3D RTE_FLOW_ITEM_TYPE_IPV4, .spec =3D &ipv4_item = }, > { .type =3D RTE_FLOW_ITEM_TYPE_UDP, .spec =3D &udp_item }, > { .type =3D RTE_FLOW_ITEM_TYPE_VXLAN, .spec =3D &vxlan_ite= m }, > { .type =3D RTE_FLOW_ITEM_TYPE_END } }; >=20 > The tunnel endpoint can then be create on the port. Whether or not any hw > configuration is required at this point would be hw dependent, but if not= the > context for the TEP is available for use in programming flow, so the > application is not forced to redefine the TEP parameters on each flow > addition. >=20 > struct rte_tep *tep =3D rte_tep_create(port_id, &attrs, pattern); >=20 > Once the tep context is created flows can then be directed to that endpoi= nt > for processing. The following sections will outline how the author envisa= ge > flow programming will work and also how TEP acceleration can be combined > with other accelerations. >=20 >=20 > Ingress TEP decapsulation, mark and forward to queue: > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ >=20 > The flows definition for TEP decapsulation actions should specify the ful= l > outer packet to be matched at a minimum. The outer packet definition > should match the tunnel definition in the tep context and the tep flow id= . > This example shows describes matching on the outer, marking the packet > with the VXLAN VNI and directing to a specified queue of the port. >=20 > Source Packet >=20 > Decapsulate Outer Hdr > / \ decap o= uter crc > / \ / = \ > +-----+------+-----+-------+-----+------+-----+---------+-----+------= -----+ > | ETH | IPv4 | UDP | VxLAN | ETH | IPv4 | TCP | PAYLOAD | CRC | OUTER > CRC | > +-----+------+-----+-------+-----+------+-----+---------+-----+------= -----+ >=20 > /* Flow Attributes/Items Definitions */ >=20 > struct rte_flow_attr attr =3D { .ingress =3D 1 }; >=20 > struct rte_flow_item_eth eth_item =3D { .src =3D s_addr, .dst =3D d_addr,= .type =3D > ether_type }; struct rte_flow_item_tep tep_item =3D { .tep =3D tep, .id = =3D vni }; >=20 > struct rte_flow_item pattern[] =3D { > { .type =3D RTE_FLOW_ITEM_TYPE_ETH, .spec =3D ð_item }, > { .type =3D RTE_FLOW_ITEM_TYPE_TEP, .spec =3D &tep_item }= , > { .type =3D RTE_FLOW_ITEM_TYPE_END } }; >=20 > /* Flow Actions Definitions */ >=20 > struct rte_flow_action_decap decap_eth =3D { > .type =3D RTE_FLOW_ITEM_TYPE_ETH, > .item =3D { .src =3D s_addr, .dst =3D d_addr, .type =3D et= her_type } }; >=20 > struct rte_flow_action_decap decap_tep =3D { > .type =3D RTE_FLOW_ITEM_TYPE_TEP, .spec =3D &tep_item }; >=20 > struct rte_flow_action_queue queue_action =3D { .index =3D qid }; >=20 > struct rte_flow_action_port mark_action =3D { .index =3D vni }; >=20 > struct rte_flow_action actions[] =3D { > { .type =3D RTE_FLOW_ACTION_TYPE_DECAP, .conf =3D &decap_e= th }, > { .type =3D RTE_FLOW_ACTION_TYPE_DECAP, .conf =3D &decap_t= ep }, > { .type =3D RTE_FLOW_ACTION_TYPE_MARK, .conf =3D &mark_act= ion }, > { .type =3D RTE_FLOW_ACTION_TYPE_QUEUE, .conf =3D &queue_a= ction }, > { .type =3D RTE_FLOW_ACTION_TYPE_END } }; >=20 > /** VERY IMPORTANT NOTE **/ > One of the core concepts of this proposal is that actions which modify th= e > packet are defined in the order which they are to be processed. So first > decap outer ethernet header, then the outer TEP headers. > I think this is not only logical from a usability point of view, it shoul= d also > simplify the logic required in PMDs to parse the desired actions. >=20 > struct rte_flow *flow =3D > rte_flow_create(port_id, &attr, pattern, ac= tions, &err); >=20 > The processed packets are delivered to specifed queue with mbuf metadata > denoting marked flow id and with mbuf ol_flags PKT_RX_TEP_OFFLOAD set. >=20 > +-----+------+-----+---------+-----+ > | ETH | IPv4 | TCP | PAYLOAD | CRC | > +-----+------+-----+---------+-----+ >=20 >=20 > Ingress TEP decapsulation switch to port: > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ >=20 > This is intended to represent how a TEP decapsulation could be configured= in > a switching offload case, it makes an assumption that there is a logical = port > representation for all ports on the hw switch in the DPDK application, bu= t > similar functionality could be achieved by specifying something like a VF= ID of > the device. >=20 > Like the previous scenario the flows definition for TEP decapsulation act= ions > should specify the full outer packet to be matched at a minimum but also > define the elements of the inner match to match against including masks i= f > required. >=20 > struct rte_flow_attr attr =3D { .ingress =3D 1 }; >=20 > struct rte_flow_item pattern[] =3D { > { .type =3D RTE_FLOW_ITEM_TYPE_ETH, .spec =3D &outer_eth_i= tem }, > { .type =3D RTE_FLOW_ITEM_TYPE_TEP, .spec =3D &outer_tep_i= tem, > .mask =3D &tep_mask }, > { .type =3D RTE_FLOW_ITEM_TYPE_ETH, .spec =3D &inner_eth_i= tem, > .mask =3D ð_mask } > { .type =3D RTE_FLOW_ITEM_TYPE_IPv4, .spec =3D &inner_ipv4= _item, > .mask =3D &ipv4_mask }, > { .type =3D RTE_FLOW_ITEM_TYPE_TCP, .spec =3D &inner_tcp_i= tem, > .mask =3D &tcp_mask }, > { .type =3D RTE_FLOW_ITEM_TYPE_END } }; >=20 > /* Flow Actions Definitions */ >=20 > struct rte_flow_action_decap decap_eth =3D { > .type =3D RTE_FLOW_ITEM_TYPE_ETH, > .item =3D { .src =3D s_addr, .dst =3D d_addr, .type =3D et= her_type } }; >=20 > struct rte_flow_action_decap decap_tep =3D { > .type =3D RTE_FLOW_ITEM_TYPE_TEP, > .item =3D &outer_tep_item > }; >=20 > struct rte_flow_action_port port_action =3D { .index =3D port_id }; >=20 > struct rte_flow_action actions[] =3D { > { .type =3D RTE_FLOW_ACTION_TYPE_DECAP, .conf =3D &decap_e= th }, > { .type =3D RTE_FLOW_ACTION_TYPE_DECAP, .conf =3D &decap_t= ep }, > { .type =3D RTE_FLOW_ACTION_TYPE_PORT, .conf =3D &port_act= ion }, > { .type =3D RTE_FLOW_ACTION_TYPE_END } }; >=20 > struct rte_flow *flow =3D rte_flow_create(port_id, &attr, pattern, action= s, > &err); >=20 > This action will forward the decapsulated packets to another port of the > switch fabric but no information will on the tunnel or the fact that the = packet > was decapsulated will be passed with it, thereby enable segregation of th= e > infrastructure and >=20 >=20 > Egress TEP encapsulation: > ~~~~~~~~~~~~~~~~~~~~~~~~~ >=20 > Encapulsation TEP actions require the flow definitions for the source pac= ket > and then the actions to do on that, this example shows a ipv4/tcp packet > action. >=20 > Source Packet >=20 > +-----+------+-----+---------+-----+ > | ETH | IPv4 | TCP | PAYLOAD | CRC | > +-----+------+-----+---------+-----+ >=20 > struct rte_flow_attr attr =3D { .egress =3D 1 }; >=20 > struct rte_flow_item_eth eth_item =3D { .src =3D s_addr, .dst =3D d_addr,= .type =3D > ether_type }; struct rte_flow_item_ipv4 ipv4_item =3D { .hdr =3D { .src_a= ddr =3D > src_addr, .dst_addr =3D dst_addr } }; struct rte_flow_item_udp tcp_item = =3D { > .hdr =3D { .src_port =3D src_port, .dst_port =3D dst_port } }; >=20 > struct rte_flow_item pattern[] =3D { > { .type =3D RTE_FLOW_ITEM_TYPE_ETH, .spec =3D ð_item }, > { .type =3D RTE_FLOW_ITEM_TYPE_IPV4, .spec =3D &ipv4_item = }, > { .type =3D RTE_FLOW_ITEM_TYPE_TCP, .spec =3D &tcp_item }, > { .type =3D RTE_FLOW_ITEM_TYPE_END } }; >=20 > /* Flow Actions Definitions */ >=20 > struct rte_flow_action_encap encap_eth =3D { > .type =3D RTE_FLOW_ITEM_TYPE_ETH, > .item =3D { .src =3D s_addr, .dst =3D d_addr, .type =3D et= her_type } }; >=20 > struct rte_flow_action_encap encap_tep =3D { > .type =3D RTE_FLOW_ITEM_TYPE_TEP, > .item =3D { .tep =3D tep, .id =3D vni } }; struct rte_flow= _action_mark > port_action =3D { .index =3D port_id }; >=20 > struct rte_flow_action actions[] =3D { > { .type =3D RTE_FLOW_ACTION_TYPE_ENCAP, .conf =3D &encap_t= ep }, > { .type =3D RTE_FLOW_ACTION_TYPE_ENCAP, .conf =3D &encap_e= th }, > { .type =3D RTE_FLOW_ACTION_TYPE_PORT, .conf =3D &port_act= ion }, > { .type =3D RTE_FLOW_ACTION_TYPE_END } } struct rte_flow *= flow =3D > rte_flow_create(port_id, &attr, pattern, actions, &err); >=20 >=20 > encapsulating Outer Hdr > / \ outer= crc > / \ / = \ > +-----+------+-----+-------+-----+------+-----+---------+-----+------= -----+ > | ETH | IPv4 | UDP | VxLAN | ETH | IPv4 | TCP | PAYLOAD | CRC | OUTER > CRC | > +-----+------+-----+-------+-----+------+-----+---------+-----+------= -----+ >=20 >=20 >=20 > Chaining multiple modification actions eg IPsec and TEP > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ >=20 > For example the definition for full hw acceleration for an IPsec ESP/Tran= sport > SA encapsulated in a vxlan tunnel would look something like: >=20 > struct rte_flow_action actions[] =3D { > { .type =3D RTE_FLOW_ACTION_TYPE_ENCAP, .conf =3D &encap_t= ep }, > { .type =3D RTE_FLOW_ACTION_TYPE_SECURITY, .conf =3D &sec_= session > }, > { .type =3D RTE_FLOW_ACTION_TYPE_ENCAP, .conf =3D &encap_e= th }, > { .type =3D RTE_FLOW_ACTION_TYPE_END } } >=20 > 1. Source Packet > +-----+------+-----+---------+-----+ > | ETH | IPv4 | TCP | PAYLOAD | CRC | > +-----+------+-----+---------+-----+ >=20 > 2. First Action - Tunnel Endpoint Encapsulation >=20 > +------+-----+-------+-----+------+-----+---------+-----+ > | IPv4 | UDP | VxLAN | ETH | IPv4 | TCP | PAYLOAD | CRC | > +------+-----+-------+-----+------+-----+---------+-----+ >=20 > 3. Second Action - IPsec ESP/Transport Security Processing >=20 > +------+-----+-----+-------+-----+------+-----+---------+-----+----= ---------+ > | IPv4 | ESP | ENCRYPTED PAYLOAD | ESP= TRAILER | > +------+-----+-----+-------+-----+------+-----+---------+-----+----= ---------+ >=20 > 4. Third Action - Outer Ethernet Encapsulation >=20 > +-----+------+-----+-----+-------+-----+------+-----+---------+-----+----= ---------+--- > --------+ > | ETH | IPv4 | ESP | ENCRYPTED PAYLOAD | ESP= TRAILER | > OUTER CRC | > +-----+------+-----+-----+-------+-----+------+-----+---------+-----+----= ---------+--- > --------+ >=20 > This example demonstrates the importance of making the interoperation of > actions to be ordered, as in the above example, a security action can be > defined on both the inner and outer packet by simply placing another > security action at the beginning of the action list. >=20 > It also demonstrates the rationale for not collapsing the Ethernet into t= he TEP > definition as when you have multiple encapsulating actions, all could > potentially be the place where the Ethernet header needs to be defined. >=20