From patchwork Tue May 17 15:23:03 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paul Boca X-Patchwork-Id: 623175 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from archives.nicira.com (archives.nicira.com [96.126.127.54]) by ozlabs.org (Postfix) with ESMTP id 3r8LjF565jz9t6K for ; Wed, 18 May 2016 01:24:33 +1000 (AEST) Received: from archives.nicira.com (localhost [127.0.0.1]) by archives.nicira.com (Postfix) with ESMTP id B157010882; Tue, 17 May 2016 08:24:26 -0700 (PDT) X-Original-To: dev@openvswitch.org Delivered-To: dev@openvswitch.org Received: from mx3v3.cudamail.com (mx3.cudamail.com [64.34.241.5]) by archives.nicira.com (Postfix) with ESMTPS id 4D45B10712 for ; Tue, 17 May 2016 08:24:25 -0700 (PDT) Received: from bar6.cudamail.com (localhost [127.0.0.1]) by mx3v3.cudamail.com (Postfix) with ESMTPS id DB52E1625CC for ; Tue, 17 May 2016 09:24:24 -0600 (MDT) X-ASG-Debug-ID: 1463498663-0b32374e9109820001-byXFYA Received: from mx1-pf2.cudamail.com ([192.168.24.2]) by bar6.cudamail.com with ESMTP id ZEqYGjk0DYmxmlzM (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO) for ; Tue, 17 May 2016 09:24:24 -0600 (MDT) X-Barracuda-Envelope-From: pboca@cloudbasesolutions.com X-Barracuda-RBL-Trusted-Forwarder: 192.168.24.2 Received: from unknown (HELO cbssmtp1.cloudbase.local) (91.232.152.5) by mx1-pf2.cudamail.com with SMTP; 17 May 2016 15:24:23 -0000 Received-SPF: pass (mx1-pf2.cudamail.com: SPF record at cloudbasesolutions.com designates 91.232.152.5 as permitted sender) X-Barracuda-Apparent-Source-IP: 91.232.152.5 X-Barracuda-RBL-IP: 91.232.152.5 Received: from localhost (localhost [127.0.0.1]) by cbssmtp1.cloudbase.local (Postfix) with ESMTP id 52FBD42142 for ; Tue, 17 May 2016 18:24:22 +0300 (EEST) X-Virus-Scanned: amavisd-new at cloudbasesolutions.com Received: from cbssmtp1.cloudbase.local ([127.0.0.1]) by localhost (cbssmtp1.cloudbase.local [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id J_GPMccwFYBF for ; Tue, 17 May 2016 18:24:01 +0300 (EEST) Received: from CBSEX1.cloudbase.local (unknown [10.77.78.3]) by cbssmtp1.cloudbase.local (Postfix) with ESMTP id 0C918426E2 for ; Tue, 17 May 2016 18:23:04 +0300 (EEST) Received: from CBSEX1.cloudbase.local ([10.77.78.3]) by CBSEX1.cloudbase.local ([10.77.78.3]) with mapi id 14.03.0224.002; Tue, 17 May 2016 17:23:03 +0200 X-CudaMail-Envelope-Sender: pboca@cloudbasesolutions.com From: Paul Boca To: "dev@openvswitch.org" X-CudaMail-MID: CM-E2-516037841 X-CudaMail-DTE: 051716 X-CudaMail-Originating-IP: 91.232.152.5 Thread-Topic: [PATCH 4/4] datapath-windows: Add ECN support on STT decapsulation X-ASG-Orig-Subj: [##CM-E2-516037841##][PATCH 4/4] datapath-windows: Add ECN support on STT decapsulation Thread-Index: AQHRsFABqKb7y0oJPkmWysILgcQ4dg== Date: Tue, 17 May 2016 15:23:03 +0000 Message-ID: <1463498579-13060-5-git-send-email-pboca@cloudbasesolutions.com> References: <1463498579-13060-1-git-send-email-pboca@cloudbasesolutions.com> In-Reply-To: <1463498579-13060-1-git-send-email-pboca@cloudbasesolutions.com> Accept-Language: en-US, it-IT Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: x-originating-ip: [10.77.78.1] MIME-Version: 1.0 X-GBUdb-Analysis: 0, 91.232.152.5, Ugly c=0.313739 p=-0.428571 Source Normal X-MessageSniffer-Rules: 0-0-0-15602-c X-Barracuda-Connect: UNKNOWN[192.168.24.2] X-Barracuda-Start-Time: 1463498663 X-Barracuda-Encrypted: DHE-RSA-AES256-SHA X-Barracuda-URL: https://web.cudamail.com:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at cudamail.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.10 X-Barracuda-Spam-Status: No, SCORE=0.10 using global scores of TAG_LEVEL=3.5 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=4.0 tests=RDNS_NONE X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.29657 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.10 RDNS_NONE Delivered to trusted network by a host with no rDNS Subject: [ovs-dev] [PATCH 4/4] datapath-windows: Add ECN support on STT decapsulation X-BeenThere: dev@openvswitch.org X-Mailman-Version: 2.1.16 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@openvswitch.org Sender: "dev" Signed-off-by: Paul-Daniel Boca --- datapath-windows/ovsext/NetProto.h | 10 ++++- datapath-windows/ovsext/PacketParser.h | 67 ++++++++++++++++++++++++++++++++++ datapath-windows/ovsext/Stt.c | 45 +++++++++++++++++++++++ datapath-windows/ovsext/Stt.h | 1 + 4 files changed, 122 insertions(+), 1 deletion(-) diff --git a/datapath-windows/ovsext/NetProto.h b/datapath-windows/ovsext/NetProto.h index f7527f8..6cf6d8e 100644 --- a/datapath-windows/ovsext/NetProto.h +++ b/datapath-windows/ovsext/NetProto.h @@ -45,6 +45,8 @@ typedef struct EthHdr { #define ICMP_CSUM_OFFSET 2 #define INET_CSUM_LENGTH (sizeof(UINT16)) +#define PACKET_MAX_LENGTH 64*1024 // 64K + #define IP4_UNITS_TO_BYTES(x) ((x) << 2) #define IP4_BYTES_TO_UNITS(x) ((x) >> 2) @@ -245,7 +247,13 @@ typedef union _OVS_PACKET_HDR_INFO { typedef struct IPHdr { UINT8 ihl:4, version:4; - UINT8 tos; + union { + struct { + UINT8 ecn:2, + dscp:6; + }; + UINT8 tos; + }; UINT16 tot_len; UINT16 id; UINT16 frag_off; diff --git a/datapath-windows/ovsext/PacketParser.h b/datapath-windows/ovsext/PacketParser.h index f1d7f28..a72b7dc 100644 --- a/datapath-windows/ovsext/PacketParser.h +++ b/datapath-windows/ovsext/PacketParser.h @@ -99,6 +99,73 @@ OvsGetArp(const NET_BUFFER_LIST *packet, return OvsGetPacketBytes(packet, sizeof *storage, ofs, storage); } +/* +* Returns the start of NBL and computes the total length of Ethernet header +* Also returns the type of L3 header +*/ +static const PVOID +OvsGetEthHeader(const NET_BUFFER_LIST *packet, + UINT16 *length, + UINT16 *dlType, + Eth_Header *storage) +{ + UINT8 offset = 0; + PVOID vlanTagValue; + PUINT8 buffStart = NULL; + + const Eth_Header *eth = OvsGetPacketBytes(packet, ETH_MAX_HEADER_LEN, + 0, storage); + if (eth == NULL) { + return NULL; + } + + /* Keep a copy of packet start */ + buffStart = (PUINT8)eth; + + /* + * vlan_tci. + */ + vlanTagValue = NET_BUFFER_LIST_INFO(packet, Ieee8021QNetBufferListInfo); + if (!vlanTagValue) { + if (eth->dix.typeNBO == ETH_TYPE_802_1PQ_NBO) { + offset = sizeof(Eth_802_1pq_Tag); + } + + /* + * XXX Please note after this point, src mac and dst mac should + * not be accessed through eth + */ + eth = (Eth_Header *)((UINT8 *)eth + offset); + } + + /* + * dl_type. + * + * XXX assume that at least the first + * 12 bytes of received packets are mapped. This code has the stronger + * assumption that at least the first 22 bytes of 'packet' is mapped (if my + * arithmetic is right). + */ + if (ETH_TYPENOT8023(eth->dix.typeNBO)) { + *dlType = eth->dix.typeNBO; + *length = ETH_HEADER_LEN_DIX + offset; + } else if (OvsPacketLenNBL(packet) >= ETH_HEADER_LEN_802_3 && + eth->e802_3.llc.dsap == 0xaa && + eth->e802_3.llc.ssap == 0xaa && + eth->e802_3.llc.control == ETH_LLC_CONTROL_UFRAME && + eth->e802_3.snap.snapOrg[0] == 0x00 && + eth->e802_3.snap.snapOrg[1] == 0x00 && + eth->e802_3.snap.snapOrg[2] == 0x00) { + *dlType = eth->e802_3.snap.snapType.typeNBO; + *length = ETH_HEADER_LEN_802_3 + offset; + } else { + *dlType = htons(OVSWIN_DL_TYPE_NONE); + *length = ETH_HEADER_LEN_DIX + offset; + } + + return (UINT8*)eth; +} + static const IPHdr * OvsGetIp(const NET_BUFFER_LIST *packet, UINT32 ofs, diff --git a/datapath-windows/ovsext/Stt.c b/datapath-windows/ovsext/Stt.c index 8a1b1a9..a9e1cac 100644 --- a/datapath-windows/ovsext/Stt.c +++ b/datapath-windows/ovsext/Stt.c @@ -642,6 +642,9 @@ OvsSttReassemble(POVS_SWITCH_CONTEXT switchContext, NdisMoveMemory(&entry->ovsPktKey, &pktKey, sizeof (OVS_STT_PKT_KEY)); entry->recvdLen = fragmentLength; + if (ipHdr->ecn == IP_ECN_CE) { + entry->ecn = IP_ECN_CE; + } UINT64 currentTime; NdisGetCurrentSystemTime((LARGE_INTEGER *) ¤tTime); @@ -678,6 +681,9 @@ OvsSttReassemble(POVS_SWITCH_CONTEXT switchContext, if (segOffset == 0) { pktFragEntry->sttHdr = *sttHdr; } + if (ipHdr->ecn == IP_ECN_CE) { + pktFragEntry->ecn = IP_ECN_CE; + } /* Copy the fragment data from Source to existing buffer */ if (OvsGetPacketBytes(curNbl, fragmentLength, startOffset, @@ -689,6 +695,14 @@ OvsSttReassemble(POVS_SWITCH_CONTEXT switchContext, handle_error: if (lastPacket) { + /* It is RECOMMENDED that if any segment of the received STT + * frame has the CE (congestion experienced) bit set + * in its IP header, then the CE bit SHOULD be set in the IP + * header of the decapsulated STT frame.*/ + if (pktFragEntry->ecn == IP_ECN_CE) { + ipHdr->ecn = IP_ECN_CE; + } + /* Retrieve the original STT header */ NdisMoveMemory(newSttHdr, &pktFragEntry->sttHdr, sizeof (SttHdr)); targetPNbl = OvsAllocateNBLFromBuffer(switchContext, @@ -920,6 +934,37 @@ OvsDecapStt(POVS_SWITCH_CONTEXT switchContext, tunKey->ttl = ipHdr->ttl; tunKey->pad = 0; + /* Handle ECN */ + if (0 != ipHdr->tos) { + UINT16 length, dlType; + Eth_Header storage; + PUINT8 ethHdr = OvsGetEthHeader(*newNbl, &length, &dlType, &storage); + + if (dlType == htons(ETH_TYPE_IPV4)) { + IPHdr *innerIpHdr = (IPHdr*)(ethHdr + length); + + /* + * If CE is set for outer IP header, reset ECN of inner IP + * header to CE, all other values are kept the same + */ + if (ipHdr->ecn == IP_ECN_CE) { + innerIpHdr->ecn |= IP_ECN_CE; + } + /* copy DSCP from outer header to inner header */ + innerIpHdr->dscp = ipHdr->dscp; + /* fix IP checksum */ + innerIpHdr->check = IPChecksum((UINT8 *)innerIpHdr, + innerIpHdr->ihl * 4, 0); + } else if (dlType == htons(ETH_TYPE_IPV6)) { + IPv6Hdr *innerIpv6Hdr = (IPv6Hdr*)(ethHdr + length); + /* copy ECN and DSCN to inner header */ + innerIpv6Hdr->priority = ipHdr->ecn + | ((innerIpv6Hdr->flow_lbl[0] & 0x3) << 2); + innerIpv6Hdr->flow_lbl[0] = (innerIpv6Hdr->flow_lbl[0] & 0xF) + | ((ipHdr->tos & 0xF) << 4); + } + } + /* Apply VLAN tag if present */ if (ntohs(sttHdr->vlanTCI) & OVSWIN_VLAN_CFI) { NDIS_NET_BUFFER_LIST_8021Q_INFO vlanTag; diff --git a/datapath-windows/ovsext/Stt.h b/datapath-windows/ovsext/Stt.h index 8aea164..b9e8b88 100644 --- a/datapath-windows/ovsext/Stt.h +++ b/datapath-windows/ovsext/Stt.h @@ -68,6 +68,7 @@ typedef struct _OVS_STT_PKT_ENTRY { UINT64 timeout; UINT32 recvdLen; UINT32 allocatedLen; + UINT8 ecn; SttHdr sttHdr; PCHAR packetBuf; LIST_ENTRY link;