From patchwork Fri Jun 17 17:51:52 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nithin Raju X-Patchwork-Id: 637242 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 3rWSW10GJRz9t0d for ; Sat, 18 Jun 2016 03:51:57 +1000 (AEST) Received: from archives.nicira.com (localhost [127.0.0.1]) by archives.nicira.com (Postfix) with ESMTP id 4BF5C10AFF; Fri, 17 Jun 2016 10:51:56 -0700 (PDT) X-Original-To: dev@openvswitch.org Delivered-To: dev@openvswitch.org Received: from mx1e3.cudamail.com (mx1.cudamail.com [69.90.118.67]) by archives.nicira.com (Postfix) with ESMTPS id AC70110ABF for ; Fri, 17 Jun 2016 10:51:54 -0700 (PDT) Received: from bar5.cudamail.com (localhost [127.0.0.1]) by mx1e3.cudamail.com (Postfix) with ESMTPS id 35436420139 for ; Fri, 17 Jun 2016 11:51:54 -0600 (MDT) X-ASG-Debug-ID: 1466185913-09eadd321409a20001-byXFYA Received: from mx3-pf3.cudamail.com ([192.168.14.3]) by bar5.cudamail.com with ESMTP id eCIi0c7ByNfVtKYD (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO) for ; Fri, 17 Jun 2016 11:51:53 -0600 (MDT) X-Barracuda-Envelope-From: nithin@vmware.com X-Barracuda-RBL-Trusted-Forwarder: 192.168.14.3 Received: from unknown (HELO EX13-EDG-OU-001.vmware.com) (208.91.0.189) by mx3-pf3.cudamail.com with ESMTPS (AES256-SHA encrypted); 17 Jun 2016 17:51:53 -0000 Received-SPF: error (mx3-pf3.cudamail.com: error in processing during lookup of vmware.com: DNS problem) Received: from sc9-mailhost3.vmware.com (10.113.161.73) by EX13-EDG-OU-001.vmware.com (10.113.208.155) with Microsoft SMTP Server id 15.0.1156.6; Fri, 17 Jun 2016 10:51:46 -0700 Received: from sc9-mailhost1.vmware.com (unknown [10.129.194.88]) by sc9-mailhost3.vmware.com (Postfix) with ESMTP id 5393640563; Fri, 17 Jun 2016 10:51:52 -0700 (PDT) X-CudaMail-Envelope-Sender: nithin@vmware.com From: Nithin Raju To: X-CudaMail-Whitelist-To: dev@openvswitch.org X-CudaMail-MID: CM-V3-616030018 X-CudaMail-DTE: 061716 X-CudaMail-Originating-IP: 208.91.0.189 Date: Fri, 17 Jun 2016 10:51:52 -0700 X-ASG-Orig-Subj: [##CM-V3-616030018##][PATCH v4] datapath-windows: use ip proto for tunnel port lookup Message-ID: <1466185912-1996-1-git-send-email-nithin@vmware.com> X-Mailer: git-send-email 2.7.1.windows.1 MIME-Version: 1.0 Received-SPF: None (EX13-EDG-OU-001.vmware.com: nithin@vmware.com does not designate permitted sender hosts) X-Barracuda-Connect: UNKNOWN[192.168.14.3] X-Barracuda-Start-Time: 1466185913 X-Barracuda-Encrypted: DHE-RSA-AES256-SHA X-Barracuda-URL: https://web.cudamail.com:443/cgi-mod/mark.cgi X-ASG-Whitelist: Header =?UTF-8?B?eFwtY3VkYW1haWxcLXdoaXRlbGlzdFwtdG8=?= X-Virus-Scanned: by bsmtpd at cudamail.com X-Barracuda-BRTS-Status: 1 Subject: [ovs-dev] [PATCH v4] datapath-windows: use ip proto for tunnel port lookup 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" In Actions.c, based on the IP Protocol type and L4 port of the outer packet, we lookup the tunnel port. The function that made this happen took the tunnel type as an argument. Semantically, is is better to pass the IP protocol type and let the lookup code map IP protocol type to tunnel type. In the vport add code, we make sure that we block tunnel port addition if there's already a tunnel port that uses the same IP protocol type and L4 port number. Signed-off-by: Nithin Raju Acked-by: Sairam Venugopal Acked-by: Yin Lin Acked-by: Alin Gabriel Serdean --- datapath-windows/ovsext/Actions.c | 42 ++++++++++++------------- datapath-windows/ovsext/Tunnel.c | 6 ++-- datapath-windows/ovsext/Vport.c | 64 +++++++++++++++++++++++++++++++++++++-- datapath-windows/ovsext/Vport.h | 9 ++++-- 4 files changed, 91 insertions(+), 30 deletions(-) diff --git a/datapath-windows/ovsext/Actions.c b/datapath-windows/ovsext/Actions.c index 72ebc04..7ac6bb7 100644 --- a/datapath-windows/ovsext/Actions.c +++ b/datapath-windows/ovsext/Actions.c @@ -215,32 +215,32 @@ 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. */ + + /* + * For some of the tunnel types such as GRE, the dstPort is not applicable + * since GRE does not have a L4 port. We use '0' for convenience. + */ if (!flowKey->ipKey.nwFrag) { UINT16 dstPort = htons(flowKey->ipKey.l4.tpDst); - 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) { + + ASSERT(flowKey->ipKey.nwProto != IPPROTO_GRE || dstPort == 0); + + tunnelVport = + OvsFindTunnelVportByDstPortAndNWProto(ovsFwdCtx->switchContext, + dstPort, + flowKey->ipKey.nwProto); + if (tunnelVport) { + switch(tunnelVport->ovsType) { + case OVS_VPORT_TYPE_STT: ovsActionStats.rxStt++; - } - break; - case IPPROTO_UDP: - tunnelVport = OvsFindTunnelVportByDstPort(ovsFwdCtx->switchContext, - dstPort, - OVS_VPORT_TYPE_VXLAN); - if (tunnelVport) { + break; + case OVS_VPORT_TYPE_VXLAN: ovsActionStats.rxVxlan++; + break; + case OVS_VPORT_TYPE_GRE: + ovsActionStats.rxGre++; + break; } - break; } } diff --git a/datapath-windows/ovsext/Tunnel.c b/datapath-windows/ovsext/Tunnel.c index 97d2020..c5aae1a 100644 --- a/datapath-windows/ovsext/Tunnel.c +++ b/datapath-windows/ovsext/Tunnel.c @@ -285,9 +285,9 @@ OvsInjectPacketThroughActions(PNET_BUFFER_LIST pNbl, SendFlags |= NDIS_SEND_FLAGS_DISPATCH_LEVEL; - vport = OvsFindTunnelVportByDstPort(gOvsSwitchContext, - htons(tunnelKey.dst_port), - OVS_VPORT_TYPE_VXLAN); + vport = OvsFindTunnelVportByDstPortAndType(gOvsSwitchContext, + htons(tunnelKey.dst_port), + OVS_VPORT_TYPE_VXLAN); if (vport == NULL){ status = STATUS_UNSUCCESSFUL; diff --git a/datapath-windows/ovsext/Vport.c b/datapath-windows/ovsext/Vport.c index b4234e9..fbab61b 100644 --- a/datapath-windows/ovsext/Vport.c +++ b/datapath-windows/ovsext/Vport.c @@ -689,9 +689,9 @@ OvsFindVportByPortNo(POVS_SWITCH_CONTEXT switchContext, POVS_VPORT_ENTRY -OvsFindTunnelVportByDstPort(POVS_SWITCH_CONTEXT switchContext, - UINT16 dstPort, - OVS_VPORT_TYPE ovsPortType) +OvsFindTunnelVportByDstPortAndType(POVS_SWITCH_CONTEXT switchContext, + UINT16 dstPort, + OVS_VPORT_TYPE ovsPortType) { POVS_VPORT_ENTRY vport; PLIST_ENTRY head, link; @@ -709,6 +709,41 @@ OvsFindTunnelVportByDstPort(POVS_SWITCH_CONTEXT switchContext, } POVS_VPORT_ENTRY +OvsFindTunnelVportByDstPortAndNWProto(POVS_SWITCH_CONTEXT switchContext, + UINT16 dstPort, + UINT8 nwProto) +{ + POVS_VPORT_ENTRY vport; + PLIST_ENTRY head, link; + 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 (GetPortFromPriv(vport) == dstPort) { + switch (nwProto) { + case IPPROTO_UDP: + if (vport->ovsType != OVS_VPORT_TYPE_VXLAN) { + continue; + } + break; + case IPPROTO_TCP: + if (vport->ovsType != OVS_VPORT_TYPE_STT) { + continue; + } + break; + case IPPROTO_GRE: + break; + default: + continue; + } + return vport; + } + } + return NULL; +} + +POVS_VPORT_ENTRY OvsFindTunnelVportByPortType(POVS_SWITCH_CONTEXT switchContext, OVS_VPORT_TYPE ovsPortType) { @@ -2220,15 +2255,20 @@ OvsNewVportCmdHandler(POVS_USER_PARAMS_CONTEXT usrParamsCtx, if (OvsIsTunnelVportType(portType)) { UINT16 transportPortDest = 0; + UINT8 nwProto; + POVS_VPORT_ENTRY dupVport; switch (portType) { case OVS_VPORT_TYPE_GRE: + nwProto = IPPROTO_GRE; break; case OVS_VPORT_TYPE_VXLAN: transportPortDest = VXLAN_UDP_PORT; + nwProto = IPPROTO_UDP; break; case OVS_VPORT_TYPE_STT: transportPortDest = STT_TCP_PORT; + nwProto = IPPROTO_TCP; break; default: nlError = NL_ERROR_INVAL; @@ -2243,6 +2283,22 @@ OvsNewVportCmdHandler(POVS_USER_PARAMS_CONTEXT usrParamsCtx, } } + /* + * We don't allow two tunnel ports on identical N/W protocol and + * L4 port number. This is applicable even if the two ports are of + * different tunneling types. + */ + dupVport = + OvsFindTunnelVportByDstPortAndNWProto(gOvsSwitchContext, + transportPortDest, + nwProto); + if (dupVport) { + OVS_LOG_ERROR("Vport for N/W proto and port already exists," + " type: %u, dst port: %u, name: %s", dupVport->ovsType, + transportPortDest, dupVport->ovsName); + goto Cleanup; + } + status = OvsInitTunnelVport(usrParamsCtx, vport, portType, @@ -2317,6 +2373,8 @@ OvsNewVportCmdHandler(POVS_USER_PARAMS_CONTEXT usrParamsCtx, gOvsSwitchContext->dpNo); *replyLen = msgOut->nlMsg.nlmsgLen; + OVS_LOG_INFO("Created new vport, name: %s, type: %u", vport->ovsName, + vport->ovsType); Cleanup: NdisReleaseRWLock(gOvsSwitchContext->dispatchLock, &lockState); diff --git a/datapath-windows/ovsext/Vport.h b/datapath-windows/ovsext/Vport.h index 373896d..f0a9acd 100644 --- a/datapath-windows/ovsext/Vport.h +++ b/datapath-windows/ovsext/Vport.h @@ -145,9 +145,12 @@ POVS_VPORT_ENTRY OvsFindVportByHvNameA(POVS_SWITCH_CONTEXT switchContext, POVS_VPORT_ENTRY OvsFindVportByPortIdAndNicIndex(POVS_SWITCH_CONTEXT switchContext, NDIS_SWITCH_PORT_ID portId, NDIS_SWITCH_NIC_INDEX index); -POVS_VPORT_ENTRY OvsFindTunnelVportByDstPort(POVS_SWITCH_CONTEXT switchContext, - UINT16 dstPort, - OVS_VPORT_TYPE ovsVportType); +POVS_VPORT_ENTRY OvsFindTunnelVportByDstPortAndType(POVS_SWITCH_CONTEXT switchContext, + UINT16 dstPort, + OVS_VPORT_TYPE ovsPortType); +POVS_VPORT_ENTRY OvsFindTunnelVportByDstPortAndNWProto(POVS_SWITCH_CONTEXT switchContext, + UINT16 dstPort, + UINT8 nwProto); POVS_VPORT_ENTRY OvsFindTunnelVportByPortType(POVS_SWITCH_CONTEXT switchContext, OVS_VPORT_TYPE ovsPortType);