2 * Copyright (c) 2014 VMware, Inc.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at:
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
27 /* Due to an imported header file */
28 #pragma warning( disable:4505 )
33 #define OVS_DBG_MOD OVS_DBG_DISPATCH
36 typedef struct _OVS_OID_CONTEXT {
37 NDIS_EVENT oidComplete;
39 } OVS_OID_CONTEXT, *POVS_OID_CONTEXT;
43 OvsExtOidRequestComplete(NDIS_HANDLE filterModuleContext,
44 PNDIS_OID_REQUEST oidRequest,
47 OvsOidRequestCompleteMethod(POVS_SWITCH_CONTEXT switchObject,
48 PNDIS_OID_REQUEST oidRequest,
49 PNDIS_OID_REQUEST origOidRequest,
52 OvsOidRequestCompleteSetInfo(POVS_SWITCH_CONTEXT switchObject,
53 PNDIS_OID_REQUEST oidRequest,
54 PNDIS_OID_REQUEST origOidRequest,
57 OvsOidRequestCompleteQuery(POVS_SWITCH_CONTEXT switchObject,
58 PNDIS_OID_REQUEST oidRequest,
59 PNDIS_OID_REQUEST origOidRequest,
63 OvsProcessSetOidPortProp(POVS_SWITCH_CONTEXT switchObject,
64 PNDIS_OID_REQUEST oidRequest);
66 OvsProcessSetOidPort(POVS_SWITCH_CONTEXT switchObject,
67 PNDIS_OID_REQUEST oidRequest);
69 OvsProcessSetOidNic(POVS_SWITCH_CONTEXT switchObject,
70 PNDIS_OID_REQUEST oidRequest);
73 OvsCheckOidHeaderFunc(PNDIS_OBJECT_HEADER header,
77 return header->Type != NDIS_OBJECT_TYPE_DEFAULT ||
78 header->Revision < propRev ||
79 header->Size < propSize;
82 #define OvsCheckOidHeader(_hdr, _rev) \
83 OvsCheckOidHeaderFunc(_hdr, _rev, ##NDIS_SIZEOF_##_rev)
86 OvsOidSetOrigRequest(PNDIS_OID_REQUEST clonedRequest,
87 PNDIS_OID_REQUEST origRequest)
89 *(PVOID*)(&clonedRequest->SourceReserved[0]) = origRequest;
92 static __inline PNDIS_OID_REQUEST
93 OvsOidGetOrigRequest(PNDIS_OID_REQUEST clonedRequest)
95 return *((PVOID*)(&clonedRequest->SourceReserved[0]));
99 OvsOidSetContext(PNDIS_OID_REQUEST clonedRequest,
100 POVS_OID_CONTEXT origRequest)
102 *(PVOID*)(&clonedRequest->SourceReserved[8]) = origRequest;
105 static __inline POVS_OID_CONTEXT
106 OvsOidGetContext(PNDIS_OID_REQUEST clonedRequest)
108 return *((PVOID*)(&clonedRequest->SourceReserved[8]));
112 OvsProcessSetOidPortProp(POVS_SWITCH_CONTEXT switchObject,
113 PNDIS_OID_REQUEST oidRequest)
115 NDIS_STATUS status = NDIS_STATUS_SUCCESS;
116 struct _SET *setInfo = &(oidRequest->DATA.SET_INFORMATION);
117 PNDIS_SWITCH_PORT_PROPERTY_PARAMETERS portPropParam =
118 setInfo->InformationBuffer;
119 BOOLEAN checkFailed = TRUE;
121 UNREFERENCED_PARAMETER(switchObject);
123 if (setInfo->Oid == OID_SWITCH_PORT_PROPERTY_DELETE) {
124 checkFailed = OvsCheckOidHeader(
125 (PNDIS_OBJECT_HEADER)portPropParam,
126 NDIS_SWITCH_PORT_PROPERTY_DELETE_PARAMETERS_REVISION_1);
128 /* it must be a add or update request */
129 checkFailed = OvsCheckOidHeader(
130 (PNDIS_OBJECT_HEADER)portPropParam,
131 NDIS_SWITCH_PORT_PROPERTY_PARAMETERS_REVISION_1);
135 status = NDIS_STATUS_INVALID_PARAMETER;
139 if (portPropParam->PropertyType == NdisSwitchPortPropertyTypeVlan) {
140 status = NDIS_STATUS_NOT_SUPPORTED;
149 OvsProcessSetOidPort(POVS_SWITCH_CONTEXT switchObject,
150 PNDIS_OID_REQUEST oidRequest)
152 NDIS_STATUS status = NDIS_STATUS_SUCCESS;
153 struct _SET *setInfo = &(oidRequest->DATA.SET_INFORMATION);
154 PNDIS_SWITCH_PORT_PARAMETERS portParam = setInfo->InformationBuffer;
156 if (OvsCheckOidHeader((PNDIS_OBJECT_HEADER)portParam,
157 NDIS_SWITCH_PORT_PARAMETERS_REVISION_1)) {
158 status = NDIS_STATUS_NOT_SUPPORTED;
162 if (portParam->IsValidationPort) {
163 /* Validation ports are used internally by the Hyper-V switch
164 * to validate and verify settings. We must skip handling them,
165 * and return STATUS_SUCCESS as the OID result
167 return NDIS_STATUS_SUCCESS;
170 switch(setInfo->Oid) {
171 case OID_SWITCH_PORT_CREATE:
172 status = HvCreatePort(switchObject, portParam, 0);
174 case OID_SWITCH_PORT_UPDATED:
175 status = HvUpdatePort(switchObject, portParam);
177 case OID_SWITCH_PORT_TEARDOWN:
178 HvTeardownPort(switchObject, portParam);
180 case OID_SWITCH_PORT_DELETE:
181 HvDeletePort(switchObject, portParam);
192 OvsProcessSetOidNic(POVS_SWITCH_CONTEXT switchObject,
193 PNDIS_OID_REQUEST oidRequest)
195 NDIS_STATUS status = NDIS_STATUS_SUCCESS;
196 struct _SET *setInfo = &(oidRequest->DATA.SET_INFORMATION);
197 PNDIS_SWITCH_NIC_PARAMETERS nicParam = setInfo->InformationBuffer;
199 if (OvsCheckOidHeader((PNDIS_OBJECT_HEADER)nicParam,
200 NDIS_SWITCH_NIC_PARAMETERS_REVISION_1)) {
201 status = NDIS_STATUS_NOT_SUPPORTED;
205 switch(setInfo->Oid) {
206 case OID_SWITCH_NIC_CREATE:
207 status = HvCreateNic(switchObject, nicParam);
209 case OID_SWITCH_NIC_CONNECT:
210 HvConnectNic(switchObject, nicParam);
212 case OID_SWITCH_NIC_UPDATED:
213 HvUpdateNic(switchObject, nicParam);
215 case OID_SWITCH_NIC_DISCONNECT:
216 HvDisconnectNic(switchObject, nicParam);
218 case OID_SWITCH_NIC_DELETE:
219 HvDeleteNic(switchObject, nicParam);
231 OvsProcessSetOid(POVS_SWITCH_CONTEXT switchObject,
232 PNDIS_OID_REQUEST oidRequest,
235 NDIS_STATUS status = NDIS_STATUS_SUCCESS;
236 struct _SET *setInfo = &(oidRequest->DATA.SET_INFORMATION);
240 OVS_LOG_TRACE("Enter: oidRequest %p, Oid: %lu",
241 oidRequest, setInfo->Oid);
243 /* Verify the basic Oid paramters first */
244 if (setInfo->InformationBufferLength &&
245 (setInfo->InformationBufferLength < sizeof(NDIS_OBJECT_HEADER))) {
246 status = NDIS_STATUS_INVALID_OID;
247 OVS_LOG_INFO("Invalid input %d", setInfo->InformationBufferLength);
251 /* Documentation does not specify what should be done
252 * if informationBuffer is not present. Although it mentions the
253 * structure type informationBUffer points to for each oid request,
254 * but it does not explicitly mention that it is a MUST.
255 * hence we are following this scenario same way as what sample code
257 if (!(setInfo->InformationBufferLength)) {
258 /* We cannot do anything about this oid request,
259 * lets just pass it down. */
260 OVS_LOG_INFO("Buffer Length Zero");
264 switch(setInfo->Oid) {
265 case OID_SWITCH_PORT_PROPERTY_ADD:
266 case OID_SWITCH_PORT_PROPERTY_UPDATE:
267 case OID_SWITCH_PORT_PROPERTY_DELETE:
268 status = OvsProcessSetOidPortProp(switchObject, oidRequest);
271 case OID_SWITCH_PORT_CREATE:
272 case OID_SWITCH_PORT_UPDATED:
273 case OID_SWITCH_PORT_TEARDOWN:
274 case OID_SWITCH_PORT_DELETE:
275 status = OvsProcessSetOidPort(switchObject, oidRequest);
278 case OID_SWITCH_NIC_CREATE:
279 case OID_SWITCH_NIC_CONNECT:
280 case OID_SWITCH_NIC_UPDATED:
281 case OID_SWITCH_NIC_DISCONNECT:
282 case OID_SWITCH_NIC_DELETE:
283 status = OvsProcessSetOidNic(switchObject, oidRequest);
287 /* Non handled OID request */
291 if (status != NDIS_STATUS_SUCCESS) {
300 OVS_LOG_TRACE("Exit: status %8x.", status);
305 OvsProcessMethodOid(POVS_SWITCH_CONTEXT switchObject,
306 PNDIS_OID_REQUEST oidRequest,
308 PULONG bytesNeededParam)
310 NDIS_STATUS status = NDIS_STATUS_SUCCESS;
311 struct _METHOD *methodInfo = &(oidRequest->DATA.METHOD_INFORMATION);
312 struct _SET *nicReqSetInfo = NULL;
313 PNDIS_OBJECT_HEADER header = NULL;
314 PNDIS_OID_REQUEST nicOidRequest = NULL;
316 UNREFERENCED_PARAMETER(switchObject);
318 OVS_LOG_TRACE("Enter: oidRequest %p, Oid: %lu",
319 oidRequest, methodInfo->Oid);
322 *bytesNeededParam = 0;
323 header = methodInfo->InformationBuffer;
325 switch(methodInfo->Oid) {
326 /* We deal with only OID_SWITCH_NIC_REQUEST as of now */
327 case OID_SWITCH_NIC_REQUEST:
328 if (OvsCheckOidHeader(header,
329 NDIS_SWITCH_NIC_OID_REQUEST_REVISION_1)) {
330 OVS_LOG_INFO("Check Header failed");
331 status = NDIS_STATUS_NOT_SUPPORTED;
336 nicOidRequest = (((PNDIS_SWITCH_NIC_OID_REQUEST)header)->OidRequest);
337 nicReqSetInfo = &(nicOidRequest->DATA.SET_INFORMATION);
339 /* Fail the SR-IOV VF case */
340 if ((nicOidRequest->RequestType == NdisRequestSetInformation) &&
341 (nicReqSetInfo->Oid == OID_NIC_SWITCH_ALLOCATE_VF)) {
342 OVS_LOG_INFO("We do not support Oid: "
343 "OID_NIC_SWITCH_ALLOCATE_VF");
344 status = NDIS_STATUS_FAILURE;
354 OVS_LOG_TRACE("Exit: status %8x.", status);
359 * --------------------------------------------------------------------------
360 * Implements filter driver's FilterOidRequest function.
361 * --------------------------------------------------------------------------
365 OvsExtOidRequest(NDIS_HANDLE filterModuleContext,
366 PNDIS_OID_REQUEST oidRequest)
368 POVS_SWITCH_CONTEXT switchObject = (POVS_SWITCH_CONTEXT)filterModuleContext;
369 NDIS_STATUS status = NDIS_STATUS_SUCCESS;
370 PNDIS_OID_REQUEST clonedOidRequest = NULL;
371 struct _METHOD *methodInfo = &(oidRequest->DATA.METHOD_INFORMATION);
372 BOOLEAN completeOid = FALSE;
373 ULONG bytesNeeded = 0;
375 OVS_LOG_TRACE("Enter: oidRequest %p, reqType: %d",
376 oidRequest, oidRequest->RequestType);
377 status = NdisAllocateCloneOidRequest(switchObject->NdisFilterHandle,
378 oidRequest, OVS_MEMORY_TAG,
380 if (status != NDIS_STATUS_SUCCESS) {
384 NdisInterlockedIncrement(&(switchObject->pendingOidCount));
386 /* set the original oid request in cloned one. */
387 OvsOidSetOrigRequest(clonedOidRequest, oidRequest);
388 OvsOidSetContext(clonedOidRequest, NULL);
390 switch(clonedOidRequest->RequestType) {
391 case NdisRequestSetInformation:
392 status = OvsProcessSetOid(switchObject, clonedOidRequest,
395 case NdisRequestMethod:
396 status = OvsProcessMethodOid(switchObject, clonedOidRequest,
397 &completeOid, &bytesNeeded);
400 /* We do not handle other request types as of now.
401 * We are just a passthrough for those. */
405 if (completeOid == TRUE) {
406 /* dont leave any reference back to original request,
407 * even if we are freeing it up. */
408 OVS_LOG_INFO("Complete True oidRequest %p.", oidRequest);
409 OvsOidSetOrigRequest(clonedOidRequest, NULL);
410 NdisFreeCloneOidRequest(switchObject->NdisFilterHandle,
412 methodInfo->BytesNeeded = bytesNeeded;
413 NdisInterlockedDecrement(&switchObject->pendingOidCount);
417 /* pass the request down */
418 status = NdisFOidRequest(switchObject->NdisFilterHandle, clonedOidRequest);
419 if (status != NDIS_STATUS_PENDING) {
420 OvsExtOidRequestComplete(switchObject, clonedOidRequest, status);
421 /* sample code says so */
422 status = NDIS_STATUS_PENDING;
426 OVS_LOG_TRACE("Exit: status %8x.", status);
431 * --------------------------------------------------------------------------
432 * Implements filter driver's FilterOidRequestComplete function.
433 * --------------------------------------------------------------------------
436 OvsExtOidRequestComplete(NDIS_HANDLE filterModuleContext,
437 PNDIS_OID_REQUEST oidRequest,
440 POVS_SWITCH_CONTEXT switchObject = (POVS_SWITCH_CONTEXT)filterModuleContext;
441 PNDIS_OID_REQUEST origReq = OvsOidGetOrigRequest(oidRequest);
442 POVS_OID_CONTEXT oidContext = OvsOidGetContext(oidRequest);
444 /* Only one of the two should be set */
445 ASSERT(origReq != NULL || oidContext != NULL);
446 ASSERT(oidContext != NULL || origReq != NULL);
448 OVS_LOG_TRACE("Enter: oidRequest %p, reqType: %d",
449 oidRequest, oidRequest->RequestType);
451 if (origReq == NULL) {
452 NdisInterlockedDecrement(&(switchObject->pendingOidCount));
453 oidContext->status = status;
454 NdisSetEvent(&oidContext->oidComplete);
455 OVS_LOG_INFO("Internally generated request");
459 switch(oidRequest->RequestType) {
460 case NdisRequestMethod:
461 OvsOidRequestCompleteMethod(switchObject, oidRequest,
465 case NdisRequestSetInformation:
466 OvsOidRequestCompleteSetInfo(switchObject, oidRequest,
470 case NdisRequestQueryInformation:
471 case NdisRequestQueryStatistics:
473 OvsOidRequestCompleteQuery(switchObject, oidRequest,
478 OvsOidSetOrigRequest(oidRequest, NULL);
480 NdisFreeCloneOidRequest(switchObject->NdisFilterHandle, oidRequest);
481 NdisFOidRequestComplete(switchObject->NdisFilterHandle, origReq, status);
482 NdisInterlockedDecrement(&(switchObject->pendingOidCount));
485 OVS_LOG_TRACE("Exit");
489 OvsOidRequestCompleteMethod(POVS_SWITCH_CONTEXT switchObject,
490 PNDIS_OID_REQUEST oidRequest,
491 PNDIS_OID_REQUEST origOidRequest,
494 UNREFERENCED_PARAMETER(status);
495 UNREFERENCED_PARAMETER(switchObject);
497 struct _METHOD *methodInfo = &(oidRequest->DATA.METHOD_INFORMATION);
498 struct _METHOD *origMethodInfo = &(origOidRequest->DATA.
501 OVS_LOG_TRACE("Enter: oidRequest %p, Oid: %lu",
502 oidRequest, methodInfo->Oid);
504 origMethodInfo->OutputBufferLength = methodInfo->OutputBufferLength;
505 origMethodInfo->BytesRead = methodInfo->BytesRead;
506 origMethodInfo->BytesNeeded = methodInfo->BytesNeeded;
507 origMethodInfo->BytesWritten = methodInfo->BytesWritten;
509 OVS_LOG_TRACE("Exit");
513 OvsOidRequestCompleteSetInfo(POVS_SWITCH_CONTEXT switchObject,
514 PNDIS_OID_REQUEST oidRequest,
515 PNDIS_OID_REQUEST origOidRequest,
518 struct _SET *setInfo = &(oidRequest->DATA.SET_INFORMATION);
519 struct _SET *origSetInfo = &(origOidRequest->DATA.SET_INFORMATION);
520 PNDIS_OBJECT_HEADER origHeader = origSetInfo->InformationBuffer;
522 OVS_LOG_TRACE("Enter: oidRequest %p, Oid: %lu",
523 oidRequest, setInfo->Oid);
525 origSetInfo->BytesRead = setInfo->BytesRead;
526 origSetInfo->BytesNeeded = setInfo->BytesNeeded;
528 if (status != NDIS_STATUS_SUCCESS) {
530 switch(setInfo->Oid) {
531 case OID_SWITCH_PORT_CREATE:
532 HvDeletePort(switchObject,
533 (PNDIS_SWITCH_PORT_PARAMETERS)origHeader);
536 case OID_SWITCH_NIC_CREATE:
537 HvDeleteNic(switchObject,
538 (PNDIS_SWITCH_NIC_PARAMETERS)origHeader);
546 OVS_LOG_TRACE("Exit");
550 OvsOidRequestCompleteQuery(POVS_SWITCH_CONTEXT switchObject,
551 PNDIS_OID_REQUEST oidRequest,
552 PNDIS_OID_REQUEST origOidRequest,
555 UNREFERENCED_PARAMETER(switchObject);
556 UNREFERENCED_PARAMETER(status);
558 struct _QUERY *queryInfo = &((oidRequest->DATA).QUERY_INFORMATION);
559 struct _QUERY *origQueryInfo = &((origOidRequest->DATA).QUERY_INFORMATION);
561 OVS_LOG_TRACE("Enter: oidRequest %p, Oid: %lu",
562 oidRequest, queryInfo->Oid);
564 origQueryInfo->BytesWritten = queryInfo->BytesWritten;
565 origQueryInfo->BytesNeeded = queryInfo->BytesNeeded;
567 OVS_LOG_TRACE("Exit");
571 * --------------------------------------------------------------------------
572 * Implements filter driver's FilterCancelOidRequest function.
573 * --------------------------------------------------------------------------
576 OvsExtCancelOidRequest(NDIS_HANDLE filterModuleContext,
579 OVS_LOG_TRACE("Enter: requestId: %p", requestId);
581 UNREFERENCED_PARAMETER(filterModuleContext);
582 UNREFERENCED_PARAMETER(requestId);
587 * --------------------------------------------------------------------------
588 * Utility function to issue the specified OID to the NDIS stack. The OID is
589 * directed towards the miniport edge of the extensible switch.
590 * An OID that gets issued may not complete immediately, and in such cases, the
591 * function waits for the OID to complete. Thus, this function must not be
592 * called at the PASSIVE_LEVEL.
593 * --------------------------------------------------------------------------
596 OvsIssueOidRequest(POVS_SWITCH_CONTEXT switchContext,
597 NDIS_REQUEST_TYPE oidType,
598 UINT32 oidRequestEnum,
599 PVOID oidInputBuffer,
601 PVOID oidOutputBuffer,
603 UINT32 *outputSizeNeeded)
606 PNDIS_OID_REQUEST oidRequest;
607 POVS_OID_CONTEXT oidContext;
608 ULONG OvsExtOidRequestId = 'ISVO';
610 DBG_UNREFERENCED_PARAMETER(inputSize);
611 DBG_UNREFERENCED_PARAMETER(oidInputBuffer);
613 OVS_LOG_TRACE("Enter: switchContext: %p, oidType: %d",
614 switchContext, oidType);
616 ASSERT(oidInputBuffer == NULL || inputSize != 0);
617 ASSERT(oidOutputBuffer == NULL || outputSize != 0);
618 ASSERT(KeGetCurrentIrql() == PASSIVE_LEVEL);
620 oidRequest = OvsAllocateMemoryWithTag(sizeof *oidRequest,
623 status = NDIS_STATUS_RESOURCES;
627 oidContext = OvsAllocateMemoryWithTag(sizeof *oidContext,
630 OvsFreeMemoryWithTag(oidRequest, OVS_OID_POOL_TAG);
631 status = NDIS_STATUS_RESOURCES;
635 RtlZeroMemory(oidRequest, sizeof *oidRequest);
636 RtlZeroMemory(oidContext, sizeof *oidContext);
638 oidRequest->Header.Type = NDIS_OBJECT_TYPE_OID_REQUEST;
639 oidRequest->Header.Revision = NDIS_OID_REQUEST_REVISION_1;
640 oidRequest->Header.Size = NDIS_SIZEOF_OID_REQUEST_REVISION_1;
642 oidRequest->RequestType = oidType;
643 oidRequest->PortNumber = 0;
644 oidRequest->Timeout = 0;
645 oidRequest->RequestId = (PVOID)OvsExtOidRequestId;
648 case NdisRequestQueryInformation:
649 oidRequest->DATA.QUERY_INFORMATION.Oid = oidRequestEnum;
650 oidRequest->DATA.QUERY_INFORMATION.InformationBuffer = oidOutputBuffer;
651 oidRequest->DATA.QUERY_INFORMATION.InformationBufferLength = outputSize;
655 status = NDIS_STATUS_INVALID_PARAMETER;
660 * We make use of the SourceReserved field in the OID request to store
661 * pointers to the original OID (if any), and also context for completion
664 oidContext->status = NDIS_STATUS_SUCCESS;
665 NdisInitializeEvent(&oidContext->oidComplete);
667 OvsOidSetOrigRequest(oidRequest, NULL);
668 OvsOidSetContext(oidRequest, oidContext);
670 NdisInterlockedIncrement(&(switchContext->pendingOidCount));
671 status = NdisFOidRequest(switchContext->NdisFilterHandle, oidRequest);
672 if (status == NDIS_STATUS_PENDING) {
673 NdisWaitEvent(&oidContext->oidComplete, 0);
675 NdisInterlockedDecrement(&(switchContext->pendingOidCount));
678 if (status == NDIS_STATUS_INVALID_LENGTH ||
679 oidContext->status == NDIS_STATUS_INVALID_LENGTH) {
681 case NdisRequestQueryInformation:
682 *outputSizeNeeded = oidRequest->DATA.QUERY_INFORMATION.BytesNeeded;
686 status = oidContext->status;
687 ASSERT(status != NDIS_STATUS_PENDING);
689 OvsFreeMemoryWithTag(oidRequest, OVS_OID_POOL_TAG);
690 OvsFreeMemoryWithTag(oidContext, OVS_OID_POOL_TAG);
693 OVS_LOG_TRACE("Exit: status %8x.", status);
699 * --------------------------------------------------------------------------
700 * Utility function to query if the extensible switch has completed activation
702 * --------------------------------------------------------------------------
705 OvsQuerySwitchActivationComplete(POVS_SWITCH_CONTEXT switchContext,
706 BOOLEAN *switchActive)
709 PNDIS_SWITCH_PARAMETERS switchParams;
710 UINT32 outputSizeNeeded;
712 OVS_LOG_TRACE("Enter: switchContext: %p, switchActive: %p",
713 switchContext, switchActive);
715 switchParams = OvsAllocateMemoryWithTag(sizeof *switchParams,
718 status = NDIS_STATUS_RESOURCES;
723 * Even though 'switchParms' is supposed to be populated by the OID, it
724 * needs to be initialized nevertheless. Otherwise, OID returns
725 * NDIS_STATUS_INVALID_PARAMETER. This is not clear in the documentation.
727 RtlZeroMemory(switchParams, sizeof *switchParams);
728 switchParams->Header.Revision = NDIS_SWITCH_PARAMETERS_REVISION_1;
729 switchParams->Header.Type = NDIS_OBJECT_TYPE_DEFAULT;
730 switchParams->Header.Size = NDIS_SIZEOF_NDIS_SWITCH_PARAMETERS_REVISION_1;
732 status = OvsIssueOidRequest(switchContext, NdisRequestQueryInformation,
733 OID_SWITCH_PARAMETERS, NULL, 0,
734 (PVOID)switchParams, sizeof *switchParams,
737 ASSERT(status != NDIS_STATUS_INVALID_LENGTH);
738 ASSERT(status != NDIS_STATUS_PENDING);
739 if (status == NDIS_STATUS_SUCCESS) {
740 ASSERT(switchParams->Header.Type == NDIS_OBJECT_TYPE_DEFAULT);
741 ASSERT(switchParams->Header.Revision == NDIS_SWITCH_PARAMETERS_REVISION_1);
742 ASSERT(switchParams->Header.Size ==
743 NDIS_SIZEOF_NDIS_SWITCH_PARAMETERS_REVISION_1);
744 *switchActive = switchParams->IsActive;
747 OvsFreeMemoryWithTag(switchParams, OVS_OID_POOL_TAG);
750 OVS_LOG_TRACE("Exit: status %8x, switchActive: %d.",
751 status, *switchActive);
757 * --------------------------------------------------------------------------
758 * Utility function to get the array of ports on the extensible switch. Upon
759 * success, the caller needs to free the returned array.
760 * --------------------------------------------------------------------------
763 OvsGetPortsOnSwitch(POVS_SWITCH_CONTEXT switchContext,
764 PNDIS_SWITCH_PORT_ARRAY *portArrayOut)
766 PNDIS_SWITCH_PORT_ARRAY portArray;
767 UINT32 arraySize = sizeof *portArray;
768 NDIS_STATUS status = NDIS_STATUS_FAILURE;
770 OVS_LOG_TRACE("Enter: switchContext: %p, portArray: %p",
771 switchContext, portArrayOut);
773 UINT32 reqdArraySize;
775 portArray = OvsAllocateMemoryWithTag(arraySize, OVS_OID_POOL_TAG);
777 status = NDIS_STATUS_RESOURCES;
782 * Even though 'portArray' is supposed to be populated by the OID, it
783 * needs to be initialized nevertheless. Otherwise, OID returns
784 * NDIS_STATUS_INVALID_PARAMETER. This is not clear in the documentation.
786 RtlZeroMemory(portArray, sizeof *portArray);
787 portArray->Header.Revision = NDIS_SWITCH_PORT_ARRAY_REVISION_1;
788 portArray->Header.Type = NDIS_OBJECT_TYPE_DEFAULT;
789 portArray->Header.Size = NDIS_SIZEOF_NDIS_SWITCH_PORT_ARRAY_REVISION_1;
791 status = OvsIssueOidRequest(switchContext, NdisRequestQueryInformation,
792 OID_SWITCH_PORT_ARRAY, NULL, 0,
793 (PVOID)portArray, arraySize,
795 if (status == NDIS_STATUS_SUCCESS) {
796 *portArrayOut = portArray;
800 OvsFreeMemoryWithTag(portArray, OVS_OID_POOL_TAG);
801 arraySize = reqdArraySize;
802 if (status != NDIS_STATUS_INVALID_LENGTH) {
805 } while(status == NDIS_STATUS_INVALID_LENGTH);
808 OVS_LOG_TRACE("Exit: status %8x.", status);
814 * --------------------------------------------------------------------------
815 * Utility function to get the array of nics on the extensible switch. Upon
816 * success, the caller needs to free the returned array.
817 * --------------------------------------------------------------------------
820 OvsGetNicsOnSwitch(POVS_SWITCH_CONTEXT switchContext,
821 PNDIS_SWITCH_NIC_ARRAY *nicArrayOut)
823 PNDIS_SWITCH_NIC_ARRAY nicArray;
824 UINT32 arraySize = sizeof *nicArray;
825 NDIS_STATUS status = NDIS_STATUS_FAILURE;
827 OVS_LOG_TRACE("Enter: switchContext: %p, nicArray: %p",
828 switchContext, nicArrayOut);
831 UINT32 reqdArraySize;
833 nicArray = OvsAllocateMemoryWithTag(arraySize, OVS_OID_POOL_TAG);
835 status = NDIS_STATUS_RESOURCES;
840 * Even though 'nicArray' is supposed to be populated by the OID, it
841 * needs to be initialized nevertheless. Otherwise, OID returns
842 * NDIS_STATUS_INVALID_PARAMETER. This is not clear in the documentation.
844 RtlZeroMemory(nicArray, sizeof *nicArray);
845 nicArray->Header.Revision = NDIS_SWITCH_NIC_ARRAY_REVISION_1;
846 nicArray->Header.Type = NDIS_OBJECT_TYPE_DEFAULT;
847 nicArray->Header.Size = NDIS_SIZEOF_NDIS_SWITCH_NIC_ARRAY_REVISION_1;
849 status = OvsIssueOidRequest(switchContext, NdisRequestQueryInformation,
850 OID_SWITCH_NIC_ARRAY, NULL, 0,
851 (PVOID)nicArray, arraySize,
853 if (status == NDIS_STATUS_SUCCESS) {
854 *nicArrayOut = nicArray;
858 OvsFreeMemoryWithTag(nicArray, OVS_OID_POOL_TAG);
859 arraySize = reqdArraySize;
860 if (status != NDIS_STATUS_INVALID_LENGTH) {
863 } while(status == NDIS_STATUS_INVALID_LENGTH);
866 OVS_LOG_TRACE("Exit: status %8x.", status);
870 VOID OvsFreeSwitchPortsArray(PNDIS_SWITCH_PORT_ARRAY portsArray)
873 OvsFreeMemoryWithTag(portsArray, OVS_OID_POOL_TAG);
877 VOID OvsFreeSwitchNicsArray(PNDIS_SWITCH_NIC_ARRAY nicsArray)
880 OvsFreeMemoryWithTag(nicsArray, OVS_OID_POOL_TAG);