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