Merge "master" into "ovn".
[cascardo/ovs.git] / datapath-windows / ovsext / Driver.c
1 /*
2  * Copyright (c) 2014 VMware, Inc.
3  *
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:
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  */
16
17 #include "precomp.h"
18 #include "Switch.h"
19 #include "User.h"
20 #include "Datapath.h"
21
22 #ifdef OVS_DBG_MOD
23 #undef OVS_DBG_MOD
24 #endif
25 #define OVS_DBG_MOD OVS_DBG_DRIVER
26 #include "Debug.h"
27
28 /* Global handles. XXX: Some of them need not be global. */
29 /*
30  * Maps to DriverObject and FilterDriverContext parameters in the NDIS filter
31  * driver functions.
32  * DriverObject is specified by NDIS.
33  * FilterDriverContext is specified by the filter driver.
34  */
35 NDIS_HANDLE gOvsExtDriverObject;
36
37 /*
38  * Maps to NdisFilterHandle parameter in the NDIS filter driver functions.
39  * NdisFilterHandle is returned by NDISFRegisterFilterDriver.
40  */
41 NDIS_HANDLE gOvsExtDriverHandle;
42
43 /*
44  * Maps to FilterModuleContext parameter in the NDIS filter driver functions.
45  * FilterModuleContext is a allocated by the driver in the FilterAttach
46  * function.
47  */
48 extern POVS_SWITCH_CONTEXT gOvsSwitchContext;
49
50 static PWCHAR ovsExtFriendlyName = L"Open vSwitch Extension";
51 static PWCHAR ovsExtServiceName = L"OVSExt";
52 NDIS_STRING ovsExtGuidUC;
53 NDIS_STRING ovsExtFriendlyNameUC;
54
55 static PWCHAR ovsExtGuidStr = L"{583CC151-73EC-4A6A-8B47-578297AD7623}";
56 static const GUID ovsExtGuid = {
57       0x583cc151,
58       0x73ec,
59       0x4a6a,
60       {0x8b, 0x47, 0x57, 0x82, 0x97, 0xad, 0x76, 0x23}
61 };
62
63 /* Declarations of callback functions for the filter driver. */
64 DRIVER_UNLOAD OvsExtUnload;
65 FILTER_NET_PNP_EVENT OvsExtNetPnPEvent;
66 FILTER_STATUS OvsExtStatus;
67
68 FILTER_ATTACH OvsExtAttach;
69 FILTER_DETACH OvsExtDetach;
70 FILTER_RESTART OvsExtRestart;
71 FILTER_PAUSE OvsExtPause;
72
73 FILTER_SEND_NET_BUFFER_LISTS OvsExtSendNBL;
74 FILTER_SEND_NET_BUFFER_LISTS_COMPLETE OvsExtSendNBLComplete;
75 FILTER_CANCEL_SEND_NET_BUFFER_LISTS OvsExtCancelSendNBL;
76 FILTER_RECEIVE_NET_BUFFER_LISTS OvsExtReceiveNBL;
77 FILTER_RETURN_NET_BUFFER_LISTS OvsExtReturnNBL;
78
79 FILTER_OID_REQUEST OvsExtOidRequest;
80 FILTER_OID_REQUEST_COMPLETE OvsExtOidRequestComplete;
81 FILTER_CANCEL_OID_REQUEST OvsExtCancelOidRequest;
82
83
84 /*
85  * --------------------------------------------------------------------------
86  * Init/Load function for the OVSEXT filter Driver.
87  * --------------------------------------------------------------------------
88  */
89 NTSTATUS
90 DriverEntry(PDRIVER_OBJECT driverObject,
91             PUNICODE_STRING registryPath)
92 {
93     NDIS_STATUS status;
94     NDIS_FILTER_DRIVER_CHARACTERISTICS driverChars;
95
96     UNREFERENCED_PARAMETER(registryPath);
97
98     /* Initialize driver associated data structures. */
99     OvsInit();
100
101     gOvsExtDriverObject = driverObject;
102
103     RtlZeroMemory(&driverChars, sizeof driverChars);
104     driverChars.Header.Type = NDIS_OBJECT_TYPE_FILTER_DRIVER_CHARACTERISTICS;
105     driverChars.Header.Size = sizeof driverChars;
106     driverChars.Header.Revision = NDIS_FILTER_CHARACTERISTICS_REVISION_2;
107     driverChars.MajorNdisVersion = NDIS_FILTER_MAJOR_VERSION;
108     driverChars.MinorNdisVersion = NDIS_FILTER_MINOR_VERSION;
109     driverChars.MajorDriverVersion = 1;
110     driverChars.MinorDriverVersion = 0;
111     driverChars.Flags = 0;
112
113     RtlInitUnicodeString(&driverChars.ServiceName, ovsExtServiceName);
114     RtlInitUnicodeString(&ovsExtFriendlyNameUC, ovsExtFriendlyName);
115     RtlInitUnicodeString(&ovsExtGuidUC, ovsExtGuidStr);
116
117     driverChars.FriendlyName = ovsExtFriendlyNameUC;
118     driverChars.UniqueName = ovsExtGuidUC;
119
120     driverChars.AttachHandler = OvsExtAttach;
121     driverChars.DetachHandler = OvsExtDetach;
122     driverChars.RestartHandler = OvsExtRestart;
123     driverChars.PauseHandler = OvsExtPause;
124
125     driverChars.SendNetBufferListsHandler = OvsExtSendNBL;
126     driverChars.SendNetBufferListsCompleteHandler = OvsExtSendNBLComplete;
127     driverChars.CancelSendNetBufferListsHandler = OvsExtCancelSendNBL;
128     driverChars.ReceiveNetBufferListsHandler = NULL;
129     driverChars.ReturnNetBufferListsHandler = NULL;
130
131     driverChars.OidRequestHandler = OvsExtOidRequest;
132     driverChars.OidRequestCompleteHandler = OvsExtOidRequestComplete;
133     driverChars.CancelOidRequestHandler = OvsExtCancelOidRequest;
134
135     driverChars.DevicePnPEventNotifyHandler = NULL;
136     driverChars.NetPnPEventHandler = OvsExtNetPnPEvent;
137     driverChars.StatusHandler = NULL;
138
139     driverObject->DriverUnload = OvsExtUnload;
140
141     status = NdisFRegisterFilterDriver(driverObject,
142                                        (NDIS_HANDLE) gOvsExtDriverObject,
143                                        &driverChars, &gOvsExtDriverHandle);
144     if (status != NDIS_STATUS_SUCCESS) {
145         return status;
146     }
147
148     /* Create the communication channel for usersapce. */
149     status = OvsCreateDeviceObject(gOvsExtDriverHandle);
150     if (status != NDIS_STATUS_SUCCESS) {
151         OvsCleanup();
152         NdisFDeregisterFilterDriver(gOvsExtDriverHandle);
153         gOvsExtDriverHandle = NULL;
154     }
155
156     return status;
157 }
158
159
160 /*
161  * --------------------------------------------------------------------------
162  * Un-init/Unload function for the OVS intermediate Driver.
163  * --------------------------------------------------------------------------
164  */
165 VOID
166 OvsExtUnload(struct _DRIVER_OBJECT *driverObject)
167 {
168     UNREFERENCED_PARAMETER(driverObject);
169
170     /* Release driver associated data structures. */
171     OvsCleanup();
172
173     OvsDeleteDeviceObject();
174
175     NdisFDeregisterFilterDriver(gOvsExtDriverHandle);
176 }
177
178
179 /*
180  * --------------------------------------------------------------------------
181  *  Implements filter driver's FilterStatus function.
182  * --------------------------------------------------------------------------
183  */
184 VOID
185 OvsExtStatus(NDIS_HANDLE filterModuleContext,
186              PNDIS_STATUS_INDICATION statusIndication)
187 {
188     UNREFERENCED_PARAMETER(statusIndication);
189     POVS_SWITCH_CONTEXT switchObject = (POVS_SWITCH_CONTEXT)filterModuleContext;
190
191     NdisFIndicateStatus(switchObject->NdisFilterHandle, statusIndication);
192     return;
193 }