-NTSTATUS
-OvsAddVportIoctl(PVOID inputBuffer,
- UINT32 inputLength,
- PVOID outputBuffer,
- UINT32 outputLength,
- UINT32 *replyLen)
-{
- NTSTATUS status = STATUS_SUCCESS;
- POVS_VPORT_INFO vportInfo;
- POVS_VPORT_ADD_REQUEST addReq;
- POVS_VPORT_ENTRY vport;
- LOCK_STATE_EX lockState;
- UINT32 index;
- UINT32 portNo;
-
- OVS_LOG_TRACE("Enter: inputLength: %u, outputLength: %u",
- inputLength, outputLength);
- if (inputLength < sizeof (OVS_VPORT_ADD_REQUEST) ||
- outputLength < sizeof (OVS_VPORT_INFO)) {
- status = STATUS_INVALID_PARAMETER;
- goto vport_add_done;
- }
- addReq = (POVS_VPORT_ADD_REQUEST)inputBuffer;
- addReq->name[OVS_MAX_PORT_NAME_LENGTH - 1] = 0;
-
- switch (addReq->type) {
- case OVS_VPORT_TYPE_GRE:
- index = OVS_GRE_VPORT_INDEX;
- break;
- case OVS_VPORT_TYPE_GRE64:
- index = OVS_GRE64_VPORT_INDEX;
- break;
- case OVS_VPORT_TYPE_VXLAN:
- index = OVS_VXLAN_VPORT_INDEX;
- break;
- default:
- status = STATUS_NOT_SUPPORTED;
- goto vport_add_done;
- }
-
- vport = (POVS_VPORT_ENTRY)OvsAllocateVport();
- if (vport == NULL) {
- status = STATUS_INSUFFICIENT_RESOURCES;
- goto vport_add_done;
- }
-
- NdisAcquireSpinLock(gOvsCtrlLock);
- if (gOvsSwitchContext == NULL ||
- gOvsSwitchContext->dpNo != addReq->dpNo) {
- NdisReleaseSpinLock(gOvsCtrlLock);
- status = STATUS_INVALID_PARAMETER;
- OvsFreeMemory(vport);
- goto vport_add_done;
- }
- NdisAcquireRWLockRead(gOvsSwitchContext->dispatchLock, &lockState,
- NDIS_RWL_AT_DISPATCH_LEVEL);
- if (!OVS_IS_VPORT_ENTRY_NULL(gOvsSwitchContext, index)) {
- status = STATUS_DEVICE_BUSY;
- NdisReleaseRWLock(gOvsSwitchContext->dispatchLock, &lockState);
- NdisReleaseSpinLock(gOvsCtrlLock);
- OvsFreeMemory(vport);
- goto vport_add_done;
- }
-
- status = OvsInitTunnelVport(vport, addReq);
- if (status != STATUS_SUCCESS) {
- NdisReleaseRWLock(gOvsSwitchContext->dispatchLock, &lockState);
- NdisReleaseSpinLock(gOvsCtrlLock);
- OvsFreeMemory(vport);
- goto vport_add_done;
- }
-
- status = OvsInitVportCommon(gOvsSwitchContext, vport);
- ASSERT(status == NDIS_STATUS_SUCCESS);
-
- vport->ovsState = OVS_STATE_CONNECTED;
- vport->nicState = NdisSwitchNicStateConnected;
-
- vportInfo = (POVS_VPORT_INFO)outputBuffer;
-
- RtlZeroMemory(vportInfo, sizeof (POVS_VPORT_INFO));
- vportInfo->dpNo = gOvsSwitchContext->dpNo;
- vportInfo->portNo = vport->portNo;
- vportInfo->type = vport->ovsType;
- RtlCopyMemory(vportInfo->name, vport->ovsName, vport->ovsNameLen + 1);
- portNo = vport->portNo;
-
- NdisReleaseRWLock(gOvsSwitchContext->dispatchLock, &lockState);
- NdisReleaseSpinLock(gOvsCtrlLock);
- OvsPostEvent(portNo, OVS_EVENT_CONNECT | OVS_EVENT_LINK_UP);
- *replyLen = sizeof (OVS_VPORT_INFO);
- status = STATUS_SUCCESS;
-vport_add_done:
- OVS_LOG_TRACE("Exit: byteReturned: %u, status: %x",
- *replyLen, status);
- return status;
-}
-
-NTSTATUS
-OvsDelVportIoctl(PVOID inputBuffer,
- UINT32 inputLength,
- UINT32 *replyLen)
-{
- NTSTATUS status = STATUS_SUCCESS;
- POVS_VPORT_DELETE_REQUEST delReq;
- LOCK_STATE_EX lockState;
- POVS_VPORT_ENTRY vport;
- size_t len;
- UINT32 portNo = 0;
-
- OVS_LOG_TRACE("Enter: inputLength: %u", inputLength);
-
- if (inputLength < sizeof (OVS_VPORT_DELETE_REQUEST)) {
- status = STATUS_INVALID_PARAMETER;
- goto vport_del_done;
- }
- delReq = (POVS_VPORT_DELETE_REQUEST)inputBuffer;
-
- NdisAcquireSpinLock(gOvsCtrlLock);
- if (gOvsSwitchContext == NULL ||
- gOvsSwitchContext->dpNo != delReq->dpNo) {
- NdisReleaseSpinLock(gOvsCtrlLock);
- status = STATUS_INVALID_PARAMETER;
- goto vport_del_done;
- }
- NdisAcquireRWLockRead(gOvsSwitchContext->dispatchLock, &lockState,
- NDIS_RWL_AT_DISPATCH_LEVEL);
- if (delReq->portNo == 0) {
- StringCbLengthA(delReq->name, OVS_MAX_PORT_NAME_LENGTH - 1, &len);
- vport = OvsFindVportByOvsName(gOvsSwitchContext, delReq->name,
- (UINT32)len);
- } else {
- vport = OvsFindVportByPortNo(gOvsSwitchContext, delReq->portNo);
- }
- if (vport) {
- OVS_LOG_INFO("delete vport: %s, portNo: %x", vport->ovsName,
- vport->portNo);
- portNo = vport->portNo;
- OvsRemoveAndDeleteVport(gOvsSwitchContext, vport);
- } else {
- status = STATUS_DEVICE_DOES_NOT_EXIST;
- }
- NdisReleaseRWLock(gOvsSwitchContext->dispatchLock, &lockState);
- NdisReleaseSpinLock(gOvsCtrlLock);
- if (vport) {
- OvsPostEvent(portNo, OVS_EVENT_DISCONNECT | OVS_EVENT_LINK_DOWN);
- }
-vport_del_done:
- OVS_LOG_TRACE("Exit: byteReturned: %u, status: %x",
- *replyLen, status);
- return status;
-}
-