1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233
|
/*
* 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.
*/
/*
* This file contains the definition of the switch object for the OVS.
*/
#ifndef __SWITCH_H_
#define __SWITCH_H_ 1
#include "NetProto.h"
#include "BufferMgmt.h"
#include "TunnelIntf.h"
#define OVS_MAX_VPORT_ARRAY_SIZE 1024
#define OVS_MAX_PID_ARRAY_SIZE 1024
#define OVS_VPORT_MASK (OVS_MAX_VPORT_ARRAY_SIZE - 1)
#define OVS_PID_MASK (OVS_MAX_PID_ARRAY_SIZE - 1)
#define OVS_INTERNAL_VPORT_DEFAULT_INDEX 0
//Tunnel port indicies
#define RESERVED_START_INDEX1 1
#define OVS_TUNNEL_INDEX_START RESERVED_START_INDEX1
#define OVS_VXLAN_VPORT_INDEX 2
#define OVS_GRE_VPORT_INDEX 3
#define OVS_TUNNEL_INDEX_END OVS_GRE_VPORT_INDEX
#define OVS_MAX_PHYS_ADAPTERS 32
#define OVS_MAX_IP_VPOR 32
#define OVS_HASH_BASIS 0x13578642
typedef struct _OVS_VPORT_ENTRY *POVS_VPORT_ENTRY;
typedef struct _OVS_DATAPATH
{
PLIST_ENTRY flowTable; // Contains OvsFlows.
UINT32 nFlows; // Number of entries in flowTable.
// List_Links queues[64]; // Hash table of queue IDs.
/* Statistics. */
UINT64 hits; // Number of flow table hits.
UINT64 misses; // Number of flow table misses.
UINT64 lost; // Number of dropped misses.
/* Used to protect the flows in the flowtable. */
PNDIS_RW_LOCK_EX lock;
} OVS_DATAPATH, *POVS_DATAPATH;
/*
* OVS_SWITCH_CONTEXT
*
* The context allocated per switch., For OVS, we only
* support one switch which corresponding to one datapath.
* Each datapath can have multiple logical bridges configured
* which is maintained by vswitchd.
*/
typedef enum OVS_SWITCH_DATAFLOW_STATE
{
OvsSwitchPaused,
OvsSwitchRunning
} OVS_SWITCH_DATAFLOW_STATE, *POVS_SWITCH_DATAFLOW_STATE;
typedef enum OVS_SWITCH_CONTROFLOW_STATE
{
OvsSwitchUnknown,
OvsSwitchAttached,
OvsSwitchDetached
} OVS_SWITCH_CONTROLFLOW_STATE, *POVS_SWITCH_CONTROLFLOW_STATE;
// XXX: Take care of alignment and grouping members by cacheline
typedef struct _OVS_SWITCH_CONTEXT
{
/* Coarse and fine-grained switch states. */
OVS_SWITCH_DATAFLOW_STATE dataFlowState;
OVS_SWITCH_CONTROLFLOW_STATE controlFlowState;
BOOLEAN isActivated;
BOOLEAN isActivateFailed;
UINT32 dpNo;
/*
* 'virtualExternalVport' represents default external interface. This is
* a virtual interface. The friendly name of such an interface has
* been observed to be: "Microsoft Default External Interface". This NIC
* has 'NicIndex' == 0.
*
* The "real" physical external NIC has 'NicIndex' > 0. For each
* external interface, virtual or physical, NDIS gives an NIC level
* OID callback. Note that, even though there are multiple "NICs",
* there's only one underlying Hyper-V port. Thus, we get a single
* NDIS port-level callback, but multiple NDIS NIC-level callbacks.
*
* The virtual external NIC can be accessed at 'virtualExternalVport', and
* is assigned the name "external.defaultAdapter". The virtual external
* NIC is not inserted into the 'portIdHashArray' since the port must not
* be exposed to OVS userspace.
*
* The physical external NICs are assigned names "external.%INDEX%",
* where '%INDEX%' represents the 'NicIndex' of the NIC.
*
* While adding a physical external NIC in OvsInitConfiguredSwitchNics(),
* some required properties of the vport are available only at the
* NDIS port-level. So, these are copied from 'virtualExternalVport'.
* The vport created for the physical external NIC is inserted into the
* 'portIdHashArray'.
*
* When the virtual external NIC is torn down or deleted, the
* corresponding physical external ports are also torn down or
* deleted. The number of physical external NICs is tracked by
* 'numPhysicalNics'.
*/
NDIS_SWITCH_PORT_ID virtualExternalPortId;
POVS_VPORT_ENTRY virtualExternalVport; /* the virtual adapter
* vport */
INT32 countInternalVports; /* the number of internal
* vports */
UINT32 ipHelperBoundVportNo; /* vportNo bound to
* IpHelper */
/*
* 'portIdHashArray' ONLY contains ports that exist on the Hyper-V switch,
* namely: VIF (vNIC) ports, external port and Hyper-V internal port.
* 'numHvVports' counts the ports in 'portIdHashArray'. If a port got
* deleted on the Hyper-V switch, it gets deleted from 'portIdHashArray'.
* The port itself will not get deallocated if it has been added from OVS
* userspace. 'numHvVports' is decremented when the port is deallocated.
*
* 'portNoHashArray' ONLY contains ports that are added from OVS userspace,
* regardless of whether that port exists on the Hyper-V switch or not.
* Tunnel ports and bridge-internal ports are examples of ports that do not
* exist on the Hyper-V switch, and 'numNonHvVports' counts such ports in
* 'portNoHashArray'.
*
* 'tunnelVportsArray' contains tunnel ports that are added from OVS
* userspace. Currently only VXLAN tunnels are added in this list.
*
* 'ovsPortNameHashArray' contains the same entries as 'portNoHashArray' but
* hashed on a different key.
*/
PLIST_ENTRY portIdHashArray; // based on Hyper-V portId
PLIST_ENTRY portNoHashArray; // based on ovs port number
PLIST_ENTRY tunnelVportsArray; // based on ovs dst port number
PLIST_ENTRY ovsPortNameHashArray; // based on ovsName
PLIST_ENTRY pidHashArray; // based on packet pids
NDIS_SPIN_LOCK pidHashLock; // Lock for pidHash table
UINT32 numPhysicalNics; // the number of physical
// external NICs.
UINT32 numHvVports;
UINT32 numNonHvVports;
/* Lock taken over the switch. This protects the ports on the switch. */
PNDIS_RW_LOCK_EX dispatchLock;
/* The flowtable. */
OVS_DATAPATH datapath;
/* Handle to the OVSExt filter driver. Same as 'gOvsExtDriverHandle'. */
NDIS_HANDLE NdisFilterHandle;
/* Handle and callbacks exposed by the underlying hyper-v switch. */
NDIS_SWITCH_CONTEXT NdisSwitchContext;
NDIS_SWITCH_OPTIONAL_HANDLERS NdisSwitchHandlers;
volatile LONG pendingInjectedNblCount;
volatile LONG pendingOidCount;
OVS_NBL_POOL ovsPool;
} OVS_SWITCH_CONTEXT, *POVS_SWITCH_CONTEXT;
_IRQL_raises_(DISPATCH_LEVEL)
_IRQL_saves_global_(OldIrql, lockState)
_Acquires_lock_(datapath->lock)
static __inline VOID
OvsAcquireDatapathRead(OVS_DATAPATH *datapath,
LOCK_STATE_EX *lockState,
BOOLEAN dispatch)
{
ASSERT(datapath);
NdisAcquireRWLockRead(datapath->lock, lockState,
dispatch ? NDIS_RWL_AT_DISPATCH_LEVEL : 0);
}
_IRQL_raises_(DISPATCH_LEVEL)
_IRQL_saves_global_(OldIrql, lockState)
_Acquires_lock_(datapath->lock)
static __inline VOID
OvsAcquireDatapathWrite(OVS_DATAPATH *datapath,
LOCK_STATE_EX *lockState,
BOOLEAN dispatch)
{
ASSERT(datapath);
NdisAcquireRWLockWrite(datapath->lock, lockState,
dispatch ? NDIS_RWL_AT_DISPATCH_LEVEL : 0);
}
_IRQL_requires_(DISPATCH_LEVEL)
_IRQL_restores_global_(OldIrql, lockState)
_Requires_lock_held_(datapath->lock)
_Releases_lock_(datapath->lock)
static __inline VOID
OvsReleaseDatapath(OVS_DATAPATH *datapath,
LOCK_STATE_EX *lockState)
{
ASSERT(datapath);
NdisReleaseRWLock(datapath->lock, lockState);
}
BOOLEAN
OvsAcquireSwitchContext(VOID);
VOID
OvsReleaseSwitchContext(POVS_SWITCH_CONTEXT switchContext);
#endif /* __SWITCH_H_ */
|