summaryrefslogtreecommitdiff
path: root/datapath-windows/ovsext/TunnelFilter.c
diff options
context:
space:
mode:
authorSamuel Ghinet <sghinet@cloudbasesolutions.com>2014-08-29 04:06:48 +0000
committerBen Pfaff <blp@nicira.com>2014-08-29 07:55:05 -0700
commitfa1324c92810c6b1e33b7e87caaaf2e6c4041040 (patch)
tree8e06f5d991d755215bb6839a997bc58721b2d754 /datapath-windows/ovsext/TunnelFilter.c
parentfd972eb87a888242fb1a8ec2394fa7b3030fbd7d (diff)
downloadopenvswitch-fa1324c92810c6b1e33b7e87caaaf2e6c4041040.tar.gz
datapath-windows: Rename files.
This patch includes the file renaming and accommodations needed for the file renaming to build the forwarding extension for Hyper-V. This patch is also a follow-up for the thread: http://openvswitch.org/pipermail/dev/2014-August/044005.html Signed-off-by: Samuel Ghinet <sghinet@cloudbasesolutions.com> Co-authored-by: Alin Gabriel Serdean <aserdean@cloudbasesolutions.com> Signed-off-by: Ben Pfaff <blp@nicira.com>
Diffstat (limited to 'datapath-windows/ovsext/TunnelFilter.c')
-rw-r--r--datapath-windows/ovsext/TunnelFilter.c343
1 files changed, 343 insertions, 0 deletions
diff --git a/datapath-windows/ovsext/TunnelFilter.c b/datapath-windows/ovsext/TunnelFilter.c
new file mode 100644
index 000000000..b191dd1f5
--- /dev/null
+++ b/datapath-windows/ovsext/TunnelFilter.c
@@ -0,0 +1,343 @@
+/*
+ * Copyright (c) 2014 VMware, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "precomp.h"
+
+#pragma warning(push)
+#pragma warning(disable:4201) // unnamed struct/union
+
+
+#include <fwpsk.h>
+
+#pragma warning(pop)
+
+#include <fwpmk.h>
+#include <ws2ipdef.h>
+#include <in6addr.h>
+#include <ip2string.h>
+
+#include "Tunnel.h"
+#include "Switch.h"
+#include "Vport.h"
+#include "Event.h"
+#include "User.h"
+#include "Vxlan.h"
+
+
+#define INITGUID
+#include <guiddef.h>
+
+
+/* Configurable parameters (addresses and ports are in host order) */
+UINT16 configNewDestPort = VXLAN_UDP_PORT;
+
+/*
+ * Callout and sublayer GUIDs
+ */
+// b16b0a6e-2b2a-41a3-8b39-bd3ffc855ff8
+DEFINE_GUID(
+ OVS_TUNNEL_CALLOUT_V4,
+ 0xb16b0a6e,
+ 0x2b2a,
+ 0x41a3,
+ 0x8b, 0x39, 0xbd, 0x3f, 0xfc, 0x85, 0x5f, 0xf8
+ );
+
+/* 0104fd7e-c825-414e-94c9-f0d525bbc169 */
+DEFINE_GUID(
+ OVS_TUNNEL_SUBLAYER,
+ 0x0104fd7e,
+ 0xc825,
+ 0x414e,
+ 0x94, 0xc9, 0xf0, 0xd5, 0x25, 0xbb, 0xc1, 0x69
+ );
+
+/*
+ * Callout driver global variables
+ */
+PDEVICE_OBJECT gDeviceObject;
+
+HANDLE gEngineHandle;
+UINT32 gCalloutIdV4;
+
+
+/* Callout driver implementation */
+
+NTSTATUS
+OvsTunnelAddFilter(PWSTR filterName,
+ const PWSTR filterDesc,
+ USHORT remotePort,
+ FWP_DIRECTION direction,
+ UINT64 context,
+ const GUID *layerKey,
+ const GUID *calloutKey)
+{
+ NTSTATUS status = STATUS_SUCCESS;
+ FWPM_FILTER filter = {0};
+ FWPM_FILTER_CONDITION filterConditions[3] = {0};
+ UINT conditionIndex;
+
+ UNREFERENCED_PARAMETER(remotePort);
+ UNREFERENCED_PARAMETER(direction);
+
+ filter.layerKey = *layerKey;
+ filter.displayData.name = (wchar_t*)filterName;
+ filter.displayData.description = (wchar_t*)filterDesc;
+
+ filter.action.type = FWP_ACTION_CALLOUT_TERMINATING;
+ filter.action.calloutKey = *calloutKey;
+ filter.filterCondition = filterConditions;
+ filter.subLayerKey = OVS_TUNNEL_SUBLAYER;
+ filter.weight.type = FWP_EMPTY; // auto-weight.
+ filter.rawContext = context;
+
+ conditionIndex = 0;
+
+ filterConditions[conditionIndex].fieldKey = FWPM_CONDITION_DIRECTION;
+ filterConditions[conditionIndex].matchType = FWP_MATCH_EQUAL;
+ filterConditions[conditionIndex].conditionValue.type = FWP_UINT32;
+ filterConditions[conditionIndex].conditionValue.uint32 = direction;
+
+ conditionIndex++;
+
+ filterConditions[conditionIndex].fieldKey = FWPM_CONDITION_IP_LOCAL_PORT;
+ filterConditions[conditionIndex].matchType = FWP_MATCH_EQUAL;
+ filterConditions[conditionIndex].conditionValue.type = FWP_UINT16;
+ filterConditions[conditionIndex].conditionValue.uint16 = remotePort;
+
+ conditionIndex++;
+
+ filter.numFilterConditions = conditionIndex;
+
+ status = FwpmFilterAdd(gEngineHandle,
+ &filter,
+ NULL,
+ NULL);
+
+ return status;
+}
+
+/*
+ * --------------------------------------------------------------------------
+ * This function registers callouts and filters that intercept UDP traffic at
+ * WFP FWPM_LAYER_DATAGRAM_DATA_V4
+ * --------------------------------------------------------------------------
+ */
+NTSTATUS
+OvsTunnelRegisterDatagramDataCallouts(const GUID *layerKey,
+ const GUID *calloutKey,
+ VOID *deviceObject,
+ UINT32 *calloutId)
+{
+ NTSTATUS status = STATUS_SUCCESS;
+
+ FWPS_CALLOUT sCallout = {0};
+ FWPM_CALLOUT mCallout = {0};
+
+ FWPM_DISPLAY_DATA displayData = {0};
+
+ BOOLEAN calloutRegistered = FALSE;
+
+ sCallout.calloutKey = *calloutKey;
+ sCallout.classifyFn = OvsTunnelClassify;
+ sCallout.notifyFn = OvsTunnelNotify;
+#if FLOW_CONTEXT
+ /* Currnetly we don't associate a context with the flow */
+ sCallout.flowDeleteFn = OvsTunnelFlowDelete;
+ sCallout.flags = FWP_CALLOUT_FLAG_CONDITIONAL_ON_FLOW;
+#endif
+
+ status = FwpsCalloutRegister(deviceObject,
+ &sCallout,
+ calloutId);
+
+ if (!NT_SUCCESS(status)) {
+ goto Exit;
+ }
+ calloutRegistered = TRUE;
+
+ displayData.name = L"Datagram-Data OVS Callout";
+ displayData.description = L"Proxies destination address/port for UDP";
+
+ mCallout.calloutKey = *calloutKey;
+ mCallout.displayData = displayData;
+ mCallout.applicableLayer = *layerKey;
+
+ status = FwpmCalloutAdd(gEngineHandle,
+ &mCallout,
+ NULL,
+ NULL);
+
+ if (!NT_SUCCESS(status)) {
+ goto Exit;
+ }
+
+ status = OvsTunnelAddFilter(L"Datagram-Data OVS Filter (Inbound)",
+ L"address/port for UDP",
+ configNewDestPort,
+ FWP_DIRECTION_INBOUND,
+ 0,
+ layerKey,
+ calloutKey);
+
+Exit:
+
+ if (!NT_SUCCESS(status)){
+ if (calloutRegistered) {
+ FwpsCalloutUnregisterById(*calloutId);
+ *calloutId = 0;
+ }
+ }
+
+ return status;
+}
+
+/*
+ * --------------------------------------------------------------------------
+ * This function registers dynamic callouts and filters that intercept UDP
+ * Callouts and filters will be removed during De-Initialize.
+ * --------------------------------------------------------------------------
+ */
+NTSTATUS
+OvsTunnelRegisterCallouts(VOID *deviceObject)
+{
+ NTSTATUS status = STATUS_SUCCESS;
+ FWPM_SUBLAYER OvsTunnelSubLayer;
+
+ BOOLEAN engineOpened = FALSE;
+ BOOLEAN inTransaction = FALSE;
+
+ FWPM_SESSION session = {0};
+
+ session.flags = FWPM_SESSION_FLAG_DYNAMIC;
+
+ status = FwpmEngineOpen(NULL,
+ RPC_C_AUTHN_WINNT,
+ NULL,
+ &session,
+ &gEngineHandle);
+
+ if (!NT_SUCCESS(status)) {
+ goto Exit;
+ }
+ engineOpened = TRUE;
+
+ status = FwpmTransactionBegin(gEngineHandle, 0);
+ if (!NT_SUCCESS(status)) {
+ goto Exit;
+ }
+ inTransaction = TRUE;
+
+ RtlZeroMemory(&OvsTunnelSubLayer, sizeof(FWPM_SUBLAYER));
+
+ OvsTunnelSubLayer.subLayerKey = OVS_TUNNEL_SUBLAYER;
+ OvsTunnelSubLayer.displayData.name = L"Datagram-Data OVS Sub-Layer";
+ OvsTunnelSubLayer.displayData.description =
+ L"Sub-Layer for use by Datagram-Data OVS callouts";
+ OvsTunnelSubLayer.flags = 0;
+ OvsTunnelSubLayer.weight = FWP_EMPTY; /* auto-weight */
+
+ status = FwpmSubLayerAdd(gEngineHandle, &OvsTunnelSubLayer, NULL);
+ if (!NT_SUCCESS(status)) {
+ goto Exit;
+ }
+
+ // In order to use this callout a socket must be opened
+ status = OvsTunnelRegisterDatagramDataCallouts(&FWPM_LAYER_DATAGRAM_DATA_V4,
+ &OVS_TUNNEL_CALLOUT_V4,
+ deviceObject,
+ &gCalloutIdV4);
+ if (!NT_SUCCESS(status)) {
+ goto Exit;
+ }
+
+ status = FwpmTransactionCommit(gEngineHandle);
+ if (!NT_SUCCESS(status)){
+ goto Exit;
+ }
+ inTransaction = FALSE;
+
+Exit:
+
+ if (!NT_SUCCESS(status)) {
+ if (inTransaction) {
+ FwpmTransactionAbort(gEngineHandle);
+ }
+ if (engineOpened) {
+ FwpmEngineClose(gEngineHandle);
+ gEngineHandle = NULL;
+ }
+ }
+
+ return status;
+}
+
+VOID
+OvsTunnelUnregisterCallouts(VOID)
+{
+ FwpmEngineClose(gEngineHandle);
+ gEngineHandle = NULL;
+ FwpsCalloutUnregisterById(gCalloutIdV4);
+}
+
+
+VOID
+OvsTunnelFilterUninitialize(PDRIVER_OBJECT driverObject)
+{
+ UNREFERENCED_PARAMETER(driverObject);
+
+ OvsTunnelUnregisterCallouts();
+ IoDeleteDevice(gDeviceObject);
+}
+
+
+NTSTATUS
+OvsTunnelFilterInitialize(PDRIVER_OBJECT driverObject)
+{
+ NTSTATUS status = STATUS_SUCCESS;
+ UNICODE_STRING deviceName;
+
+ RtlInitUnicodeString(&deviceName,
+ L"\\Device\\OvsTunnelFilter");
+
+ status = IoCreateDevice(driverObject,
+ 0,
+ &deviceName,
+ FILE_DEVICE_NETWORK,
+ 0,
+ FALSE,
+ &gDeviceObject);
+
+ if (!NT_SUCCESS(status)){
+ goto Exit;
+ }
+
+ status = OvsTunnelRegisterCallouts(gDeviceObject);
+
+Exit:
+
+ if (!NT_SUCCESS(status)){
+ if (gEngineHandle != NULL) {
+ OvsTunnelUnregisterCallouts();
+ }
+
+ if (gDeviceObject) {
+ IoDeleteDevice(gDeviceObject);
+ }
+ }
+
+ return status;
+}