Acked-by: Alin Gabriel Serdean <aserd...@cloudbasesolutions.com>
Tested-by: Alin Gabriel Serdean <aserd...@cloudbasesolutions.com>



-----Mesaj original-----
De la: dev [mailto:dev-boun...@openvswitch.org] În numele Nithin Raju
Trimis: Monday, October 13, 2014 6:56 AM
Către: dev@openvswitch.org
Cc: Samuel Ghinet
Subiect: [ovs-dev] [PATCH 2/6] datapath-windows: Add netlink command vport 
delete

Deletion of a vport is now handled both by the netlink command vport delete and 
the hyper-v switch port delete handler. If a netlink command vport delete is 
requested on a vport that has no hyper-v switch port counterpart (i.e., it is a 
tunnel port, or or the hyper-v switch virtual nic is disconnected), the vport 
is deleted and removed.

If the hyper-v switch port delete is requested (i.e. the VNic is
disconnecting) and the ovs (datapath) part is deleted (i.e. was deleted by 
netlink command vport delete, or was never created by an netlink command vport 
new), then the hyper-v switch port delete function handler deletes and removes 
the vport.

If the hyper-v switch port delete is requested while its datapath counterpart 
is still alive, or, when the netlink command vport delete is requested while 
the hyper-v switch port is still alive, the port is only marked that it's part 
is deleted - the field hvDeleted was added to OVS_VPORT_ENTRY to specify if the 
hyper-v switch port side was deleted; if the ovs (datapath) port number is 
invalid, then it means that the ovs (datapath) side of the port is deleted (or, 
not created).

Signed-off-by: Samuel Ghinet <sghi...@cloudbasesolutions.com>
Acked-by: Nithin Raju <nit...@vmware.com>
Acked-by: Ankur Sharma <ankursha...@vmware.com>
Acked-by: Eitan Eliahu <elia...@vmware.com>

---
 datapath-windows/ovsext/Datapath.c |  112 +++++++++++++++++++++++++++++++++++-
 datapath-windows/ovsext/Vport.c    |   21 +++++--
 2 files changed, 126 insertions(+), 7 deletions(-)

diff --git a/datapath-windows/ovsext/Datapath.c 
b/datapath-windows/ovsext/Datapath.c
index e55f29d..19c0834 100644
--- a/datapath-windows/ovsext/Datapath.c
+++ b/datapath-windows/ovsext/Datapath.c
@@ -95,7 +95,8 @@ static NetlinkCmdHandler OvsGetPidCmdHandler,
                          OvsGetDpCmdHandler,
                          OvsSetDpCmdHandler,
                          OvsGetVportCmdHandler,
-                         OvsNewVportCmdHandler;
+                         OvsNewVportCmdHandler,
+                         OvsDeleteVportCmdHandler;
 
 NetlinkCmdHandler        OvsGetNetdevCmdHandler;
 
@@ -199,7 +200,12 @@ NETLINK_CMD nlVportFamilyCmdOps[] = {
       .handler = OvsNewVportCmdHandler,
       .supportedDevOp = OVS_TRANSACTION_DEV_OP,
       .validateDpIndex = TRUE
-    }
+    },
+    { .cmd = OVS_VPORT_CMD_DEL,
+      .handler = OvsDeleteVportCmdHandler,
+      .supportedDevOp = OVS_TRANSACTION_DEV_OP,
+      .validateDpIndex = TRUE
+    },
 };
 
 NETLINK_FAMILY nlVportFamilyOps = {
@@ -1880,6 +1886,108 @@ Cleanup:
     return STATUS_SUCCESS;
 }
 
+
+static NTSTATUS
+OvsDeleteVportCmdHandler(POVS_USER_PARAMS_CONTEXT usrParamsCtx,
+                         UINT32 *replyLen) {
+    NDIS_STATUS status = STATUS_SUCCESS;
+    LOCK_STATE_EX lockState;
+
+    POVS_MESSAGE msgIn = (POVS_MESSAGE)usrParamsCtx->inputBuffer;
+    POVS_MESSAGE msgOut = (POVS_MESSAGE)usrParamsCtx->outputBuffer;
+    POVS_VPORT_ENTRY vport = NULL;
+    NL_ERROR nlError = NL_ERROR_SUCCESS;
+    PSTR portName = NULL;
+    UINT32 portNameLen = 0;
+
+    static const NL_POLICY ovsVportPolicy[] = {
+        [OVS_VPORT_ATTR_PORT_NO] = { .type = NL_A_U32, .optional = TRUE },
+        [OVS_VPORT_ATTR_NAME] = { .type = NL_A_STRING, .maxLen = IFNAMSIZ, 
.optional = TRUE },
+    };
+    PNL_ATTR vportAttrs[ARRAY_SIZE(ovsVportPolicy)];
+
+    ASSERT(usrParamsCtx->inputBuffer != NULL);
+
+    if (!NlAttrParse((PNL_MSG_HDR)msgIn,
+        NLMSG_HDRLEN + GENL_HDRLEN + OVS_HDRLEN,
+        NlMsgAttrsLen((PNL_MSG_HDR)msgIn),
+        ovsVportPolicy, vportAttrs, ARRAY_SIZE(vportAttrs))) {
+        return STATUS_INVALID_PARAMETER;
+    }
+
+    if (msgOut == NULL || usrParamsCtx->outputLength < sizeof *msgOut) {
+        return STATUS_NDIS_INVALID_LENGTH;
+    }
+
+    OvsAcquireCtrlLock();
+    if (!gOvsSwitchContext) {
+        OvsReleaseCtrlLock();
+        return STATUS_INVALID_PARAMETER;
+    }
+    OvsReleaseCtrlLock();
+
+    NdisAcquireRWLockWrite(gOvsSwitchContext->dispatchLock, &lockState, 0);
+    if (vportAttrs[OVS_VPORT_ATTR_NAME] != NULL) {
+        portName = NlAttrGet(vportAttrs[OVS_VPORT_ATTR_NAME]);
+        portNameLen = NlAttrGetSize(vportAttrs[OVS_VPORT_ATTR_NAME]);
+
+        /* the port name is expected to be null-terminated */
+        ASSERT(portName[portNameLen - 1] == '\0');
+
+        vport = OvsFindVportByOvsName(gOvsSwitchContext, portName);
+    }
+    else if (vportAttrs[OVS_VPORT_ATTR_PORT_NO] != NULL) {
+        vport = OvsFindVportByPortNo(gOvsSwitchContext,
+            NlAttrGetU32(vportAttrs[OVS_VPORT_ATTR_PORT_NO]));
+    }
+
+    if (!vport) {
+        nlError = NL_ERROR_NODEV;
+        goto Cleanup;
+    }
+
+    status = OvsCreateMsgFromVport(vport, msgIn, usrParamsCtx->outputBuffer,
+                                   usrParamsCtx->outputLength,
+                                   gOvsSwitchContext->dpNo);
+
+    if (vport->hvDeleted || OvsIsTunnelVportType(vport->ovsType)) {
+        /*
+         * The associated hyper-v switch port is not in created state, or,
+         * there is no hyper-v switch port counterpart (for logical ports).
+         * This means that this datapath port is not mapped to a living
+         * hyper-v switc hport. We can destroy and remove the vport from the
+         * list.
+        */
+        OvsRemoveAndDeleteVport(gOvsSwitchContext, vport);
+    } else {
+        /* The associated hyper-v switch port is in the created state, and the
+         * datapath port is mapped to a living hyper-v switch port. We cannot
+         * destroy the vport and cannot remove it from the list of vports.
+         * Instead, we mark the datapath (ovs) part of the vport as
+         * "not created", i.e. we set vport->portNo = OVS_PORT_NUMBER_INVALID.
+        */
+        vport->portNo = OVS_DPPORT_NUMBER_INVALID;
+        vport->ovsName[0] = '\0';
+    }
+
+    *replyLen = msgOut->nlMsg.nlmsgLen;
+
+Cleanup:
+    NdisReleaseRWLock(gOvsSwitchContext->dispatchLock, &lockState);
+
+    if (nlError != NL_ERROR_SUCCESS) {
+        POVS_MESSAGE_ERROR msgError = (POVS_MESSAGE_ERROR)
+            usrParamsCtx->outputBuffer;
+
+        BuildErrorMsg(msgIn, msgError, nlError);
+        *replyLen = msgError->nlMsg.nlmsgLen;
+    }
+
+    return STATUS_SUCCESS;
+}
+
+
 /*
  * --------------------------------------------------------------------------
  *  Utility function to map the output buffer in an IRP. The buffer is assumed 
diff --git a/datapath-windows/ovsext/Vport.c b/datapath-windows/ovsext/Vport.c 
index 00a9145..61fa71d 100644
--- a/datapath-windows/ovsext/Vport.c
+++ b/datapath-windows/ovsext/Vport.c
@@ -133,24 +133,35 @@ HvTeardownPort(POVS_SWITCH_CONTEXT switchContext,
 
 VOID
 HvDeletePort(POVS_SWITCH_CONTEXT switchContext,
-             PNDIS_SWITCH_PORT_PARAMETERS portParam)
+             PNDIS_SWITCH_PORT_PARAMETERS portParams)
 {
     POVS_VPORT_ENTRY vport;
     LOCK_STATE_EX lockState;
 
-    VPORT_PORT_ENTER(portParam);
+    VPORT_PORT_ENTER(portParams);
 
     NdisAcquireRWLockWrite(switchContext->dispatchLock, &lockState, 0);
     vport = OvsFindVportByPortIdAndNicIndex(switchContext,
-                                            portParam->PortId, 0);
+                                            portParams->PortId, 0);
+
+    /*
+     * XXX: we can only destroy and remove the port if its datapath port
+     * counterpart was deleted. If the datapath port counterpart is present,
+     * we only mark the vport for deletion, so that a netlink command vport
+     * delete will delete the vport.
+    */
     if (vport) {
-        OvsRemoveAndDeleteVport(switchContext, vport);
+        if (vport->portNo == OVS_DPPORT_NUMBER_INVALID) {
+            OvsRemoveAndDeleteVport(switchContext, vport);
+        } else {
+            vport->hvDeleted = TRUE;
+        }
     } else {
         OVS_LOG_WARN("Vport not present.");
     }
     NdisReleaseRWLock(switchContext->dispatchLock, &lockState);
 
-    VPORT_PORT_EXIT(portParam);
+    VPORT_PORT_EXIT(portParams);
 }
 
 
--
1.7.4.1

_______________________________________________
dev mailing list
dev@openvswitch.org
http://openvswitch.org/mailman/listinfo/dev
_______________________________________________
dev mailing list
dev@openvswitch.org
http://openvswitch.org/mailman/listinfo/dev

Reply via email to