netdev-dpdk: fix mbuf leaks
[cascardo/ovs.git] / datapath-windows / ovsext / Vport.h
index e606e1f..373896d 100644 (file)
 #ifndef __VPORT_H_
 #define __VPORT_H_ 1
 
+#include "Gre.h"
+#include "Stt.h"
 #include "Switch.h"
+#include "VxLan.h"
+
+#define OVS_MAX_DPPORTS             MAXUINT16
+#define OVS_DPPORT_NUMBER_INVALID   OVS_MAX_DPPORTS
+/*
+ * The local port (0) is a reserved port, that is not allowed to be be
+ * created by the netlink command vport add. On linux, this port is created
+ * at netlink command datapath new. However, on windows, we do not need to
+ * create it, and more, we shouldn't. The userspace attempts to create two
+ * internal vports, the LOCAL port (0) and the internal port (with any other
+ * port number). The non-LOCAL internal port is used in the userspace when it
+ * requests the internal port.
+ */
+#define OVS_DPPORT_NUMBER_LOCAL    0
 
 /*
  * A Vport, or Virtual Port, is a port on the OVS. It can be one of the
@@ -60,11 +76,13 @@ typedef struct _OVS_VPORT_FULL_STATS {
 /*
  * Each internal, external adapter or vritual adapter has
  * one vport entry. In addition, we have one vport for each
- * tunnel type, such as vxlan, gre, gre64
+ * tunnel type, such as vxlan, gre
  */
 typedef struct _OVS_VPORT_ENTRY {
-    LIST_ENTRY             nameLink;
-    LIST_ENTRY             portLink;
+    LIST_ENTRY             ovsNameLink;
+    LIST_ENTRY             portIdLink;
+    LIST_ENTRY             portNoLink;
+    LIST_ENTRY             tunnelVportLink;
 
     OVS_VPORT_STATE        ovsState;
     OVS_VPORT_TYPE         ovsType;
@@ -72,45 +90,66 @@ typedef struct _OVS_VPORT_ENTRY {
     OVS_VPORT_ERR_STATS    errStats;
     UINT32                 portNo;
     UINT32                 mtu;
+    /* ovsName is the ovs (datapath) port name - it is null terminated. */
     CHAR                   ovsName[OVS_MAX_PORT_NAME_LENGTH];
-    UINT32                 ovsNameLen;
 
     PVOID                  priv;
     NDIS_SWITCH_PORT_ID    portId;
     NDIS_SWITCH_NIC_INDEX  nicIndex;
+    NDIS_SWITCH_NIC_TYPE   nicType;
     UINT16                 numaNodeId;
     NDIS_SWITCH_PORT_STATE portState;
     NDIS_SWITCH_NIC_STATE  nicState;
     NDIS_SWITCH_PORT_TYPE  portType;
-    BOOLEAN                isValidationPort;
 
-    UINT8                  permMacAddress[MAC_ADDRESS_LEN];
-    UINT8                  currMacAddress[MAC_ADDRESS_LEN];
-    UINT8                  vmMacAddress[MAC_ADDRESS_LEN];
+    UINT8                  permMacAddress[ETH_ADDR_LEN];
+    UINT8                  currMacAddress[ETH_ADDR_LEN];
+    UINT8                  vmMacAddress[ETH_ADDR_LEN];
 
-    NDIS_SWITCH_PORT_NAME  portName;
+    NDIS_SWITCH_PORT_NAME  hvPortName;
+    IF_COUNTED_STRING      portFriendlyName;
     NDIS_SWITCH_NIC_NAME   nicName;
     NDIS_VM_NAME           vmName;
     GUID                   netCfgInstanceId;
+    /*
+     * OVS userpace has a notion of bridges which basically defines an
+     * L2-domain. Each "bridge" has an "internal" port of type
+     * OVS_VPORT_TYPE_INTERNAL. Such a port is connected to the OVS datapath in
+     * one end, and the other end is a virtual adapter on the hypervisor host.
+     * This is akin to the Hyper-V "internal" NIC. It is intuitive to map the
+     * Hyper-V "internal" NIC to the OVS bridge's "internal" port, but there's
+     * only one Hyper-V NIC but multiple bridges. To support multiple OVS bridge
+     * "internal" ports, we use the flag 'isBridgeInternal' in each vport. We
+     * support addition of multiple bridge-internal ports. A vport with
+     * 'isBridgeInternal' == TRUE is a dummy port and has no backing currently.
+     * If a flow actions specifies the output port to be a bridge-internal port,
+     * the port is silently ignored.
+     */
+    BOOLEAN                isBridgeInternal;
     BOOLEAN                isExternal;
     UINT32                 upcallPid; /* netlink upcall port id */
+    PNL_ATTR               portOptions;
+    BOOLEAN                isAbsentOnHv; /* Is this port present on the
+                                             Hyper-V switch? */
 } OVS_VPORT_ENTRY, *POVS_VPORT_ENTRY;
 
 struct _OVS_SWITCH_CONTEXT;
 
-#define OVS_IS_VPORT_ENTRY_NULL(_SwitchContext, _i) \
-   ((UINT64)(_SwitchContext)->vportArray[_i] <= 0xff)
-
-POVS_VPORT_ENTRY
-OvsFindVportByPortNo(struct _OVS_SWITCH_CONTEXT *switchContext,
-                     UINT32 portNo);
-POVS_VPORT_ENTRY
-OvsFindVportByOvsName(struct _OVS_SWITCH_CONTEXT *switchContext,
-                      CHAR *name, UINT32 length);
-POVS_VPORT_ENTRY
-OvsFindVportByPortIdAndNicIndex(struct _OVS_SWITCH_CONTEXT *switchContext,
-                                NDIS_SWITCH_PORT_ID portId,
-                                NDIS_SWITCH_NIC_INDEX index);
+POVS_VPORT_ENTRY OvsFindVportByPortNo(POVS_SWITCH_CONTEXT switchContext,
+                                      UINT32 portNo);
+/* "name" is null-terminated */
+POVS_VPORT_ENTRY OvsFindVportByOvsName(POVS_SWITCH_CONTEXT switchContext,
+                                       PSTR name);
+POVS_VPORT_ENTRY OvsFindVportByHvNameA(POVS_SWITCH_CONTEXT switchContext,
+                                       PSTR name);
+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 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);
@@ -120,6 +159,9 @@ VOID OvsClearAllSwitchVports(struct _OVS_SWITCH_CONTEXT *switchContext);
 NDIS_STATUS HvCreateNic(POVS_SWITCH_CONTEXT switchContext,
                         PNDIS_SWITCH_NIC_PARAMETERS nicParam);
 NDIS_STATUS HvCreatePort(POVS_SWITCH_CONTEXT switchContext,
+                         PNDIS_SWITCH_PORT_PARAMETERS portParam,
+                         NDIS_SWITCH_NIC_INDEX nicIndex);
+NDIS_STATUS HvUpdatePort(POVS_SWITCH_CONTEXT switchContext,
                          PNDIS_SWITCH_PORT_PARAMETERS portParam);
 VOID HvTeardownPort(POVS_SWITCH_CONTEXT switchContext,
                     PNDIS_SWITCH_PORT_PARAMETERS portParam);
@@ -138,8 +180,15 @@ static __inline BOOLEAN
 OvsIsTunnelVportType(OVS_VPORT_TYPE ovsType)
 {
     return ovsType == OVS_VPORT_TYPE_VXLAN ||
-           ovsType == OVS_VPORT_TYPE_GRE ||
-           ovsType == OVS_VPORT_TYPE_GRE64;
+           ovsType == OVS_VPORT_TYPE_STT ||
+           ovsType == OVS_VPORT_TYPE_GRE;
+}
+
+
+static __inline PVOID
+GetOvsVportPriv(POVS_VPORT_ENTRY ovsVport)
+{
+    return ovsVport->priv;
 }
 
 static __inline BOOLEAN
@@ -149,43 +198,88 @@ OvsIsInternalVportType(OVS_VPORT_TYPE ovsType)
 }
 
 static __inline BOOLEAN
-OvsIsTunnelVportNo(UINT32 portNo)
+OvsIsVirtualExternalVport(POVS_VPORT_ENTRY vport)
 {
-    UINT32 idx = OVS_VPORT_INDEX(portNo);
-    return (idx >= OVS_TUNNEL_INDEX_START && idx <= OVS_TUNNEL_INDEX_END);
+    return vport->nicType == NdisSwitchNicTypeExternal &&
+           vport->nicIndex == 0;
 }
 
 static __inline BOOLEAN
-OvsIsVifVportNo(UINT32 portNo)
+OvsIsRealExternalVport(POVS_VPORT_ENTRY vport)
 {
-    UINT32 idx = OVS_VPORT_INDEX(portNo);
-    return (idx >= OVS_VM_VPORT_START && idx <= OVS_VM_VPORT_MAX);
+    return vport->nicType == NdisSwitchNicTypeExternal &&
+           vport->nicIndex != 0;
 }
 
-static __inline POVS_VPORT_ENTRY
-OvsGetTunnelVport(OVS_VPORT_TYPE type)
+static __inline BOOLEAN
+OvsIsBridgeInternalVport(POVS_VPORT_ENTRY vport)
 {
-    ASSERT(OvsIsTunnelVportType(type));
-    switch(type) {
-    case OVS_VPORT_TYPE_VXLAN:
-        return (POVS_VPORT_ENTRY) OvsGetVportFromIndex(OVS_VXLAN_VPORT_INDEX);
-    default:
-        ASSERT(! "OvsGetTunnelVport not implemented for this tunnel.");
-    }
+    ASSERT(vport->isBridgeInternal != TRUE ||
+           vport->ovsType == OVS_VPORT_TYPE_INTERNAL);
+    return vport->isBridgeInternal == TRUE;
+}
+
+static __inline BOOLEAN
+OvsIsInternalNIC(NDIS_SWITCH_NIC_TYPE   nicType)
+{
+    return nicType == NdisSwitchNicTypeInternal;
+}
 
-    return NULL;
+static __inline BOOLEAN
+OvsIsRealExternalNIC(NDIS_SWITCH_NIC_TYPE   nicType,
+                     NDIS_SWITCH_NIC_INDEX  nicIndex)
+{
+    return nicType == NdisSwitchNicTypeExternal &&
+           nicIndex != 0;
 }
 
-static __inline PVOID
-OvsGetVportPriv(OVS_VPORT_TYPE type)
+NTSTATUS OvsRemoveAndDeleteVport(PVOID usrParamsCtx,
+                                 POVS_SWITCH_CONTEXT switchContext,
+                                 POVS_VPORT_ENTRY vport,
+                                 BOOLEAN hvDelete, BOOLEAN ovsDelete);
+static __inline POVS_VPORT_ENTRY
+OvsGetExternalVport(POVS_SWITCH_CONTEXT switchContext)
 {
-    return OvsGetTunnelVport(type)->priv;
+    return switchContext->virtualExternalVport;
 }
 
 static __inline UINT32
-OvsGetExternalMtu()
+OvsGetExternalMtu(POVS_SWITCH_CONTEXT switchContext)
+{
+    ASSERT(OvsGetExternalVport(switchContext));
+    return ((POVS_VPORT_ENTRY) OvsGetExternalVport(switchContext))->mtu;
+}
+
+static __inline UINT16
+GetPortFromPriv(POVS_VPORT_ENTRY vport)
 {
-    return ((POVS_VPORT_ENTRY) OvsGetExternalVport())->mtu;
+    UINT16 dstPort = 0;
+    PVOID vportPriv = GetOvsVportPriv(vport);
+
+    /* XXX would better to have a commom tunnel "parent" structure */
+    ASSERT(vportPriv);
+    switch(vport->ovsType) {
+    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 || vport->ovsType == OVS_VPORT_TYPE_GRE);
+    return dstPort;
 }
 
+NDIS_STATUS InitOvsVportCommon(POVS_SWITCH_CONTEXT switchContext,
+                               POVS_VPORT_ENTRY vport);
+NTSTATUS OvsInitTunnelVport(PVOID usrParamsCtx, POVS_VPORT_ENTRY vport,
+                            OVS_VPORT_TYPE ovsType, UINT16 dstport);
+NTSTATUS OvsInitBridgeInternalVport(POVS_VPORT_ENTRY vport);
+
+POVS_VPORT_ENTRY OvsAllocateVport(VOID);
+
 #endif /* __VPORT_H_ */