hi Alin, LG, but for the comments I had. Acked-by: Nithin Raju <nit...@vmware.com>
On Sep 30, 2014, at 8:00 AM, Samuel Ghinet <sghi...@cloudbasesolutions.com> wrote: > 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> > --- > datapath-windows/ovsext/Datapath.c | 109 ++++++++++++++++++++++++++++++++++++- > datapath-windows/ovsext/Vport.c | 23 +++++--- > 2 files changed, 123 insertions(+), 9 deletions(-) > > diff --git a/datapath-windows/ovsext/Datapath.c > b/datapath-windows/ovsext/Datapath.c > index dc03961..7897330 100644 > --- a/datapath-windows/ovsext/Datapath.c > +++ b/datapath-windows/ovsext/Datapath.c > @@ -104,7 +104,8 @@ static NetlinkCmdHandler OvsGetPidCmdHandler, > OvsSetDpCmdHandler, > OvsReadEventCmdHandler, > OvsGetVportCmdHandler, > - OvsNewVportCmdHandler; > + OvsNewVportCmdHandler, > + OvsDeleteVportCmdHandler; > > static NTSTATUS HandleGetDpTransaction(POVS_USER_PARAMS_CONTEXT usrParamsCtx, > UINT32 *replyLen); > @@ -201,7 +202,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 = { > @@ -1811,6 +1817,105 @@ 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 }, long line. > + }; > + PNL_ATTR vportAttrs[ARRAY_SIZE(ovsVportPolicy)]; > + > + ASSERT(usrParamsCtx->inputBuffer != NULL); > + > + if (!NlAttrParse((PNL_MSG_HDR)msgIn, > + NLMSG_HDRLEN + GENL_HDRLEN + OVS_HDRLEN, > + 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(); CtrlLock should be released after at the end of the function. > + > + 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; Pls. set *replylen only on error. > + > +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 7cee140..d90fd2b 100644 > --- a/datapath-windows/ovsext/Vport.c > +++ b/datapath-windows/ovsext/Vport.c > @@ -121,28 +121,37 @@ HvOnTeardownPort(POVS_SWITCH_CONTEXT switchContext, > VPORT_PORT_EXIT(portParam); > } > > - > - > VOID > HvOnDeletePort(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); Can we ASSERT here that vport->hvDeleted != TRUE. > + if (vport->portNo == OVS_DPPORT_NUMBER_INVALID) { > + OvsRemoveAndDeleteVport(switchContext, vport); > + } else { > + vport->hvDeleted = TRUE; > + } > } else { We should ASSERT here, at least till the code stabilizes. > OVS_LOG_WARN("Vport not present."); > } > NdisReleaseRWLock(switchContext->dispatchLock, &lockState); > > - VPORT_PORT_EXIT(portParam); > + VPORT_PORT_EXIT(portParams); > } > > > -- > 1.8.3.msysgit.0 > Thanks, -- Nithin _______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev