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);
174 case OID_SWITCH_PORT_TEARDOWN:
175 HvTeardownPort(switchObject, portParam);
177 case OID_SWITCH_PORT_DELETE:
178 HvDeletePort(switchObject, portParam);
189 OvsProcessSetOidNic(POVS_SWITCH_CONTEXT switchObject,
190 PNDIS_OID_REQUEST oidRequest)
192 NDIS_STATUS status = NDIS_STATUS_SUCCESS;
193 struct _SET *setInfo = &(oidRequest->DATA.SET_INFORMATION);
194 PNDIS_SWITCH_NIC_PARAMETERS nicParam = setInfo->InformationBuffer;
196 if (OvsCheckOidHeader((PNDIS_OBJECT_HEADER)nicParam,
197 NDIS_SWITCH_NIC_PARAMETERS_REVISION_1)) {
198 status = NDIS_STATUS_NOT_SUPPORTED;
202 switch(setInfo->Oid) {
203 case OID_SWITCH_NIC_CREATE:
204 status = HvCreateNic(switchObject, nicParam);
206 case OID_SWITCH_NIC_CONNECT:
207 HvConnectNic(switchObject, nicParam);
209 case OID_SWITCH_NIC_UPDATED:
210 HvUpdateNic(switchObject, nicParam);
212 case OID_SWITCH_NIC_DISCONNECT:
213 HvDisconnectNic(switchObject, nicParam);
215 case OID_SWITCH_NIC_DELETE:
216 HvDeleteNic(switchObject, nicParam);
228 OvsProcessSetOid(POVS_SWITCH_CONTEXT switchObject,
229 PNDIS_OID_REQUEST oidRequest,
232 NDIS_STATUS status = NDIS_STATUS_SUCCESS;
233 struct _SET *setInfo = &(oidRequest->DATA.SET_INFORMATION);
237 OVS_LOG_TRACE("Enter: oidRequest %p, Oid: %lu",
238 oidRequest, setInfo->Oid);
240 /* Verify the basic Oid paramters first */
241 if (setInfo->InformationBufferLength &&
242 (setInfo->InformationBufferLength < sizeof(NDIS_OBJECT_HEADER))) {
243 status = NDIS_STATUS_INVALID_OID;
244 OVS_LOG_INFO("Invalid input %d", setInfo->InformationBufferLength);
248 /* Documentation does not specify what should be done
249 * if informationBuffer is not present. Although it mentions the
250 * structure type informationBUffer points to for each oid request,
251 * but it does not explicitly mention that it is a MUST.
252 * hence we are following this scenario same way as what sample code
254 if (!(setInfo->InformationBufferLength)) {
255 /* We cannot do anything about this oid request,
256 * lets just pass it down. */
257 OVS_LOG_INFO("Buffer Length Zero");
261 switch(setInfo->Oid) {
262 case OID_SWITCH_PORT_PROPERTY_ADD:
263 case OID_SWITCH_PORT_PROPERTY_UPDATE:
264 case OID_SWITCH_PORT_PROPERTY_DELETE:
265 status = OvsProcessSetOidPortProp(switchObject, oidRequest);
268 case OID_SWITCH_PORT_CREATE:
269 case OID_SWITCH_PORT_UPDATED:
270 case OID_SWITCH_PORT_TEARDOWN:
271 case OID_SWITCH_PORT_DELETE:
272 status = OvsProcessSetOidPort(switchObject, oidRequest);
275 case OID_SWITCH_NIC_CREATE:
276 case OID_SWITCH_NIC_CONNECT:
277 case OID_SWITCH_NIC_UPDATED:
278 case OID_SWITCH_NIC_DISCONNECT:
279 case OID_SWITCH_NIC_DELETE:
280 status = OvsProcessSetOidNic(switchObject, oidRequest);
284 /* Non handled OID request */
288 if (status != NDIS_STATUS_SUCCESS) {
297 OVS_LOG_TRACE("Exit: status %8x.", status);
302 OvsProcessMethodOid(POVS_SWITCH_CONTEXT switchObject,
303 PNDIS_OID_REQUEST oidRequest,
305 PULONG bytesNeededParam)
307 NDIS_STATUS status = NDIS_STATUS_SUCCESS;
308 struct _METHOD *methodInfo = &(oidRequest->DATA.METHOD_INFORMATION);
309 struct _SET *nicReqSetInfo = NULL;
310 PNDIS_OBJECT_HEADER header = NULL;
311 PNDIS_OID_REQUEST nicOidRequest = NULL;
313 UNREFERENCED_PARAMETER(switchObject);
315 OVS_LOG_TRACE("Enter: oidRequest %p, Oid: %lu",
316 oidRequest, methodInfo->Oid);
319 *bytesNeededParam = 0;
320 header = methodInfo->InformationBuffer;
322 switch(methodInfo->Oid) {
323 /* We deal with only OID_SWITCH_NIC_REQUEST as of now */
324 case OID_SWITCH_NIC_REQUEST:
325 if (OvsCheckOidHeader(header,
326 NDIS_SWITCH_NIC_OID_REQUEST_REVISION_1)) {
327 OVS_LOG_INFO("Check Header failed");
328 status = NDIS_STATUS_NOT_SUPPORTED;
333 nicOidRequest = (((PNDIS_SWITCH_NIC_OID_REQUEST)header)->OidRequest);
334 nicReqSetInfo = &(nicOidRequest->DATA.SET_INFORMATION);
336 /* Fail the SR-IOV VF case */
337 if ((nicOidRequest->RequestType == NdisRequestSetInformation) &&
338 (nicReqSetInfo->Oid == OID_NIC_SWITCH_ALLOCATE_VF)) {
339 OVS_LOG_INFO("We do not support Oid: "
340 "OID_NIC_SWITCH_ALLOCATE_VF");
341 status = NDIS_STATUS_FAILURE;
351 OVS_LOG_TRACE("Exit: status %8x.", status);
356 * --------------------------------------------------------------------------
357 * Implements filter driver's FilterOidRequest function.
358 * --------------------------------------------------------------------------
362 OvsExtOidRequest(NDIS_HANDLE filterModuleContext,
363 PNDIS_OID_REQUEST oidRequest)
365 POVS_SWITCH_CONTEXT switchObject = (POVS_SWITCH_CONTEXT)filterModuleContext;
366 NDIS_STATUS status = NDIS_STATUS_SUCCESS;
367 PNDIS_OID_REQUEST clonedOidRequest = NULL;
368 struct _METHOD *methodInfo = &(oidRequest->DATA.METHOD_INFORMATION);
369 BOOLEAN completeOid = FALSE;
370 ULONG bytesNeeded = 0;
372 OVS_LOG_TRACE("Enter: oidRequest %p, reqType: %d",
373 oidRequest, oidRequest->RequestType);
374 status = NdisAllocateCloneOidRequest(switchObject->NdisFilterHandle,
375 oidRequest, OVS_MEMORY_TAG,
377 if (status != NDIS_STATUS_SUCCESS) {
381 NdisInterlockedIncrement(&(switchObject->pendingOidCount));
383 /* set the original oid request in cloned one. */
384 OvsOidSetOrigRequest(clonedOidRequest, oidRequest);
385 OvsOidSetContext(clonedOidRequest, NULL);
387 switch(clonedOidRequest->RequestType) {
388 case NdisRequestSetInformation:
389 status = OvsProcessSetOid(switchObject, clonedOidRequest,
392 case NdisRequestMethod:
393 status = OvsProcessMethodOid(switchObject, clonedOidRequest,
394 &completeOid, &bytesNeeded);
397 /* We do not handle other request types as of now.
398 * We are just a passthrough for those. */
402 if (completeOid == TRUE) {
403 /* dont leave any reference back to original request,
404 * even if we are freeing it up. */
405 OVS_LOG_INFO("Complete True oidRequest %p.", oidRequest);
406 OvsOidSetOrigRequest(clonedOidRequest, NULL);
407 NdisFreeCloneOidRequest(switchObject->NdisFilterHandle,
409 methodInfo->BytesNeeded = bytesNeeded;
410 NdisInterlockedDecrement(&switchObject->pendingOidCount);
414 /* pass the request down */
415 status = NdisFOidRequest(switchObject->NdisFilterHandle, clonedOidRequest);
416 if (status != NDIS_STATUS_PENDING) {
417 OvsExtOidRequestComplete(switchObject, clonedOidRequest, status);
418 /* sample code says so */
419 status = NDIS_STATUS_PENDING;
423 OVS_LOG_TRACE("Exit: status %8x.", status);
428 * --------------------------------------------------------------------------
429 * Implements filter driver's FilterOidRequestComplete function.
430 * --------------------------------------------------------------------------
433 OvsExtOidRequestComplete(NDIS_HANDLE filterModuleContext,
434 PNDIS_OID_REQUEST oidRequest,
437 POVS_SWITCH_CONTEXT switchObject = (POVS_SWITCH_CONTEXT)filterModuleContext;
438 PNDIS_OID_REQUEST origReq = OvsOidGetOrigRequest(oidRequest);
439 POVS_OID_CONTEXT oidContext = OvsOidGetContext(oidRequest);
441 /* Only one of the two should be set */
442 ASSERT(origReq != NULL || oidContext != NULL);
443 ASSERT(oidContext != NULL || origReq != NULL);
445 OVS_LOG_TRACE("Enter: oidRequest %p, reqType: %d",
446 oidRequest, oidRequest->RequestType);
448 if (origReq == NULL) {
449 NdisInterlockedDecrement(&(switchObject->pendingOidCount));
450 oidContext->status = status;
451 NdisSetEvent(&oidContext->oidComplete);
452 OVS_LOG_INFO("Internally generated request");
456 switch(oidRequest->RequestType) {
457 case NdisRequestMethod:
458 OvsOidRequestCompleteMethod(switchObject, oidRequest,
462 case NdisRequestSetInformation:
463 OvsOidRequestCompleteSetInfo(switchObject, oidRequest,
467 case NdisRequestQueryInformation:
468 case NdisRequestQueryStatistics:
470 OvsOidRequestCompleteQuery(switchObject, oidRequest,
475 OvsOidSetOrigRequest(oidRequest, NULL);
477 NdisFreeCloneOidRequest(switchObject->NdisFilterHandle, oidRequest);
478 NdisFOidRequestComplete(switchObject->NdisFilterHandle, origReq, status);
479 NdisInterlockedDecrement(&(switchObject->pendingOidCount));
482 OVS_LOG_TRACE("Exit");
486 OvsOidRequestCompleteMethod(POVS_SWITCH_CONTEXT switchObject,
487 PNDIS_OID_REQUEST oidRequest,
488 PNDIS_OID_REQUEST origOidRequest,
491 UNREFERENCED_PARAMETER(status);
492 UNREFERENCED_PARAMETER(switchObject);
494 struct _METHOD *methodInfo = &(oidRequest->DATA.METHOD_INFORMATION);
495 struct _METHOD *origMethodInfo = &(origOidRequest->DATA.
498 OVS_LOG_TRACE("Enter: oidRequest %p, Oid: %lu",
499 oidRequest, methodInfo->Oid);
501 origMethodInfo->OutputBufferLength = methodInfo->OutputBufferLength;
502 origMethodInfo->BytesRead = methodInfo->BytesRead;
503 origMethodInfo->BytesNeeded = methodInfo->BytesNeeded;
504 origMethodInfo->BytesWritten = methodInfo->BytesWritten;
506 OVS_LOG_TRACE("Exit");
510 OvsOidRequestCompleteSetInfo(POVS_SWITCH_CONTEXT switchObject,
511 PNDIS_OID_REQUEST oidRequest,
512 PNDIS_OID_REQUEST origOidRequest,
515 struct _SET *setInfo = &(oidRequest->DATA.SET_INFORMATION);
516 struct _SET *origSetInfo = &(origOidRequest->DATA.SET_INFORMATION);
517 PNDIS_OBJECT_HEADER origHeader = origSetInfo->InformationBuffer;
519 OVS_LOG_TRACE("Enter: oidRequest %p, Oid: %lu",
520 oidRequest, setInfo->Oid);
522 origSetInfo->BytesRead = setInfo->BytesRead;
523 origSetInfo->BytesNeeded = setInfo->BytesNeeded;
525 if (status != NDIS_STATUS_SUCCESS) {
527 switch(setInfo->Oid) {
528 case OID_SWITCH_PORT_CREATE:
529 HvDeletePort(switchObject,
530 (PNDIS_SWITCH_PORT_PARAMETERS)origHeader);
533 case OID_SWITCH_NIC_CREATE:
534 HvDeleteNic(switchObject,
535 (PNDIS_SWITCH_NIC_PARAMETERS)origHeader);
543 OVS_LOG_TRACE("Exit");
547 OvsOidRequestCompleteQuery(POVS_SWITCH_CONTEXT switchObject,
548 PNDIS_OID_REQUEST oidRequest,
549 PNDIS_OID_REQUEST origOidRequest,
552 UNREFERENCED_PARAMETER(switchObject);
553 UNREFERENCED_PARAMETER(status);
555 struct _QUERY *queryInfo = &((oidRequest->DATA).QUERY_INFORMATION);
556 struct _QUERY *origQueryInfo = &((origOidRequest->DATA).QUERY_INFORMATION);
558 OVS_LOG_TRACE("Enter: oidRequest %p, Oid: %lu",
559 oidRequest, queryInfo->Oid);
561 origQueryInfo->BytesWritten = queryInfo->BytesWritten;
562 origQueryInfo->BytesNeeded = queryInfo->BytesNeeded;
564 OVS_LOG_TRACE("Exit");
568 * --------------------------------------------------------------------------
569 * Implements filter driver's FilterCancelOidRequest function.
570 * --------------------------------------------------------------------------
573 OvsExtCancelOidRequest(NDIS_HANDLE filterModuleContext,
576 OVS_LOG_TRACE("Enter: requestId: %p", requestId);
578 UNREFERENCED_PARAMETER(filterModuleContext);
579 UNREFERENCED_PARAMETER(requestId);
584 * --------------------------------------------------------------------------
585 * Utility function to issue the specified OID to the NDIS stack. The OID is
586 * directed towards the miniport edge of the extensible switch.
587 * An OID that gets issued may not complete immediately, and in such cases, the
588 * function waits for the OID to complete. Thus, this function must not be
589 * called at the PASSIVE_LEVEL.
590 * --------------------------------------------------------------------------
593 OvsIssueOidRequest(POVS_SWITCH_CONTEXT switchContext,
594 NDIS_REQUEST_TYPE oidType,
595 UINT32 oidRequestEnum,
596 PVOID oidInputBuffer,
598 PVOID oidOutputBuffer,
600 UINT32 *outputSizeNeeded)
603 PNDIS_OID_REQUEST oidRequest;
604 POVS_OID_CONTEXT oidContext;
605 ULONG OvsExtOidRequestId = 'ISVO';
607 DBG_UNREFERENCED_PARAMETER(inputSize);
608 DBG_UNREFERENCED_PARAMETER(oidInputBuffer);
610 OVS_LOG_TRACE("Enter: switchContext: %p, oidType: %d",
611 switchContext, oidType);
613 ASSERT(oidInputBuffer == NULL || inputSize != 0);
614 ASSERT(oidOutputBuffer == NULL || outputSize != 0);
615 ASSERT(KeGetCurrentIrql() == PASSIVE_LEVEL);
617 oidRequest = OvsAllocateMemory(sizeof *oidRequest);
619 status = NDIS_STATUS_RESOURCES;
623 oidContext = OvsAllocateMemory(sizeof *oidContext);
625 OvsFreeMemory(oidRequest);
626 status = NDIS_STATUS_RESOURCES;
630 RtlZeroMemory(oidRequest, sizeof *oidRequest);
631 RtlZeroMemory(oidContext, sizeof *oidContext);
633 oidRequest->Header.Type = NDIS_OBJECT_TYPE_OID_REQUEST;
634 oidRequest->Header.Revision = NDIS_OID_REQUEST_REVISION_1;
635 oidRequest->Header.Size = NDIS_SIZEOF_OID_REQUEST_REVISION_1;
637 oidRequest->RequestType = oidType;
638 oidRequest->PortNumber = 0;
639 oidRequest->Timeout = 0;
640 oidRequest->RequestId = (PVOID)OvsExtOidRequestId;
643 case NdisRequestQueryInformation:
644 oidRequest->DATA.QUERY_INFORMATION.Oid = oidRequestEnum;
645 oidRequest->DATA.QUERY_INFORMATION.InformationBuffer = oidOutputBuffer;
646 oidRequest->DATA.QUERY_INFORMATION.InformationBufferLength = outputSize;
650 status = NDIS_STATUS_INVALID_PARAMETER;
655 * We make use of the SourceReserved field in the OID request to store
656 * pointers to the original OID (if any), and also context for completion
659 oidContext->status = NDIS_STATUS_SUCCESS;
660 NdisInitializeEvent(&oidContext->oidComplete);
662 OvsOidSetOrigRequest(oidRequest, NULL);
663 OvsOidSetContext(oidRequest, oidContext);
665 NdisInterlockedIncrement(&(switchContext->pendingOidCount));
666 status = NdisFOidRequest(switchContext->NdisFilterHandle, oidRequest);
667 if (status == NDIS_STATUS_PENDING) {
668 NdisWaitEvent(&oidContext->oidComplete, 0);
670 NdisInterlockedDecrement(&(switchContext->pendingOidCount));
673 if (status == NDIS_STATUS_INVALID_LENGTH ||
674 oidContext->status == NDIS_STATUS_INVALID_LENGTH) {
676 case NdisRequestQueryInformation:
677 *outputSizeNeeded = oidRequest->DATA.QUERY_INFORMATION.BytesNeeded;
681 status = oidContext->status;
682 ASSERT(status != NDIS_STATUS_PENDING);
684 OvsFreeMemory(oidRequest);
685 OvsFreeMemory(oidContext);
688 OVS_LOG_TRACE("Exit: status %8x.", status);
694 * --------------------------------------------------------------------------
695 * Utility function to query if the extensible switch has completed activation
697 * --------------------------------------------------------------------------
700 OvsQuerySwitchActivationComplete(POVS_SWITCH_CONTEXT switchContext,
701 BOOLEAN *switchActive)
704 PNDIS_SWITCH_PARAMETERS switchParams;
705 UINT32 outputSizeNeeded;
707 OVS_LOG_TRACE("Enter: switchContext: %p, switchActive: %p",
708 switchContext, switchActive);
710 switchParams = OvsAllocateMemory(sizeof *switchParams);
712 status = NDIS_STATUS_RESOURCES;
717 * Even though 'switchParms' is supposed to be populated by the OID, it
718 * needs to be initialized nevertheless. Otherwise, OID returns
719 * NDIS_STATUS_INVALID_PARAMETER. This is not clear in the documentation.
721 RtlZeroMemory(switchParams, sizeof *switchParams);
722 switchParams->Header.Revision = NDIS_SWITCH_PARAMETERS_REVISION_1;
723 switchParams->Header.Type = NDIS_OBJECT_TYPE_DEFAULT;
724 switchParams->Header.Size = NDIS_SIZEOF_NDIS_SWITCH_PARAMETERS_REVISION_1;
726 status = OvsIssueOidRequest(switchContext, NdisRequestQueryInformation,
727 OID_SWITCH_PARAMETERS, NULL, 0,
728 (PVOID)switchParams, sizeof *switchParams,
731 ASSERT(status != NDIS_STATUS_INVALID_LENGTH);
732 ASSERT(status != NDIS_STATUS_PENDING);
733 if (status == NDIS_STATUS_SUCCESS) {
734 ASSERT(switchParams->Header.Type == NDIS_OBJECT_TYPE_DEFAULT);
735 ASSERT(switchParams->Header.Revision == NDIS_SWITCH_PARAMETERS_REVISION_1);
736 ASSERT(switchParams->Header.Size ==
737 NDIS_SIZEOF_NDIS_SWITCH_PARAMETERS_REVISION_1);
738 *switchActive = switchParams->IsActive;
741 OvsFreeMemory(switchParams);
744 OVS_LOG_TRACE("Exit: status %8x, switchActive: %d.",
745 status, *switchActive);
751 * --------------------------------------------------------------------------
752 * Utility function to get the array of ports on the extensible switch. Upon
753 * success, the caller needs to free the returned array.
754 * --------------------------------------------------------------------------
757 OvsGetPortsOnSwitch(POVS_SWITCH_CONTEXT switchContext,
758 PNDIS_SWITCH_PORT_ARRAY *portArrayOut)
760 PNDIS_SWITCH_PORT_ARRAY portArray;
761 UINT32 arraySize = sizeof *portArray;
762 NDIS_STATUS status = NDIS_STATUS_FAILURE;
764 OVS_LOG_TRACE("Enter: switchContext: %p, portArray: %p",
765 switchContext, portArrayOut);
767 UINT32 reqdArraySize;
769 portArray = OvsAllocateMemory(arraySize);
771 status = NDIS_STATUS_RESOURCES;
776 * Even though 'portArray' is supposed to be populated by the OID, it
777 * needs to be initialized nevertheless. Otherwise, OID returns
778 * NDIS_STATUS_INVALID_PARAMETER. This is not clear in the documentation.
780 RtlZeroMemory(portArray, sizeof *portArray);
781 portArray->Header.Revision = NDIS_SWITCH_PORT_ARRAY_REVISION_1;
782 portArray->Header.Type = NDIS_OBJECT_TYPE_DEFAULT;
783 portArray->Header.Size = NDIS_SIZEOF_NDIS_SWITCH_PORT_ARRAY_REVISION_1;
785 status = OvsIssueOidRequest(switchContext, NdisRequestQueryInformation,
786 OID_SWITCH_PORT_ARRAY, NULL, 0,
787 (PVOID)portArray, arraySize,
789 if (status == NDIS_STATUS_SUCCESS) {
790 *portArrayOut = portArray;
794 OvsFreeMemory(portArray);
795 arraySize = reqdArraySize;
796 if (status != NDIS_STATUS_INVALID_LENGTH) {
799 } while(status == NDIS_STATUS_INVALID_LENGTH);
802 OVS_LOG_TRACE("Exit: status %8x.", status);
808 * --------------------------------------------------------------------------
809 * Utility function to get the array of nics on the extensible switch. Upon
810 * success, the caller needs to free the returned array.
811 * --------------------------------------------------------------------------
814 OvsGetNicsOnSwitch(POVS_SWITCH_CONTEXT switchContext,
815 PNDIS_SWITCH_NIC_ARRAY *nicArrayOut)
817 PNDIS_SWITCH_NIC_ARRAY nicArray;
818 UINT32 arraySize = sizeof *nicArray;
819 NDIS_STATUS status = NDIS_STATUS_FAILURE;
821 OVS_LOG_TRACE("Enter: switchContext: %p, nicArray: %p",
822 switchContext, nicArrayOut);
825 UINT32 reqdArraySize;
827 nicArray = OvsAllocateMemory(arraySize);
829 status = NDIS_STATUS_RESOURCES;
834 * Even though 'nicArray' is supposed to be populated by the OID, it
835 * needs to be initialized nevertheless. Otherwise, OID returns
836 * NDIS_STATUS_INVALID_PARAMETER. This is not clear in the documentation.
838 RtlZeroMemory(nicArray, sizeof *nicArray);
839 nicArray->Header.Revision = NDIS_SWITCH_NIC_ARRAY_REVISION_1;
840 nicArray->Header.Type = NDIS_OBJECT_TYPE_DEFAULT;
841 nicArray->Header.Size = NDIS_SIZEOF_NDIS_SWITCH_NIC_ARRAY_REVISION_1;
843 status = OvsIssueOidRequest(switchContext, NdisRequestQueryInformation,
844 OID_SWITCH_NIC_ARRAY, NULL, 0,
845 (PVOID)nicArray, arraySize,
847 if (status == NDIS_STATUS_SUCCESS) {
848 *nicArrayOut = nicArray;
852 OvsFreeMemory(nicArray);
853 arraySize = reqdArraySize;
854 if (status != NDIS_STATUS_INVALID_LENGTH) {
857 } while(status == NDIS_STATUS_INVALID_LENGTH);
860 OVS_LOG_TRACE("Exit: status %8x.", status);