[ovs-dev] [PATCH] datapath-windows: fix OVS_VPORT_TYPE

Samuel Ghinet sghinet at cloudbasesolutions.com
Wed Sep 17 13:06:43 UTC 2014


The windows ovs kernel uses an OVS_VPORT_TYPE enum that is incompatible with
the userspace counterpart (enum ovs_vport_type from openvswitch.h). We must use
the same enum type - enum ovs_vport_type - for the netlink communication to work
properly.

This patch makes the fix: "typedef enum ovs_vport_type OVS_VPORT_TYPE" and
changes the afferent kernel driver code:
o) vport types synthetic and emulated turn to: netdev
o) vport type internal turns to: internal
o) vport type external truns to: netdev (plus, we hold a field in vport, "isExternal")

This patch is required for the ovs-dpctl show and vswitchd vport commands to work
properly.

Signed-off-by: Samuel Ghinet <sghinet at cloudbasesolutions.com>
---
 datapath-windows/include/OvsDpInterfaceExt.h |  2 +
 datapath-windows/include/OvsPub.h            | 25 ++-------
 datapath-windows/ovsext/Actions.c            |  6 +--
 datapath-windows/ovsext/Tunnel.c             |  4 +-
 datapath-windows/ovsext/Vport.c              | 81 ++++++++++++++--------------
 datapath-windows/ovsext/Vport.h              | 11 ++--
 datapath-windows/ovsext/Vxlan.c              |  4 +-
 datapath-windows/ovsext/precomp.h            | 12 ++---
 8 files changed, 67 insertions(+), 78 deletions(-)

diff --git a/datapath-windows/include/OvsDpInterfaceExt.h b/datapath-windows/include/OvsDpInterfaceExt.h
index 877b2ad..9624894 100644
--- a/datapath-windows/include/OvsDpInterfaceExt.h
+++ b/datapath-windows/include/OvsDpInterfaceExt.h
@@ -80,4 +80,6 @@ enum ovs_nl_mcast_attr {
     OVS_NL_ATTR_MCAST_JOIN,  /* (UINT8) 1/0 - Join/Unjoin */
 };
 
+typedef enum ovs_vport_type OVS_VPORT_TYPE;
+
 #endif /* __OVS_DP_INTERFACE_EXT_H_ */
diff --git a/datapath-windows/include/OvsPub.h b/datapath-windows/include/OvsPub.h
index 36814c4..ff0e8ce 100644
--- a/datapath-windows/include/OvsPub.h
+++ b/datapath-windows/include/OvsPub.h
@@ -142,34 +142,19 @@ typedef struct _OVS_VPORT_GET {
     char     name[OVS_MAX_PORT_NAME_LENGTH];
 } OVS_VPORT_GET, *POVS_VPORT_GET;
 
-
-typedef enum {
-    OVSWIN_VPORT_TYPE_UNKNOWN,
-    OVSWIN_VPORT_TYPE_RESERVED,
-    OVSWIN_VPORT_TYPE_EXTERNAL,
-    OVSWIN_VPORT_TYPE_INTERNAL,
-    OVSWIN_VPORT_TYPE_SYNTHETIC,
-    OVSWIN_VPORT_TYPE_EMULATED,
-    OVSWIN_VPORT_TYPE_GRE,
-    OVSWIN_VPORT_TYPE_GRE64,
-    OVSWIN_VPORT_TYPE_VXLAN,
-    OVSWIN_VPORT_TYPE_LOCAL,    /* For bridge local port. */
-} OVS_VPORT_TYPE;
-
 static __inline const char *
 OvsVportTypeToStr(OVS_VPORT_TYPE t)
 {
     switch(t) {
-#define STR(t) case OVSWIN_VPORT_TYPE_##t : return "VPORT_##t";
-    STR(UNKNOWN)
-    STR(EXTERNAL)
+#define STR(t) case OVS_VPORT_TYPE_##t : return "VPORT_##t";
+    STR(UNSPEC)
+    STR(NETDEV)
     STR(INTERNAL)
-    STR(SYNTHETIC)
-    STR(EMULATED)
     STR(GRE)
     STR(GRE64)
     STR(VXLAN)
-    STR(LOCAL)
+    STR(GENEVE)
+    STR(LISP)
     }
 #undef STR
 
diff --git a/datapath-windows/ovsext/Actions.c b/datapath-windows/ovsext/Actions.c
index 35ebfdf..180b6b8 100644
--- a/datapath-windows/ovsext/Actions.c
+++ b/datapath-windows/ovsext/Actions.c
@@ -205,7 +205,7 @@ OvsDetectTunnelRxPkt(OvsForwardingContext *ovsFwdCtx,
     if (!flowKey->ipKey.nwFrag &&
         flowKey->ipKey.nwProto == IPPROTO_UDP &&
         flowKey->ipKey.l4.tpDst == VXLAN_UDP_PORT_NBO) {
-        tunnelVport = OvsGetTunnelVport(OVSWIN_VPORT_TYPE_VXLAN);
+        tunnelVport = OvsGetTunnelVport(OVS_VPORT_TYPE_VXLAN);
         ovsActionStats.rxVxlan++;
     }
 
@@ -616,7 +616,7 @@ OvsTunnelPortTx(OvsForwardingContext *ovsFwdCtx)
 
     /* Do the encap. Encap function does not consume the NBL. */
     switch(ovsFwdCtx->tunnelTxNic->ovsType) {
-    case OVSWIN_VPORT_TYPE_VXLAN:
+    case OVS_VPORT_TYPE_VXLAN:
         status = OvsEncapVxlan(ovsFwdCtx->curNbl, &ovsFwdCtx->tunKey,
                                ovsFwdCtx->switchContext,
                                (VOID *)ovsFwdCtx->completionList,
@@ -678,7 +678,7 @@ OvsTunnelPortRx(OvsForwardingContext *ovsFwdCtx)
     }
 
     switch(tunnelRxVport->ovsType) {
-    case OVSWIN_VPORT_TYPE_VXLAN:
+    case OVS_VPORT_TYPE_VXLAN:
         /*
          * OvsDoDecapVxlan should return a new NBL if it was copied, and
          * this new NBL should be setup as the ovsFwdCtx->curNbl.
diff --git a/datapath-windows/ovsext/Tunnel.c b/datapath-windows/ovsext/Tunnel.c
index 2e7da10..304ab59 100644
--- a/datapath-windows/ovsext/Tunnel.c
+++ b/datapath-windows/ovsext/Tunnel.c
@@ -284,14 +284,14 @@ OvsInjectPacketThroughActions(PNET_BUFFER_LIST pNbl,
 
         SendFlags |= NDIS_SEND_FLAGS_DISPATCH_LEVEL;
 
-        vport = OvsGetTunnelVport(OVSWIN_VPORT_TYPE_VXLAN);
+        vport = OvsGetTunnelVport(OVS_VPORT_TYPE_VXLAN);
 
         if (vport == NULL){
             status = STATUS_UNSUCCESSFUL;
             goto unlockAndDrop;
         }
 
-        ASSERT(vport->ovsType == OVSWIN_VPORT_TYPE_VXLAN);
+        ASSERT(vport->ovsType == OVS_VPORT_TYPE_VXLAN);
 
         portNo = vport->portNo;
 
diff --git a/datapath-windows/ovsext/Vport.c b/datapath-windows/ovsext/Vport.c
index 0d1e4ab..14b68d9 100644
--- a/datapath-windows/ovsext/Vport.c
+++ b/datapath-windows/ovsext/Vport.c
@@ -50,7 +50,8 @@ extern POVS_SWITCH_CONTEXT gOvsSwitchContext;
 extern PNDIS_SPIN_LOCK gOvsCtrlLock;
 
 static UINT32 OvsGetVportNo(POVS_SWITCH_CONTEXT switchContext, UINT32 nicIndex,
-                            OVS_VPORT_TYPE ovsType);
+                            OVS_VPORT_TYPE ovsType,
+                            BOOLEAN isExternal);
 static POVS_VPORT_ENTRY OvsAllocateVport(VOID);
 static VOID OvsInitVportWithPortParam(POVS_VPORT_ENTRY vport,
                 PNDIS_SWITCH_PORT_PARAMETERS portParam);
@@ -380,7 +381,7 @@ OvsDisconnectNic(POVS_SWITCH_CONTEXT switchContext,
     vport->ovsState = OVS_STATE_NIC_CREATED;
     portNo = vport->portNo;
 
-    if (vport->ovsType == OVSWIN_VPORT_TYPE_INTERNAL) {
+    if (vport->ovsType == OVS_VPORT_TYPE_INTERNAL) {
         isInternalPort = TRUE;
     }
 
@@ -520,13 +521,13 @@ OvsFindVportByPortIdAndNicIndex(POVS_SWITCH_CONTEXT switchContext,
 static UINT32
 OvsGetVportNo(POVS_SWITCH_CONTEXT switchContext,
               UINT32 nicIndex,
-              OVS_VPORT_TYPE ovsType)
+              OVS_VPORT_TYPE ovsType,
+              BOOLEAN isExternal)
 {
     UINT32 index = 0xffffff, i = 0;
     UINT64 gen;
 
-    switch (ovsType) {
-    case OVSWIN_VPORT_TYPE_EXTERNAL:
+    if (isExternal) {
         if (nicIndex == 0) {
             return 0;  // not a valid portNo
         } else if (nicIndex > OVS_MAX_PHYS_ADAPTERS) {
@@ -534,12 +535,13 @@ OvsGetVportNo(POVS_SWITCH_CONTEXT switchContext,
         } else {
             index = nicIndex + OVS_EXTERNAL_VPORT_START;
         }
-        break;
-    case OVSWIN_VPORT_TYPE_INTERNAL:
+    }
+
+    switch (ovsType) {
+    case OVS_VPORT_TYPE_INTERNAL:
         index = OVS_INTERNAL_VPORT_DEFAULT_INDEX;
         break;
-    case OVSWIN_VPORT_TYPE_SYNTHETIC:
-    case OVSWIN_VPORT_TYPE_EMULATED:
+    case OVS_VPORT_TYPE_NETDEV:
         index = switchContext->lastPortIndex + 1;
         if (index == OVS_MAX_VPORT_ARRAY_SIZE) {
             index = OVS_VM_VPORT_START;
@@ -557,18 +559,17 @@ OvsGetVportNo(POVS_SWITCH_CONTEXT switchContext,
         }
         switchContext->lastPortIndex = index;
         break;
-    case OVSWIN_VPORT_TYPE_GRE:
+    case OVS_VPORT_TYPE_GRE:
         index = OVS_GRE_VPORT_INDEX;
         break;
-    case OVSWIN_VPORT_TYPE_GRE64:
+    case OVS_VPORT_TYPE_GRE64:
         index = OVS_GRE64_VPORT_INDEX;
         break;
-    case OVSWIN_VPORT_TYPE_VXLAN:
+    case OVS_VPORT_TYPE_VXLAN:
         index = OVS_VXLAN_VPORT_INDEX;
         break;
-    case OVSWIN_VPORT_TYPE_LOCAL:
     default:
-        ASSERT(0);
+        ASSERT(isExternal);
     }
     if (index > OVS_MAX_VPORT_ARRAY_SIZE) {
         return 0;
@@ -605,19 +606,19 @@ OvsInitVportWithPortParam(POVS_VPORT_ENTRY vport,
     vport->portState = portParam->PortState;
     vport->portId = portParam->PortId;
     vport->nicState = NdisSwitchNicStateUnknown;
+    vport->isExternal = FALSE;
 
     switch (vport->portType) {
     case NdisSwitchPortTypeExternal:
-        vport->ovsType = OVSWIN_VPORT_TYPE_EXTERNAL;
+        vport->isExternal = TRUE;
+        vport->ovsType = OVS_VPORT_TYPE_NETDEV;
         break;
     case NdisSwitchPortTypeInternal:
-        vport->ovsType = OVSWIN_VPORT_TYPE_INTERNAL;
+        vport->ovsType = OVS_VPORT_TYPE_INTERNAL;
         break;
     case NdisSwitchPortTypeSynthetic:
-        vport->ovsType = OVSWIN_VPORT_TYPE_SYNTHETIC;
-        break;
     case NdisSwitchPortTypeEmulated:
-        vport->ovsType = OVSWIN_VPORT_TYPE_EMULATED;
+        vport->ovsType = OVS_VPORT_TYPE_NETDEV;
         break;
     }
     RtlCopyMemory(&vport->portName, &portParam->PortName,
@@ -694,7 +695,8 @@ OvsInitPhysNicVport(POVS_VPORT_ENTRY vport,
     vport->portState = virtVport->portState;
     vport->portId = virtVport->portId;
     vport->nicState = NdisSwitchNicStateUnknown;
-    vport->ovsType = OVSWIN_VPORT_TYPE_EXTERNAL;
+    vport->ovsType = OVS_VPORT_TYPE_NETDEV;
+    vport->isExternal = TRUE;
     vport->nicIndex = (NDIS_SWITCH_NIC_INDEX)nicIndex;
     RtlCopyMemory(&vport->portName, &virtVport->portName,
                   sizeof (NDIS_SWITCH_PORT_NAME));
@@ -709,7 +711,7 @@ POVS_VPORT_ENTRY vport)
     if (vport->portType != NdisSwitchPortTypeExternal ||
         vport->nicIndex != 0) {
         vport->portNo = OvsGetVportNo(switchContext, vport->nicIndex,
-            vport->ovsType);
+            vport->ovsType, vport->portType == NdisSwitchPortTypeExternal);
         if (vport->portNo == 0) {
             return NDIS_STATUS_RESOURCES;
         }
@@ -769,8 +771,8 @@ OvsRemoveAndDeleteVport(POVS_SWITCH_CONTEXT switchContext,
                         POVS_VPORT_ENTRY vport)
 {
     UINT64 gen = vport->portNo >> 24;
-    switch (vport->ovsType) {
-    case OVSWIN_VPORT_TYPE_EXTERNAL:
+
+    if (vport->isExternal) {
         if (vport->nicIndex == 0) {
             ASSERT(switchContext->numPhysicalNics == 0);
             switchContext->externalPortId = 0;
@@ -781,20 +783,21 @@ OvsRemoveAndDeleteVport(POVS_SWITCH_CONTEXT switchContext,
             ASSERT(switchContext->numPhysicalNics);
             switchContext->numPhysicalNics--;
         }
-        break;
-    case OVSWIN_VPORT_TYPE_INTERNAL:
+    }
+
+    switch (vport->ovsType) {
+    case OVS_VPORT_TYPE_INTERNAL:
         switchContext->internalPortId = 0;
         switchContext->internalVport = NULL;
         OvsInternalAdapterDown();
         break;
-    case OVSWIN_VPORT_TYPE_VXLAN:
+    case OVS_VPORT_TYPE_VXLAN:
         OvsCleanupVxlanTunnel(vport);
         break;
-    case OVSWIN_VPORT_TYPE_GRE:
-    case OVSWIN_VPORT_TYPE_GRE64:
+    case OVS_VPORT_TYPE_GRE:
+    case OVS_VPORT_TYPE_GRE64:
         break;
-    case OVSWIN_VPORT_TYPE_EMULATED:
-    case OVSWIN_VPORT_TYPE_SYNTHETIC:
+    case OVS_VPORT_TYPE_NETDEV:
     default:
         break;
     }
@@ -1074,11 +1077,11 @@ OvsInitTunnelVport(POVS_VPORT_ENTRY vport,
     StringCbLengthA(vport->ovsName, OVS_MAX_PORT_NAME_LENGTH - 1, &len);
     vport->ovsNameLen = (UINT32)len;
     switch (addReq->type) {
-    case OVSWIN_VPORT_TYPE_GRE:
+    case OVS_VPORT_TYPE_GRE:
         break;
-    case OVSWIN_VPORT_TYPE_GRE64:
+    case OVS_VPORT_TYPE_GRE64:
         break;
-    case OVSWIN_VPORT_TYPE_VXLAN:
+    case OVS_VPORT_TYPE_VXLAN:
         status = OvsInitVxlanTunnel(vport, addReq);
         break;
     default:
@@ -1113,13 +1116,13 @@ OvsAddVportIoctl(PVOID inputBuffer,
     addReq->name[OVS_MAX_PORT_NAME_LENGTH - 1] = 0;
 
     switch (addReq->type) {
-    case OVSWIN_VPORT_TYPE_GRE:
+    case OVS_VPORT_TYPE_GRE:
         index = OVS_GRE_VPORT_INDEX;
         break;
-    case OVSWIN_VPORT_TYPE_GRE64:
+    case OVS_VPORT_TYPE_GRE64:
         index = OVS_GRE64_VPORT_INDEX;
         break;
-    case OVSWIN_VPORT_TYPE_VXLAN:
+    case OVS_VPORT_TYPE_VXLAN:
         index = OVS_VXLAN_VPORT_INDEX;
         break;
     default:
@@ -1338,8 +1341,7 @@ OvsGetExtInfoIoctl(PVOID inputBuffer,
                   sizeof (vport->currMacAddress));
     RtlCopyMemory(info->permMACAddress, vport->permMacAddress,
                   sizeof (vport->permMacAddress));
-    if (vport->ovsType == OVSWIN_VPORT_TYPE_SYNTHETIC ||
-        vport->ovsType == OVSWIN_VPORT_TYPE_EMULATED) {
+    if (vport->ovsType == OVS_VPORT_TYPE_NETDEV) {
         RtlCopyMemory(info->vmMACAddress, vport->vmMacAddress,
                       sizeof (vport->vmMacAddress));
     }
@@ -1357,8 +1359,7 @@ OvsGetExtInfoIoctl(PVOID inputBuffer,
     } else {
        info->status = OVS_EVENT_DISCONNECT;
     }
-    if ((info->type == OVSWIN_VPORT_TYPE_SYNTHETIC ||
-         info->type == OVSWIN_VPORT_TYPE_EMULATED) &&
+    if (info->type == OVS_VPORT_TYPE_NETDEV &&
         (vport->ovsState == OVS_STATE_NIC_CREATED  ||
          vport->ovsState == OVS_STATE_CONNECTED)) {
         RtlCopyMemory(&vmName, &vport->vmName, sizeof (NDIS_VM_NAME));
diff --git a/datapath-windows/ovsext/Vport.h b/datapath-windows/ovsext/Vport.h
index 0305d35..577c23d 100644
--- a/datapath-windows/ovsext/Vport.h
+++ b/datapath-windows/ovsext/Vport.h
@@ -93,6 +93,7 @@ typedef struct _OVS_VPORT_ENTRY {
     NDIS_VM_NAME           vmName;
     GUID                   netCfgInstanceId;
     UINT32                 upcallPid; /* netlink upcall port id */
+    BOOLEAN                isExternal;
 } OVS_VPORT_ENTRY, *POVS_VPORT_ENTRY;
 
 struct _OVS_SWITCH_CONTEXT;
@@ -150,15 +151,15 @@ VOID OvsDisconnectNic(POVS_SWITCH_CONTEXT switchContext,
 static __inline BOOLEAN
 OvsIsTunnelVportType(OVS_VPORT_TYPE ovsType)
 {
-    return ovsType == OVSWIN_VPORT_TYPE_VXLAN ||
-           ovsType == OVSWIN_VPORT_TYPE_GRE ||
-           ovsType == OVSWIN_VPORT_TYPE_GRE64;
+    return ovsType == OVS_VPORT_TYPE_VXLAN ||
+           ovsType == OVS_VPORT_TYPE_GRE ||
+           ovsType == OVS_VPORT_TYPE_GRE64;
 }
 
 static __inline BOOLEAN
 OvsIsInternalVportType(OVS_VPORT_TYPE ovsType)
 {
-    return ovsType == OVSWIN_VPORT_TYPE_INTERNAL;
+    return ovsType == OVS_VPORT_TYPE_INTERNAL;
 }
 
 static __inline BOOLEAN
@@ -180,7 +181,7 @@ OvsGetTunnelVport(OVS_VPORT_TYPE type)
 {
     ASSERT(OvsIsTunnelVportType(type));
     switch(type) {
-    case OVSWIN_VPORT_TYPE_VXLAN:
+    case OVS_VPORT_TYPE_VXLAN:
         return (POVS_VPORT_ENTRY) OvsGetVportFromIndex(OVS_VXLAN_VPORT_INDEX);
     default:
         ASSERT(! "OvsGetTunnelVport not implemented for this tunnel.");
diff --git a/datapath-windows/ovsext/Vxlan.c b/datapath-windows/ovsext/Vxlan.c
index 3a1291c..7f94634 100644
--- a/datapath-windows/ovsext/Vxlan.c
+++ b/datapath-windows/ovsext/Vxlan.c
@@ -57,7 +57,7 @@ OvsInitVxlanTunnel(POVS_VPORT_ENTRY vport,
     POVS_VXLAN_VPORT vxlanPort;
     NTSTATUS status = STATUS_SUCCESS;
 
-    ASSERT(addReq->type == OVSWIN_VPORT_TYPE_VXLAN);
+    ASSERT(addReq->type == OVS_VPORT_TYPE_VXLAN);
 
     vxlanPort = OvsAllocateMemory(sizeof (*vxlanPort));
     if (vxlanPort == NULL) {
@@ -80,7 +80,7 @@ OvsInitVxlanTunnel(POVS_VPORT_ENTRY vport,
 VOID
 OvsCleanupVxlanTunnel(POVS_VPORT_ENTRY vport)
 {
-    if (vport->ovsType != OVSWIN_VPORT_TYPE_VXLAN ||
+    if (vport->ovsType != OVS_VPORT_TYPE_VXLAN ||
         vport->priv == NULL) {
         return;
     }
diff --git a/datapath-windows/ovsext/precomp.h b/datapath-windows/ovsext/precomp.h
index 765075a..6e40308 100644
--- a/datapath-windows/ovsext/precomp.h
+++ b/datapath-windows/ovsext/precomp.h
@@ -22,15 +22,15 @@
 #include <Strsafe.h>
 
 #include "Types.h"
-#include "..\include\OvsPub.h"
+
+#include "..\include\OvsDpInterface.h"
+
 #include "Util.h"
 #include "Netlink/Netlink.h"
 #include "Netlink/NetlinkProto.h"
-/*
- * Include openvswitch.h from userspace. Changing the location the file from
- * include/linux is pending discussion.
- */
-#include "..\include\OvsDpInterface.h"
+
 #if defined OVS_USE_NL_INTERFACE && OVS_USE_NL_INTERFACE == 1
 #include "..\include\OvsDpInterfaceExt.h"
 #endif
+
+#include "..\include\OvsPub.h"
\ No newline at end of file
-- 
1.8.3.msysgit.0




More information about the dev mailing list