The commit message says it is based on 2890 and supports only TEB. I'll change the commit message to clearly specify we do not support sequence as well.
Thanks, Alin. > -----Mesaj original----- > De la: Nithin Raju [mailto:nit...@vmware.com] > Trimis: Friday, December 11, 2015 8:51 PM > Către: Alin Serdean <aserd...@cloudbasesolutions.com>; > dev@openvswitch.org > Subiect: Re: [ovs-dev] [PATCH v3] datapath-windows: Add GRE TEB support > for windows datapath > > Alin, > The only quip I have is the claim that we support RFC 2890 in the commit > message. I went throught RFC 2890. It seeks segregation of tunnels based on > key as well as handling out of order sequence numbers. > > In any case, the code looks correct. Thanks for implementing this feature. > > Acked-by: Nithin Raju <nit...@vmware.com> > > -----Original Message----- > From: dev <dev-boun...@openvswitch.org> on behalf of Alin Serdean > <aserd...@cloudbasesolutions.com> > Date: Friday, December 11, 2015 at 9:16 AM > To: "dev@openvswitch.org" <dev@openvswitch.org> > Subject: [ovs-dev] [PATCH v3] datapath-windows: Add GRE TEB support for > windows datapath > > >This patch introduces the support for GRE TEB (trasparent ethernet > >bridging) > >for the windows datapath. > > > >The GRE support is based on > >https://urldefense.proofpoint.com/v2/url?u=http-3A__tools.ietf.org_html > >_rf > >c2890&d=BQIGaQ&c=Sqcl0Ez6M0X8aeM67LKIiDJAXVeAw-YihVMNtXt- > uEs&r=pNHQcdr7 > >B40 > >b4h6Yb7FIedI1dnBsxdDuTLBYD3JqV80&m=bBbPQ2G30E9aAnwFUB3z46K14 > wTV-vSIFUqp > >FrH jsIQ&s=ChA9HCOqAUvNslc3R27LALlokMVhqXGp0LwC77vA7gM&e= > and supports > >only the GRE protocol type 6558 (trasparent ethernet bridging) like its > >linux counterpart. > > > >Util.h: define the GRE pool tag > >Vport.c/h: sort the includes alphabetically > > add the function OvsFindTunnelVportByPortType which searches > >the > > tunnelVportsArray for a given port type Actions.c : sort the > >includes alphabetically > > call the GRE encapsulation / decapsulation functions when > >needed Gre.c/h : add GRE type defines > > add initialization/cleanup functions > > add encapsulation / decapsulation functions with software > >offloads > > (hardware offloads will be added in a separate patch) > > support > > > >Tested using: PSPING > > > >(https://urldefense.proofpoint.com/v2/url?u=https- > 3A__technet.microsoft > >.co > >m_en- > 2Dus_sysinternals_psping.aspx&d=BQIGaQ&c=Sqcl0Ez6M0X8aeM67LKIiDJAX > >VeA > >w-YihVMNtXt- > uEs&r=pNHQcdr7B40b4h6Yb7FIedI1dnBsxdDuTLBYD3JqV80&m=bBbPQ2G > >30E > >9aAnwFUB3z46K14wTV- > vSIFUqpFrHjsIQ&s=5xmJ2Qj9nxozM4SGnnI8Y6uyibVpgoawqqu > >i8Z > >w68AQ&e= ) > > (ICMP, TCP, UDP) with various packet lengths > > IPERF3 > > > >(https://urldefense.proofpoint.com/v2/url?u=https-3A__iperf.fr_iperf-2D > >dow > >nload.php&d=BQIGaQ&c=Sqcl0Ez6M0X8aeM67LKIiDJAXVeAw-YihVMNtXt- > uEs&r=pNHQ > >cdr > >7B40b4h6Yb7FIedI1dnBsxdDuTLBYD3JqV80&m=bBbPQ2G30E9aAnwFUB3z4 > 6K14wTV-vSI > >FUq pFrHjsIQ&s=_PFVJQwDFw-Tj2o4yKyv1pbLbqwrAlf9_pSH70rp9KU&e= ) > > (TCP, UDP) with various options > > > >Signed-off-by: Alin Gabriel Serdean <aserd...@cloudbasesolutions.com> > >--- > >v3: add LSO v2 support, remove GRE sequence since it is not used, address > > comments > >v2: add Gre.c/h to automake.mk EXTRA_DIST > >--- > > datapath-windows/automake.mk | 20 +- > > datapath-windows/ovsext/Actions.c | 71 ++++-- > > datapath-windows/ovsext/Gre.c | 453 > >+++++++++++++++++++++++++++++++++ > > datapath-windows/ovsext/Gre.h | 100 ++++++++ > > datapath-windows/ovsext/Util.h | 1 + > > datapath-windows/ovsext/Vport.c | 40 ++- > > datapath-windows/ovsext/Vport.h | 13 +- > > datapath-windows/ovsext/ovsext.vcxproj | 2 + > > 8 files changed, 656 insertions(+), 44 deletions(-) create mode 100644 > > datapath-windows/ovsext/Gre.c create mode 100644 > > datapath-windows/ovsext/Gre.h > > > >diff --git a/datapath-windows/automake.mk > >b/datapath-windows/automake.mk index ed48c69..7f12d92 100644 > >--- a/datapath-windows/automake.mk > >+++ b/datapath-windows/automake.mk > >@@ -4,45 +4,49 @@ EXTRA_DIST += \ > > datapath-windows/Package/package.VcxProj \ > > datapath-windows/Package/package.VcxProj.user \ > > datapath-windows/include/OvsDpInterfaceExt.h \ > >+ datapath-windows/misc/OVS.psm1 \ > > datapath-windows/misc/install.cmd \ > > datapath-windows/misc/uninstall.cmd \ > >- datapath-windows/misc/OVS.psm1 \ > > datapath-windows/ovsext.sln \ > >- datapath-windows/ovsext/Datapath.c \ > >- datapath-windows/ovsext/Datapath.h \ > >- datapath-windows/ovsext/DpInternal.h\ > > datapath-windows/ovsext/Actions.c \ > > datapath-windows/ovsext/Atomic.h \ > > datapath-windows/ovsext/BufferMgmt.c \ > > datapath-windows/ovsext/BufferMgmt.h \ > > datapath-windows/ovsext/Checksum.c \ > > datapath-windows/ovsext/Checksum.h \ > >+ datapath-windows/ovsext/Datapath.c \ > >+ datapath-windows/ovsext/Datapath.h \ > > datapath-windows/ovsext/Debug.c \ > > datapath-windows/ovsext/Debug.h \ > >+ datapath-windows/ovsext/DpInternal.h\ > > datapath-windows/ovsext/Driver.c \ > > datapath-windows/ovsext/Ethernet.h \ > > datapath-windows/ovsext/Event.c \ > > datapath-windows/ovsext/Event.h \ > > datapath-windows/ovsext/Flow.c \ > > datapath-windows/ovsext/Flow.h \ > >+ datapath-windows/ovsext/Gre.h \ > >+ datapath-windows/ovsext/Gre.c \ > > datapath-windows/ovsext/IpHelper.c \ > > datapath-windows/ovsext/IpHelper.h \ > > datapath-windows/ovsext/Jhash.c \ > > datapath-windows/ovsext/Jhash.h \ > >+ datapath-windows/ovsext/NetProto.h \ > > datapath-windows/ovsext/Netlink/Netlink.c \ > > datapath-windows/ovsext/Netlink/Netlink.h \ > > datapath-windows/ovsext/Netlink/NetlinkBuf.c \ > > datapath-windows/ovsext/Netlink/NetlinkBuf.h \ > > datapath-windows/ovsext/Netlink/NetlinkError.h \ > > datapath-windows/ovsext/Netlink/NetlinkProto.h \ > >- datapath-windows/ovsext/NetProto.h \ > > datapath-windows/ovsext/Oid.c \ > > datapath-windows/ovsext/Oid.h \ > > datapath-windows/ovsext/PacketIO.c \ > > datapath-windows/ovsext/PacketIO.h \ > > datapath-windows/ovsext/PacketParser.c \ > > datapath-windows/ovsext/PacketParser.h \ > >- datapath-windows/ovsext/Switch.c \ > >+ datapath-windows/ovsext/Stt.c \ > >+ datapath-windows/ovsext/Stt.h \ > >+ datapath-windows/ovsext/Switch.c \ > > datapath-windows/ovsext/Switch.h \ > > datapath-windows/ovsext/Tunnel.c \ > > datapath-windows/ovsext/Tunnel.h \ > >@@ -51,13 +55,11 @@ EXTRA_DIST += \ > > datapath-windows/ovsext/Types.h \ > > datapath-windows/ovsext/User.c \ > > datapath-windows/ovsext/User.h \ > >- datapath-windows/ovsext/Util.c \ > >+ datapath-windows/ovsext/Util.c \ > > datapath-windows/ovsext/Util.h \ > > datapath-windows/ovsext/Vport.c \ > > datapath-windows/ovsext/Vport.h \ > > datapath-windows/ovsext/Vxlan.c \ > >- datapath-windows/ovsext/Stt.h \ > >- datapath-windows/ovsext/Stt.c \ > > datapath-windows/ovsext/Vxlan.h \ > > datapath-windows/ovsext/ovsext.inf \ > > datapath-windows/ovsext/ovsext.rc \ > >diff --git a/datapath-windows/ovsext/Actions.c > >b/datapath-windows/ovsext/Actions.c > >index 7d34458..bfa8482 100644 > >--- a/datapath-windows/ovsext/Actions.c > >+++ b/datapath-windows/ovsext/Actions.c > >@@ -16,16 +16,17 @@ > > > > #include "precomp.h" > > > >-#include "Switch.h" > >-#include "Vport.h" > >+#include "Checksum.h" > > #include "Event.h" > >-#include "User.h" > >-#include "NetProto.h" > > #include "Flow.h" > >-#include "Vxlan.h" > >-#include "Stt.h" > >-#include "Checksum.h" > >+#include "Gre.h" > >+#include "NetProto.h" > > #include "PacketIO.h" > >+#include "Stt.h" > >+#include "Switch.h" > >+#include "User.h" > >+#include "Vport.h" > >+#include "Vxlan.h" > > > > #ifdef OVS_DBG_MOD > > #undef OVS_DBG_MOD > >@@ -34,6 +35,8 @@ > > #include "Debug.h" > > > > typedef struct _OVS_ACTION_STATS { > >+ UINT64 rxGre; > >+ UINT64 txGre; > > UINT64 rxVxlan; > > UINT64 txVxlan; > > UINT64 rxStt; > >@@ -205,27 +208,35 @@ OvsDetectTunnelRxPkt(OvsForwardingContext > >*ovsFwdCtx, > > /* XXX: we should also check for the length of the UDP payload to > >pick > > * packets only if they are at least VXLAN header size. > > */ > >- if (!flowKey->ipKey.nwFrag && > >- flowKey->ipKey.nwProto == IPPROTO_UDP) { > >- UINT16 dstPort = ntohs(flowKey->ipKey.l4.tpDst); > >- tunnelVport = > >OvsFindTunnelVportByDstPort(ovsFwdCtx->switchContext, > >- dstPort, > >- OVS_VPORT_TYPE_VXLAN); > >- if (tunnelVport) { > >- ovsActionStats.rxVxlan++; > >- } > >- } else if (!flowKey->ipKey.nwFrag && > >- flowKey->ipKey.nwProto == IPPROTO_TCP) { > >+ if (!flowKey->ipKey.nwFrag) { > > UINT16 dstPort = htons(flowKey->ipKey.l4.tpDst); > >- tunnelVport = > >OvsFindTunnelVportByDstPort(ovsFwdCtx->switchContext, > >- dstPort, > >- OVS_VPORT_TYPE_STT); > >- if (tunnelVport) { > >- ovsActionStats.rxStt++; > >+ switch (flowKey->ipKey.nwProto) { > >+ case IPPROTO_GRE: > >+ tunnelVport = > >OvsFindTunnelVportByPortType(ovsFwdCtx->switchContext, > >+ > >OVS_VPORT_TYPE_GRE); > >+ if (tunnelVport) { > >+ ovsActionStats.rxGre++; > >+ } > >+ break; > >+ case IPPROTO_TCP: > >+ tunnelVport = > >OvsFindTunnelVportByDstPort(ovsFwdCtx->switchContext, > >+ dstPort, > >+ > >OVS_VPORT_TYPE_STT); > >+ if (tunnelVport) { > >+ ovsActionStats.rxStt++; > >+ } > >+ break; > >+ case IPPROTO_UDP: > >+ tunnelVport = > >OvsFindTunnelVportByDstPort(ovsFwdCtx->switchContext, > >+ dstPort, > >+ > >OVS_VPORT_TYPE_VXLAN); > >+ if (tunnelVport) { > >+ ovsActionStats.rxVxlan++; > >+ } > >+ break; > > } > > } > > > >- > > // We might get tunnel packets even before the tunnel gets > >initialized. > > if (tunnelVport) { > > ASSERT(ovsFwdCtx->tunnelRxNic == NULL); @@ -306,6 +317,9 @@ > >OvsDetectTunnelPkt(OvsForwardingContext *ovsFwdCtx, > > /* Tunnel the packet only if tunnel context is set. */ > > if (ovsFwdCtx->tunKey.dst != 0) { > > switch(dstVport->ovsType) { > >+ case OVS_VPORT_TYPE_GRE: > >+ ovsActionStats.txGre++; > >+ break; > > case OVS_VPORT_TYPE_VXLAN: > > ovsActionStats.txVxlan++; > > break; > >@@ -652,6 +666,11 @@ OvsTunnelPortTx(OvsForwardingContext > *ovsFwdCtx) > > > > /* Do the encap. Encap function does not consume the NBL. */ > > switch(ovsFwdCtx->tunnelTxNic->ovsType) { > >+ case OVS_VPORT_TYPE_GRE: > >+ status = OvsEncapGre(ovsFwdCtx->tunnelTxNic, ovsFwdCtx->curNbl, > >+ &ovsFwdCtx->tunKey, > >ovsFwdCtx->switchContext, > >+ &ovsFwdCtx->layers, &newNbl); > >+ break; > > case OVS_VPORT_TYPE_VXLAN: > > status = OvsEncapVxlan(ovsFwdCtx->tunnelTxNic, ovsFwdCtx->curNbl, > > &ovsFwdCtx->tunKey, > >ovsFwdCtx->switchContext, > >@@ -724,6 +743,10 @@ OvsTunnelPortRx(OvsForwardingContext > *ovsFwdCtx) > > */ > > > > switch(tunnelRxVport->ovsType) { > >+ case OVS_VPORT_TYPE_GRE: > >+ status = OvsDecapGre(ovsFwdCtx->switchContext, ovsFwdCtx- > >curNbl, > >+ &ovsFwdCtx->tunKey, &newNbl); > >+ break; > > case OVS_VPORT_TYPE_VXLAN: > > status = OvsDecapVxlan(ovsFwdCtx->switchContext, > >ovsFwdCtx->curNbl, > > &ovsFwdCtx->tunKey, &newNbl); diff > >--git a/datapath-windows/ovsext/Gre.c b/datapath-windows/ovsext/Gre.c > >new file mode 100644 index 0000000..3ebfda3 > >--- /dev/null > >+++ b/datapath-windows/ovsext/Gre.c > >@@ -0,0 +1,453 @@ > >+/* > >+ * Copyright (c) 2015 Cloudbase Solutions Srl > >+ * > >+ * 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 > >+ * > >+ * > >https://urldefense.proofpoint.com/v2/url?u=http- > 3A__www.apache.org_lice > >nse > >s_LICENSE-2D2.0&d=BQIGaQ&c=Sqcl0Ez6M0X8aeM67LKIiDJAXVeAw- > YihVMNtXt-uEs& > >r=p > >NHQcdr7B40b4h6Yb7FIedI1dnBsxdDuTLBYD3JqV80&m=bBbPQ2G30E9aAnw > FUB3z46K14w > >TV- vSIFUqpFrHjsIQ&s=ErB8lfv531t48FShVylKntHjxtbQjfhnMbPbsZlLj08&e= > >+ * > >+ * 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 "precomp.h" > >+ > >+#include "Atomic.h" > >+#include "Checksum.h" > >+#include "Flow.h" > >+#include "Gre.h" > >+#include "IpHelper.h" > >+#include "NetProto.h" > >+#include "PacketIO.h" > >+#include "PacketParser.h" > >+#include "Switch.h" > >+#include "User.h" > >+#include "Util.h" > >+#include "Vport.h" > >+ > >+#ifdef OVS_DBG_MOD > >+#undef OVS_DBG_MOD > >+#endif > >+#define OVS_DBG_MOD OVS_DBG_GRE > >+#include "Debug.h" > >+ > >+static NDIS_STATUS > >+OvsDoEncapGre(POVS_VPORT_ENTRY vport, PNET_BUFFER_LIST curNbl, > >+ const OvsIPv4TunnelKey *tunKey, > >+ const POVS_FWD_INFO fwdInfo, > >+ POVS_PACKET_HDR_INFO layers, > >+ POVS_SWITCH_CONTEXT switchContext, > >+ PNET_BUFFER_LIST *newNbl); > >+ > >+/* > >+ * > >----------------------------------------------------------------------- > >--- > >+ * OvsInitGreTunnel -- > >+ * Initialize GRE tunnel module. > >+ * > >----------------------------------------------------------------------- > >--- > >+ */ > >+NTSTATUS > >+OvsInitGreTunnel(POVS_VPORT_ENTRY vport) { > >+ POVS_GRE_VPORT grePort; > >+ > >+ grePort = > (POVS_GRE_VPORT)OvsAllocateMemoryWithTag(sizeof(*grePort), > >+ OVS_GRE_POOL_TAG); > >+ if (!grePort) { > >+ OVS_LOG_ERROR("Insufficient memory, can't allocate > >OVS_GRE_VPORT"); > >+ return STATUS_INSUFFICIENT_RESOURCES; > >+ } > >+ > >+ RtlZeroMemory(grePort, sizeof(*grePort)); > >+ vport->priv = (PVOID)grePort; > >+ return STATUS_SUCCESS; > >+} > >+ > >+/* > >+ * > >----------------------------------------------------------------------- > >--- > >+ * OvsCleanupGreTunnel -- > >+ * Cleanup GRE Tunnel module. > >+ * > >----------------------------------------------------------------------- > >--- > >+ */ > >+void > >+OvsCleanupGreTunnel(POVS_VPORT_ENTRY vport) { > >+ if (vport->ovsType != OVS_VPORT_TYPE_GRE || > >+ vport->priv == NULL) { > >+ return; > >+ } > >+ > >+ OvsFreeMemoryWithTag(vport->priv, OVS_GRE_POOL_TAG); > >+ vport->priv = NULL; > >+} > >+ > >+/* > >+ * > >----------------------------------------------------------------------- > >--- > >+ * OvsEncapGre -- > >+ * Encapsulates a packet with an GRE header. > >+ * > >----------------------------------------------------------------------- > >--- > >+ */ > >+NDIS_STATUS > >+OvsEncapGre(POVS_VPORT_ENTRY vport, > >+ PNET_BUFFER_LIST curNbl, > >+ OvsIPv4TunnelKey *tunKey, > >+ POVS_SWITCH_CONTEXT switchContext, > >+ POVS_PACKET_HDR_INFO layers, > >+ PNET_BUFFER_LIST *newNbl) > >+{ > >+ OVS_FWD_INFO fwdInfo; > >+ NDIS_STATUS status; > >+ > >+ status = OvsLookupIPFwdInfo(tunKey->dst, &fwdInfo); > >+ if (status != STATUS_SUCCESS) { > >+ OvsFwdIPHelperRequest(NULL, 0, tunKey, NULL, NULL, NULL); > >+ return NDIS_STATUS_FAILURE; > >+ } > >+ > >+ status = OvsDoEncapGre(vport, curNbl, tunKey, &fwdInfo, layers, > >+ switchContext, newNbl); > >+ return status; > >+} > >+ > >+/* > >+ * > >----------------------------------------------------------------------- > >--- > >+ * OvsDoEncapGre -- > >+ * Internal utility function which actually does the GRE encap. > >+ * > >----------------------------------------------------------------------- > >--- > >+ */ > >+NDIS_STATUS > >+OvsDoEncapGre(POVS_VPORT_ENTRY vport, > >+ PNET_BUFFER_LIST curNbl, > >+ const OvsIPv4TunnelKey *tunKey, > >+ const POVS_FWD_INFO fwdInfo, > >+ POVS_PACKET_HDR_INFO layers, > >+ POVS_SWITCH_CONTEXT switchContext, > >+ PNET_BUFFER_LIST *newNbl) { > >+ NDIS_STATUS status; > >+ PNET_BUFFER curNb; > >+ PMDL curMdl; > >+ PUINT8 bufferStart; > >+ EthHdr *ethHdr; > >+ IPHdr *ipHdr; > >+ PGREHdr greHdr; > >+ POVS_GRE_VPORT vportGre; > >+ UINT32 headRoom = GreTunHdrSize(tunKey->flags); #if DBG > >+ UINT32 counterHeadRoom; > >+#endif > >+ UINT32 packetLength; > >+ ULONG mss = 0; > >+ ASSERT(*newNbl == NULL); > >+ > >+ curNb = NET_BUFFER_LIST_FIRST_NB(curNbl); > >+ packetLength = NET_BUFFER_DATA_LENGTH(curNb); > >+ > >+ if (layers->isTcp) { > >+ NDIS_TCP_LARGE_SEND_OFFLOAD_NET_BUFFER_LIST_INFO tsoInfo; > >+ > >+ tsoInfo.Value = NET_BUFFER_LIST_INFO(curNbl, > >+ > >TcpLargeSendNetBufferListInfo); > >+ switch (tsoInfo.Transmit.Type) { > >+ case NDIS_TCP_LARGE_SEND_OFFLOAD_V1_TYPE: > >+ mss = tsoInfo.LsoV1Transmit.MSS; > >+ break; > >+ case NDIS_TCP_LARGE_SEND_OFFLOAD_V2_TYPE: > >+ mss = tsoInfo.LsoV2Transmit.MSS; > >+ break; > >+ default: > >+ OVS_LOG_ERROR("Unknown LSO transmit type:%d", > >+ tsoInfo.Transmit.Type); > >+ return NDIS_STATUS_FAILURE; > >+ } > >+ OVS_LOG_TRACE("MSS %u packet len %u", mss, > >+ packetLength); > >+ if (mss) { > >+ OVS_LOG_TRACE("l4Offset %d", layers->l4Offset); > >+ *newNbl = OvsTcpSegmentNBL(switchContext, curNbl, layers, > >+ mss, headRoom); > >+ if (*newNbl == NULL) { > >+ OVS_LOG_ERROR("Unable to segment NBL"); > >+ return NDIS_STATUS_FAILURE; > >+ } > >+ /* Clear out LSO flags after this point */ > >+ NET_BUFFER_LIST_INFO(*newNbl, > >+ TcpLargeSendNetBufferListInfo) > >= 0; > >+ } > >+ } > >+ > >+ vportGre = (POVS_GRE_VPORT)GetOvsVportPriv(vport); > >+ ASSERT(vportGre); > >+ > >+ /* If we didn't split the packet above, make a copy now */ > >+ if (*newNbl == NULL) { > >+ *newNbl = OvsPartialCopyNBL(switchContext, curNbl, 0, headRoom, > >+ FALSE /*NBL info*/); > >+ if (*newNbl == NULL) { > >+ OVS_LOG_ERROR("Unable to copy NBL"); > >+ return NDIS_STATUS_FAILURE; > >+ } > >+ /* > >+ * To this point we do not have GRE hardware offloading. > >+ * Apply defined checksums > >+ */ > >+ curNb = NET_BUFFER_LIST_FIRST_NB(*newNbl); > >+ curMdl = NET_BUFFER_CURRENT_MDL(curNb); > >+ bufferStart = (PUINT8)MmGetSystemAddressForMdlSafe(curMdl, > >+ > >LowPagePriority); > >+ if (!bufferStart) { > >+ status = NDIS_STATUS_RESOURCES; > >+ goto ret_error; > >+ } > >+ > >+ NDIS_TCP_IP_CHECKSUM_NET_BUFFER_LIST_INFO csumInfo; > >+ csumInfo.Value = NET_BUFFER_LIST_INFO(curNbl, > >+ > >TcpIpChecksumNetBufferListInfo); > >+ > >+ bufferStart += NET_BUFFER_CURRENT_MDL_OFFSET(curNb); > >+ > >+ if (layers->isIPv4) { > >+ IPHdr *ip = (IPHdr *)(bufferStart + layers->l3Offset); > >+ > >+ if (csumInfo.Transmit.IpHeaderChecksum) { > >+ ip->check = 0; > >+ ip->check = IPChecksum((UINT8 *)ip, 4 * ip->ihl, 0); > >+ } > >+ > >+ if (layers->isTcp && csumInfo.Transmit.TcpChecksum) { > >+ UINT16 csumLength = (UINT16)(packetLength - > >layers->l4Offset); > >+ TCPHdr *tcp = (TCPHdr *)(bufferStart + layers->l4Offset); > >+ tcp->check = IPPseudoChecksum(&ip->saddr, &ip->daddr, > >+ IPPROTO_TCP, csumLength); > >+ tcp->check = CalculateChecksumNB(curNb, csumLength, > >+ > >(UINT32)(layers->l4Offset)); > >+ } else if (layers->isUdp && csumInfo.Transmit.UdpChecksum) { > >+ UINT16 csumLength = (UINT16)(packetLength - > >layers->l4Offset); > >+ UDPHdr *udp = (UDPHdr *)((PCHAR)ip + sizeof *ip); > >+ udp->check = IPPseudoChecksum(&ip->saddr, &ip->daddr, > >+ IPPROTO_UDP, csumLength); > >+ udp->check = CalculateChecksumNB(curNb, csumLength, > >+ > >(UINT32)(layers->l4Offset)); > >+ } > >+ } else if (layers->isIPv6) { > >+ IPv6Hdr *ip = (IPv6Hdr *)(bufferStart + layers->l3Offset); > >+ > >+ if (layers->isTcp && csumInfo.Transmit.TcpChecksum) { > >+ UINT16 csumLength = (UINT16)(packetLength - > >layers->l4Offset); > >+ TCPHdr *tcp = (TCPHdr *)(bufferStart + layers->l4Offset); > >+ tcp->check = IPv6PseudoChecksum((UINT32 *) &ip->saddr, > >+ (UINT32 *) &ip->daddr, > >+ IPPROTO_TCP, csumLength); > >+ tcp->check = CalculateChecksumNB(curNb, csumLength, > >+ > >(UINT32)(layers->l4Offset)); > >+ } else if (layers->isUdp && csumInfo.Transmit.UdpChecksum) { > >+ UINT16 csumLength = (UINT16)(packetLength - > >layers->l4Offset); > >+ UDPHdr *udp = (UDPHdr *)((PCHAR)ip + sizeof *ip); > >+ udp->check = IPv6PseudoChecksum((UINT32 *) &ip->saddr, > >+ (UINT32 *) &ip->daddr, > >+ IPPROTO_UDP, csumLength); > >+ udp->check = CalculateChecksumNB(curNb, csumLength, > >+ > >(UINT32)(layers->l4Offset)); > >+ } > >+ } > >+ /* Clear out TcpIpChecksumNetBufferListInfo flag */ > >+ NET_BUFFER_LIST_INFO(*newNbl, TcpIpChecksumNetBufferListInfo) > >+ = > >0; > >+ } > >+ > >+ curNbl = *newNbl; > >+ for (curNb = NET_BUFFER_LIST_FIRST_NB(curNbl); curNb != NULL; > >+ curNb = curNb->Next) { > >+#if DBG > >+ counterHeadRoom = headRoom; > >+#endif > >+ status = NdisRetreatNetBufferDataStart(curNb, headRoom, 0, NULL); > >+ if (status != NDIS_STATUS_SUCCESS) { > >+ goto ret_error; > >+ } > >+ > >+ curMdl = NET_BUFFER_CURRENT_MDL(curNb); > >+ bufferStart = (PUINT8)MmGetSystemAddressForMdlSafe(curMdl, > >+ > >LowPagePriority); > >+ if (!bufferStart) { > >+ status = NDIS_STATUS_RESOURCES; > >+ goto ret_error; > >+ } > >+ > >+ bufferStart += NET_BUFFER_CURRENT_MDL_OFFSET(curNb); > >+ if (NET_BUFFER_NEXT_NB(curNb)) { > >+ OVS_LOG_TRACE("nb length %u next %u", > >+ NET_BUFFER_DATA_LENGTH(curNb), > >+ NET_BUFFER_DATA_LENGTH(curNb->Next)); > >+ } > >+ > >+ /* L2 header */ > >+ ethHdr = (EthHdr *)bufferStart; > >+ ASSERT(((PCHAR)&fwdInfo->dstMacAddr + sizeof > >fwdInfo->dstMacAddr) == > >+ (PCHAR)&fwdInfo->srcMacAddr); > >+ NdisMoveMemory(ethHdr->Destination, fwdInfo->dstMacAddr, > >+ sizeof ethHdr->Destination + sizeof > >ethHdr->Source); > >+ ethHdr->Type = htons(ETH_TYPE_IPV4); #if DBG > >+ counterHeadRoom -= sizeof *ethHdr; #endif > >+ > >+ /* IP header */ > >+ ipHdr = (IPHdr *)((PCHAR)ethHdr + sizeof *ethHdr); > >+ > >+ ipHdr->ihl = sizeof *ipHdr / 4; > >+ ipHdr->version = IPPROTO_IPV4; > >+ ipHdr->tos = tunKey->tos; > >+ ipHdr->tot_len = htons(NET_BUFFER_DATA_LENGTH(curNb) - sizeof > >*ethHdr); > >+ ipHdr->id = (uint16)atomic_add64(&vportGre->ipId, > >+ NET_BUFFER_DATA_LENGTH(curNb)); > >+ ipHdr->frag_off = (tunKey->flags & OVS_TNL_F_DONT_FRAGMENT) ? > >+ IP_DF_NBO : 0; > >+ ipHdr->ttl = tunKey->ttl ? tunKey->ttl : 64; > >+ ipHdr->protocol = IPPROTO_GRE; > >+ ASSERT(tunKey->dst == fwdInfo->dstIpAddr); > >+ ASSERT(tunKey->src == fwdInfo->srcIpAddr || tunKey->src == 0); > >+ ipHdr->saddr = fwdInfo->srcIpAddr; > >+ ipHdr->daddr = fwdInfo->dstIpAddr; > >+ > >+ ipHdr->check = 0; > >+ ipHdr->check = IPChecksum((UINT8 *)ipHdr, sizeof *ipHdr, 0); > >+#if DBG > >+ counterHeadRoom -= sizeof *ipHdr; #endif > >+ > >+ /* GRE header */ > >+ greHdr = (GREHdr *)((PCHAR)ipHdr + sizeof *ipHdr); > >+ greHdr->flags = OvsTunnelFlagsToGreFlags(tunKey->flags); > >+ greHdr->protocolType = GRE_NET_TEB; #if DBG > >+ counterHeadRoom -= sizeof *greHdr; #endif > >+ > >+ PCHAR currentOffset = (PCHAR)greHdr + sizeof *greHdr; > >+ > >+ if (tunKey->flags & OVS_TNL_F_CSUM) { > >+ RtlZeroMemory(currentOffset, 4); > >+ currentOffset += 4; > >+#if DBG > >+ counterHeadRoom -= 4; > >+#endif > >+ } > >+ > >+ if (tunKey->flags & OVS_TNL_F_KEY) { > >+ RtlZeroMemory(currentOffset, 4); > >+ UINT32 key = (tunKey->tunnelId >> 32); > >+ RtlCopyMemory(currentOffset, &key, sizeof key); > >+ currentOffset += 4; > >+#if DBG > >+ counterHeadRoom -= 4; > >+#endif > >+ } > >+ > >+#if DBG > >+ ASSERT(counterHeadRoom == 0); > >+#endif > >+ > >+ } > >+ return STATUS_SUCCESS; > >+ > >+ret_error: > >+ OvsCompleteNBL(switchContext, *newNbl, TRUE); > >+ *newNbl = NULL; > >+ return status; > >+} > >+ > >+NDIS_STATUS > >+OvsDecapGre(POVS_SWITCH_CONTEXT switchContext, > >+ PNET_BUFFER_LIST curNbl, > >+ OvsIPv4TunnelKey *tunKey, > >+ PNET_BUFFER_LIST *newNbl) > >+{ > >+ PNET_BUFFER curNb; > >+ PMDL curMdl; > >+ EthHdr *ethHdr; > >+ IPHdr *ipHdr; > >+ GREHdr *greHdr; > >+ UINT32 tunnelSize = 0, packetLength = 0; > >+ UINT32 headRoom = 0; > >+ PUINT8 bufferStart; > >+ NDIS_STATUS status; > >+ > >+ curNb = NET_BUFFER_LIST_FIRST_NB(curNbl); > >+ packetLength = NET_BUFFER_DATA_LENGTH(curNb); > >+ tunnelSize = GreTunHdrSize(tunKey->flags); > >+ if (packetLength <= tunnelSize) { > >+ return NDIS_STATUS_INVALID_LENGTH; > >+ } > >+ > >+ /* > >+ * Create a copy of the NBL so that we have all the headers in one > >MDL. > >+ */ > >+ *newNbl = OvsPartialCopyNBL(switchContext, curNbl, > >+ tunnelSize + OVS_DEFAULT_COPY_SIZE, 0, > >+ TRUE /*copy NBL info */); > >+ > >+ if (*newNbl == NULL) { > >+ return NDIS_STATUS_RESOURCES; > >+ } > >+ > >+ curNbl = *newNbl; > >+ curNb = NET_BUFFER_LIST_FIRST_NB(curNbl); > >+ curMdl = NET_BUFFER_CURRENT_MDL(curNb); > >+ bufferStart = (PUINT8)MmGetSystemAddressForMdlSafe(curMdl, > >LowPagePriority) + > >+ NET_BUFFER_CURRENT_MDL_OFFSET(curNb); > >+ if (!bufferStart) { > >+ status = NDIS_STATUS_RESOURCES; > >+ goto dropNbl; > >+ } > >+ > >+ ethHdr = (EthHdr *)bufferStart; > >+ headRoom += sizeof *ethHdr; > >+ > >+ ipHdr = (IPHdr *)((PCHAR)ethHdr + sizeof *ethHdr); > >+ tunKey->src = ipHdr->saddr; > >+ tunKey->dst = ipHdr->daddr; > >+ tunKey->tos = ipHdr->tos; > >+ tunKey->ttl = ipHdr->ttl; > >+ tunKey->pad = 0; > >+ headRoom += sizeof *ipHdr; > >+ > >+ greHdr = (GREHdr *)((PCHAR)ipHdr + sizeof *ipHdr); > >+ headRoom += sizeof *greHdr; > >+ > >+ /* Validate if GRE header protocol type. */ > >+ if (greHdr->protocolType != GRE_NET_TEB) { > >+ status = STATUS_NDIS_INVALID_PACKET; > >+ goto dropNbl; > >+ } > >+ > >+ PCHAR currentOffset = (PCHAR)greHdr + sizeof *greHdr; > >+ > >+ if (greHdr->flags & GRE_CSUM) { > >+ tunKey->flags |= OVS_TNL_F_CSUM; > >+ currentOffset += 4; > >+ headRoom += 4; > >+ } > >+ > >+ if (greHdr->flags & GRE_KEY) { > >+ tunKey->flags |= OVS_TNL_F_KEY; > >+ UINT32 key = 0; > >+ RtlCopyMemory(&key, currentOffset, 4); > >+ tunKey->tunnelId = (UINT64)key << 32; > >+ currentOffset += 4; > >+ headRoom += 4; > >+ } > >+ > >+ /* Clear out the receive flag for the inner packet. */ > >+ NET_BUFFER_LIST_INFO(curNbl, TcpIpChecksumNetBufferListInfo) = 0; > >+ NdisAdvanceNetBufferDataStart(curNb, GreTunHdrSize(tunKey->flags), > >FALSE, > >+ NULL); > >+ ASSERT(headRoom == GreTunHdrSize(tunKey->flags)); > >+ return NDIS_STATUS_SUCCESS; > >+ > >+dropNbl: > >+ OvsCompleteNBL(switchContext, *newNbl, TRUE); > >+ *newNbl = NULL; > >+ return status; > >+} > >diff --git a/datapath-windows/ovsext/Gre.h > >b/datapath-windows/ovsext/Gre.h new file mode 100644 index > >0000000..d2472d9 > >--- /dev/null > >+++ b/datapath-windows/ovsext/Gre.h > >@@ -0,0 +1,100 @@ > >+/* > >+ * Copyright (c) 2015 Cloudbase Solutions Srl > >+ * > >+ * 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 > >+ * > >+ * > >https://urldefense.proofpoint.com/v2/url?u=http- > 3A__www.apache.org_lice > >nse > >s_LICENSE-2D2.0&d=BQIGaQ&c=Sqcl0Ez6M0X8aeM67LKIiDJAXVeAw- > YihVMNtXt-uEs& > >r=p > >NHQcdr7B40b4h6Yb7FIedI1dnBsxdDuTLBYD3JqV80&m=bBbPQ2G30E9aAnw > FUB3z46K14w > >TV- vSIFUqpFrHjsIQ&s=ErB8lfv531t48FShVylKntHjxtbQjfhnMbPbsZlLj08&e= > >+ * > >+ * 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 __GRE_H_ > >+#define __GRE_H_ 1 > >+ > >+#include "NetProto.h" > >+#include "Flow.h" > >+ > >+typedef struct _OVS_GRE_VPORT { > >+ UINT64 ipId; > >+ /* > >+ * To be filled > >+ */ > >+} OVS_GRE_VPORT, *POVS_GRE_VPORT; > >+ > >+ > >+/* GRE RFC 2890 header based on > >https://urldefense.proofpoint.com/v2/url?u=http-3A__tools.ietf.org_html > >_rf > >c2890&d=BQIGaQ&c=Sqcl0Ez6M0X8aeM67LKIiDJAXVeAw-YihVMNtXt- > uEs&r=pNHQcdr7 > >B40 > >b4h6Yb7FIedI1dnBsxdDuTLBYD3JqV80&m=bBbPQ2G30E9aAnwFUB3z46K14 > wTV-vSIFUqp > >FrH jsIQ&s=ChA9HCOqAUvNslc3R27LALlokMVhqXGp0LwC77vA7gM&e= > >+ * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 > >+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ > >+ * |C| |K|S| Reserved0 | Ver | Protocol Type | > >+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ > >+ * | Checksum (optional) | Reserved1 (Optional) | > >+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ > >+ * | Key (optional) | > >+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ > >+ * | Sequence Number (Optional) | > >+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ > >+ */ > >+ > >+typedef struct GREHdr { > >+ UINT16 flags; > >+ UINT16 protocolType; > >+} GREHdr, *PGREHdr; > >+ > >+/* Transparent Ethernet Bridging */ > >+#define GRE_NET_TEB 0x5865 > >+/* GRE Flags*/ > >+#define GRE_CSUM 0x0080 > >+#define GRE_KEY 0x0020 > >+ > >+NTSTATUS OvsInitGreTunnel(POVS_VPORT_ENTRY vport); > >+ > >+VOID OvsCleanupGreTunnel(POVS_VPORT_ENTRY vport); > >+ > >+ > >+void OvsCleanupGreTunnel(POVS_VPORT_ENTRY vport); > >+ > >+NDIS_STATUS OvsEncapGre(POVS_VPORT_ENTRY vport, > >+ PNET_BUFFER_LIST curNbl, > >+ OvsIPv4TunnelKey *tunKey, > >+ POVS_SWITCH_CONTEXT switchContext, > >+ POVS_PACKET_HDR_INFO layers, > >+ PNET_BUFFER_LIST *newNbl); > >+ > >+NDIS_STATUS OvsDecapGre(POVS_SWITCH_CONTEXT switchContext, > >+ PNET_BUFFER_LIST curNbl, > >+ OvsIPv4TunnelKey *tunKey, > >+ PNET_BUFFER_LIST *newNbl); > >+ > >+static __inline UINT16 > >+OvsTunnelFlagsToGreFlags(UINT16 tunnelflags) { > >+ UINT16 flags = 0; > >+ > >+ if (tunnelflags & OVS_TNL_F_CSUM) > >+ flags |= GRE_CSUM; > >+ > >+ if (tunnelflags & OVS_TNL_F_KEY) > >+ flags |= GRE_KEY; > >+ > >+ return flags; > >+} > >+ > >+static __inline UINT32 > >+GreTunHdrSize(UINT16 flags) > >+{ > >+ UINT32 sum = sizeof(EthHdr) + sizeof(IPHdr) + sizeof(GREHdr); > >+ sum += (flags & OVS_TNL_F_CSUM) ? > >+ 4 : 0; > >+ sum += (flags & OVS_TNL_F_KEY) ? > >+ 4 : 0; > >+ > >+ return sum; > >+} > >+ > >+#endif /*__GRE_H_ */ > >diff --git a/datapath-windows/ovsext/Util.h > >b/datapath-windows/ovsext/Util.h index e5ba72b..a81c723 100644 > >--- a/datapath-windows/ovsext/Util.h > >+++ b/datapath-windows/ovsext/Util.h > >@@ -34,6 +34,7 @@ > > #define OVS_USER_POOL_TAG 'USVO' > > #define OVS_VPORT_POOL_TAG 'PSVO' > > #define OVS_STT_POOL_TAG 'RSVO' > >+#define OVS_GRE_POOL_TAG 'GSVO' > > #define OVS_TUNFLT_POOL_TAG 'WSVO' > > > > VOID *OvsAllocateMemory(size_t size); > >diff --git a/datapath-windows/ovsext/Vport.c > >b/datapath-windows/ovsext/Vport.c > >index a7576d3..7b0103d 100644 > >--- a/datapath-windows/ovsext/Vport.c > >+++ b/datapath-windows/ovsext/Vport.c > >@@ -15,16 +15,18 @@ > > */ > > > > #include "precomp.h" > >+ > >+#include "Datapath.h" > >+#include "Event.h" > >+#include "Gre.h" > >+#include "IpHelper.h" > > #include "Jhash.h" > >+#include "Oid.h" > >+#include "Stt.h" > > #include "Switch.h" > >-#include "Vport.h" > >-#include "Event.h" > > #include "User.h" > >+#include "Vport.h" > > #include "Vxlan.h" > >-#include "Stt.h" > >-#include "IpHelper.h" > >-#include "Oid.h" > >-#include "Datapath.h" > > > > #ifdef OVS_DBG_MOD > > #undef OVS_DBG_MOD > >@@ -700,6 +702,24 @@ > OvsFindTunnelVportByDstPort(POVS_SWITCH_CONTEXT > >switchContext, > > return NULL; > > } > > > >+POVS_VPORT_ENTRY > >+OvsFindTunnelVportByPortType(POVS_SWITCH_CONTEXT switchContext, > >+ OVS_VPORT_TYPE ovsPortType) { > >+ POVS_VPORT_ENTRY vport; > >+ PLIST_ENTRY head, link; > >+ UINT16 dstPort = 0; > >+ UINT32 hash = OvsJhashBytes((const VOID *)&dstPort, sizeof(dstPort), > >+ OVS_HASH_BASIS); > >+ head = &(switchContext->tunnelVportsArray[hash & > OVS_VPORT_MASK]); > >+ LIST_FORALL(head, link) { > >+ vport = CONTAINING_RECORD(link, OVS_VPORT_ENTRY, > >tunnelVportLink); > >+ if (vport->ovsType == ovsPortType) { > >+ return vport; > >+ } > >+ } > >+ return NULL; > >+} > > > > POVS_VPORT_ENTRY > > OvsFindVportByOvsName(POVS_SWITCH_CONTEXT switchContext, @@ - > 983,6 > >+1003,7 @@ OvsInitTunnelVport(PVOID userContext, > > vport->ovsState = OVS_STATE_PORT_CREATED; > > switch (ovsType) { > > case OVS_VPORT_TYPE_GRE: > >+ status = OvsInitGreTunnel(vport); > > break; > > case OVS_VPORT_TYPE_VXLAN: > > { > >@@ -1153,6 +1174,7 @@ InitOvsVportCommon(POVS_SWITCH_CONTEXT > >switchContext, > > UINT32 hash; > > > > switch(vport->ovsType) { > >+ case OVS_VPORT_TYPE_GRE: > > case OVS_VPORT_TYPE_VXLAN: > > case OVS_VPORT_TYPE_STT: > > { > >@@ -1242,6 +1264,7 @@ OvsRemoveAndDeleteVport(PVOID > usrParamsContext, > > OvsCleanupSttTunnel(vport); > > break; > > case OVS_VPORT_TYPE_GRE: > >+ OvsCleanupGreTunnel(vport); > > break; > > case OVS_VPORT_TYPE_NETDEV: > > if (vport->isExternal) { > >@@ -1299,7 +1322,8 @@ OvsRemoveAndDeleteVport(PVOID > usrParamsContext, > > RemoveEntryList(&vport->portNoLink); > > InitializeListHead(&vport->portNoLink); > > if (OVS_VPORT_TYPE_VXLAN == vport->ovsType || > >- OVS_VPORT_TYPE_STT == vport->ovsType) { > >+ OVS_VPORT_TYPE_STT == vport->ovsType || > >+ OVS_VPORT_TYPE_GRE == vport->ovsType) { > > RemoveEntryList(&vport->tunnelVportLink); > > InitializeListHead(&vport->tunnelVportLink); > > } > >@@ -2190,6 +2214,8 @@ > OvsNewVportCmdHandler(POVS_USER_PARAMS_CONTEXT > >usrParamsCtx, > > UINT16 transportPortDest = 0; > > > > switch (portType) { > >+ case OVS_VPORT_TYPE_GRE: > >+ break; > > case OVS_VPORT_TYPE_VXLAN: > > transportPortDest = VXLAN_UDP_PORT; > > break; > >diff --git a/datapath-windows/ovsext/Vport.h > >b/datapath-windows/ovsext/Vport.h > >index e9f3b03..373896d 100644 > >--- a/datapath-windows/ovsext/Vport.h > >+++ b/datapath-windows/ovsext/Vport.h > >@@ -17,9 +17,10 @@ > > #ifndef __VPORT_H_ > > #define __VPORT_H_ 1 > > > >+#include "Gre.h" > >+#include "Stt.h" > > #include "Switch.h" > > #include "VxLan.h" > >-#include "Stt.h" > > > > #define OVS_MAX_DPPORTS MAXUINT16 > > #define OVS_DPPORT_NUMBER_INVALID OVS_MAX_DPPORTS > >@@ -147,6 +148,8 @@ POVS_VPORT_ENTRY > >OvsFindVportByPortIdAndNicIndex(POVS_SWITCH_CONTEXT switchConte > >POVS_VPORT_ENTRY > OvsFindTunnelVportByDstPort(POVS_SWITCH_CONTEXT > >switchContext, > > UINT16 dstPort, > > OVS_VPORT_TYPE > >ovsVportType); > >+POVS_VPORT_ENTRY > OvsFindTunnelVportByPortType(POVS_SWITCH_CONTEXT > >switchContext, > >+ OVS_VPORT_TYPE > >ovsPortType); > > > > NDIS_STATUS OvsAddConfiguredSwitchPorts(struct > _OVS_SWITCH_CONTEXT > >*switchContext); NDIS_STATUS OvsInitConfiguredSwitchNics(struct > >_OVS_SWITCH_CONTEXT *switchContext); @@ -256,16 +259,18 @@ > >GetPortFromPriv(POVS_VPORT_ENTRY vport) > > /* XXX would better to have a commom tunnel "parent" structure */ > > ASSERT(vportPriv); > > switch(vport->ovsType) { > >- case OVS_VPORT_TYPE_VXLAN: > >- dstPort = ((POVS_VXLAN_VPORT)vportPriv)->dstPort; > >+ case OVS_VPORT_TYPE_GRE: > > break; > > case OVS_VPORT_TYPE_STT: > > dstPort = ((POVS_STT_VPORT)vportPriv)->dstPort; > > break; > >+ case OVS_VPORT_TYPE_VXLAN: > >+ dstPort = ((POVS_VXLAN_VPORT)vportPriv)->dstPort; > >+ break; > > default: > > ASSERT(! "Port is not a tunnel port"); > > } > >- ASSERT(dstPort); > >+ ASSERT(dstPort || vport->ovsType == OVS_VPORT_TYPE_GRE); > > return dstPort; > > } > > > >diff --git a/datapath-windows/ovsext/ovsext.vcxproj > >b/datapath-windows/ovsext/ovsext.vcxproj > >index 616f688..231ac83 100644 > >--- a/datapath-windows/ovsext/ovsext.vcxproj > >+++ b/datapath-windows/ovsext/ovsext.vcxproj > >@@ -80,6 +80,7 @@ > > <ClInclude Include="Ethernet.h" /> > > <ClInclude Include="Event.h" /> > > <ClInclude Include="Flow.h" /> > >+ <ClInclude Include="Gre.h" /> > > <ClInclude Include="IpHelper.h" /> > > <ClInclude Include="Jhash.h" /> > > <ClInclude Include="Netlink/Netlink.h" /> @@ -172,6 +173,7 @@ > > <ClCompile Include="Driver.c" /> > > <ClCompile Include="Event.c" /> > > <ClCompile Include="Flow.c" /> > >+ <ClCompile Include="Gre.c" /> > > <ClCompile Include="IpHelper.c" /> > > <ClCompile Include="Jhash.c" /> > > <ClCompile Include="Netlink/Netlink.c" /> > >-- > >1.9.5.msysgit.0 > >_______________________________________________ > >dev mailing list > >dev@openvswitch.org > >https://urldefense.proofpoint.com/v2/url?u=http- > 3A__openvswitch.org_mai > >lma > >n_listinfo_dev&d=BQIGaQ&c=Sqcl0Ez6M0X8aeM67LKIiDJAXVeAw- > YihVMNtXt-uEs&r > >=pN > >HQcdr7B40b4h6Yb7FIedI1dnBsxdDuTLBYD3JqV80&m=bBbPQ2G30E9aAnwF > UB3z46K14wT > >V-v SIFUqpFrHjsIQ&s=iOk_882sc2wEqu8L4Kp2qBpOm_9-- > aniVHWU7SVn2_o&e= > _______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev