datapath-windows: Hot add CPU support.
[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     status = OvsInit();
100     if (status != NDIS_STATUS_SUCCESS) {
101         goto cleanup;
102     }
103
104     gOvsExtDriverObject = driverObject;
105
106     RtlZeroMemory(&driverChars, sizeof driverChars);
107     driverChars.Header.Type = NDIS_OBJECT_TYPE_FILTER_DRIVER_CHARACTERISTICS;
108     driverChars.Header.Size = sizeof driverChars;
109     driverChars.Header.Revision = NDIS_FILTER_CHARACTERISTICS_REVISION_2;
110     driverChars.MajorNdisVersion = NDIS_FILTER_MAJOR_VERSION;
111     driverChars.MinorNdisVersion = NDIS_FILTER_MINOR_VERSION;
112     driverChars.MajorDriverVersion = 1;
113     driverChars.MinorDriverVersion = 0;
114     driverChars.Flags = 0;
115
116     RtlInitUnicodeString(&driverChars.ServiceName, ovsExtServiceName);
117     RtlInitUnicodeString(&ovsExtFriendlyNameUC, ovsExtFriendlyName);
118     RtlInitUnicodeString(&ovsExtGuidUC, ovsExtGuidStr);
119
120     driverChars.FriendlyName = ovsExtFriendlyNameUC;
121     driverChars.UniqueName = ovsExtGuidUC;
122
123     driverChars.AttachHandler = OvsExtAttach;
124     driverChars.DetachHandler = OvsExtDetach;
125     driverChars.RestartHandler = OvsExtRestart;
126     driverChars.PauseHandler = OvsExtPause;
127
128     driverChars.SendNetBufferListsHandler = OvsExtSendNBL;
129     driverChars.SendNetBufferListsCompleteHandler = OvsExtSendNBLComplete;
130     driverChars.CancelSendNetBufferListsHandler = OvsExtCancelSendNBL;
131     driverChars.ReceiveNetBufferListsHandler = NULL;
132     driverChars.ReturnNetBufferListsHandler = NULL;
133
134     driverChars.OidRequestHandler = OvsExtOidRequest;
135     driverChars.OidRequestCompleteHandler = OvsExtOidRequestComplete;
136     driverChars.CancelOidRequestHandler = OvsExtCancelOidRequest;
137
138     driverChars.DevicePnPEventNotifyHandler = NULL;
139     driverChars.NetPnPEventHandler = OvsExtNetPnPEvent;
140     driverChars.StatusHandler = NULL;
141
142     driverObject->DriverUnload = OvsExtUnload;
143
144     status = NdisFRegisterFilterDriver(driverObject,
145                                        (NDIS_HANDLE)gOvsExtDriverObject,
146                                        &driverChars,
147                                        &gOvsExtDriverHandle);
148     if (status != NDIS_STATUS_SUCCESS) {
149         goto cleanup;
150     }
151
152     /* Create the communication channel for userspace. */
153     status = OvsCreateDeviceObject(gOvsExtDriverHandle);
154     if (status != NDIS_STATUS_SUCCESS) {
155         goto cleanup;
156     }
157
158 cleanup:
159     if (status != NDIS_STATUS_SUCCESS){
160         OvsCleanup();
161         if (gOvsExtDriverHandle) {
162             NdisFDeregisterFilterDriver(gOvsExtDriverHandle);
163             gOvsExtDriverHandle = NULL;
164         }
165     }
166
167     return status;
168 }
169
170
171 /*
172  * --------------------------------------------------------------------------
173  * Un-init/Unload function for the OVS intermediate Driver.
174  * --------------------------------------------------------------------------
175  */
176 VOID
177 OvsExtUnload(struct _DRIVER_OBJECT *driverObject)
178 {
179     UNREFERENCED_PARAMETER(driverObject);
180
181     OvsDeleteDeviceObject();
182
183     NdisFDeregisterFilterDriver(gOvsExtDriverHandle);
184
185     /* Release driver associated data structures. */
186     OvsCleanup();
187 }
188
189
190 /*
191  * --------------------------------------------------------------------------
192  *  Implements filter driver's FilterStatus function.
193  * --------------------------------------------------------------------------
194  */
195 VOID
196 OvsExtStatus(NDIS_HANDLE filterModuleContext,
197              PNDIS_STATUS_INDICATION statusIndication)
198 {
199     UNREFERENCED_PARAMETER(statusIndication);
200     POVS_SWITCH_CONTEXT switchObject = (POVS_SWITCH_CONTEXT)filterModuleContext;
201
202     NdisFIndicateStatus(switchObject->NdisFilterHandle, statusIndication);
203     return;
204 }