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.
25 #define OVS_MAX_DPPORTS MAXUINT16
26 #define OVS_DPPORT_NUMBER_INVALID OVS_MAX_DPPORTS
28 * The local port (0) is a reserved port, that is not allowed to be be
29 * created by the netlink command vport add. On linux, this port is created
30 * at netlink command datapath new. However, on windows, we do not need to
31 * create it, and more, we shouldn't. The userspace attempts to create two
32 * internal vports, the LOCAL port (0) and the internal port (with any other
33 * port number). The non-LOCAL internal port is used in the userspace when it
34 * requests the internal port.
36 #define OVS_DPPORT_NUMBER_LOCAL 0
39 * A Vport, or Virtual Port, is a port on the OVS. It can be one of the
40 * following types. Some of the Vports are "real" ports on the hyper-v switch,
42 * - VIF port (VM's NIC)
43 * - External Adapters (physical NIC)
44 * - Internal Adapter (Virtual adapter exposed on the host).
45 * - Tunnel ports created by OVS userspace.
50 OVS_STATE_PORT_CREATED,
51 OVS_STATE_NIC_CREATED,
53 OVS_STATE_PORT_TEAR_DOWN,
54 OVS_STATE_PORT_DELETED,
57 typedef struct _OVS_VPORT_STATS {
64 typedef struct _OVS_VPORT_ERR_STATS {
69 } OVS_VPORT_ERR_STATS;
71 /* used for vport netlink commands. */
72 typedef struct _OVS_VPORT_FULL_STATS {
75 }OVS_VPORT_FULL_STATS;
77 * Each internal, external adapter or vritual adapter has
78 * one vport entry. In addition, we have one vport for each
79 * tunnel type, such as vxlan, gre
81 typedef struct _OVS_VPORT_ENTRY {
82 LIST_ENTRY ovsNameLink;
83 LIST_ENTRY portIdLink;
84 LIST_ENTRY portNoLink;
85 LIST_ENTRY tunnelVportLink;
87 OVS_VPORT_STATE ovsState;
88 OVS_VPORT_TYPE ovsType;
89 OVS_VPORT_STATS stats;
90 OVS_VPORT_ERR_STATS errStats;
93 /* ovsName is the ovs (datapath) port name - it is null terminated. */
94 CHAR ovsName[OVS_MAX_PORT_NAME_LENGTH];
97 NDIS_SWITCH_PORT_ID portId;
98 NDIS_SWITCH_NIC_INDEX nicIndex;
99 NDIS_SWITCH_NIC_TYPE nicType;
101 NDIS_SWITCH_PORT_STATE portState;
102 NDIS_SWITCH_NIC_STATE nicState;
103 NDIS_SWITCH_PORT_TYPE portType;
105 UINT8 permMacAddress[ETH_ADDR_LEN];
106 UINT8 currMacAddress[ETH_ADDR_LEN];
107 UINT8 vmMacAddress[ETH_ADDR_LEN];
109 NDIS_SWITCH_PORT_NAME hvPortName;
110 IF_COUNTED_STRING portFriendlyName;
111 NDIS_SWITCH_NIC_NAME nicName;
113 GUID netCfgInstanceId;
115 * OVS userpace has a notion of bridges which basically defines an
116 * L2-domain. Each "bridge" has an "internal" port of type
117 * OVS_VPORT_TYPE_INTERNAL. Such a port is connected to the OVS datapath in
118 * one end, and the other end is a virtual adapter on the hypervisor host.
119 * This is akin to the Hyper-V "internal" NIC. It is intuitive to map the
120 * Hyper-V "internal" NIC to the OVS bridge's "internal" port, but there's
121 * only one Hyper-V NIC but multiple bridges. To support multiple OVS bridge
122 * "internal" ports, we use the flag 'isBridgeInternal' in each vport. We
123 * support addition of multiple bridge-internal ports. A vport with
124 * 'isBridgeInternal' == TRUE is a dummy port and has no backing currently.
125 * If a flow actions specifies the output port to be a bridge-internal port,
126 * the port is silently ignored.
128 BOOLEAN isBridgeInternal;
130 UINT32 upcallPid; /* netlink upcall port id */
131 PNL_ATTR portOptions;
132 BOOLEAN isAbsentOnHv; /* Is this port present on the
134 } OVS_VPORT_ENTRY, *POVS_VPORT_ENTRY;
136 struct _OVS_SWITCH_CONTEXT;
138 POVS_VPORT_ENTRY OvsFindVportByPortNo(POVS_SWITCH_CONTEXT switchContext,
140 /* "name" is null-terminated */
141 POVS_VPORT_ENTRY OvsFindVportByOvsName(POVS_SWITCH_CONTEXT switchContext,
143 POVS_VPORT_ENTRY OvsFindVportByHvNameA(POVS_SWITCH_CONTEXT switchContext,
145 POVS_VPORT_ENTRY OvsFindVportByPortIdAndNicIndex(POVS_SWITCH_CONTEXT switchContext,
146 NDIS_SWITCH_PORT_ID portId,
147 NDIS_SWITCH_NIC_INDEX index);
148 POVS_VPORT_ENTRY OvsFindTunnelVportByDstPortAndType(POVS_SWITCH_CONTEXT switchContext,
150 OVS_VPORT_TYPE ovsPortType);
151 POVS_VPORT_ENTRY OvsFindTunnelVportByDstPortAndNWProto(POVS_SWITCH_CONTEXT switchContext,
154 POVS_VPORT_ENTRY OvsFindTunnelVportByPortType(POVS_SWITCH_CONTEXT switchContext,
155 OVS_VPORT_TYPE ovsPortType);
157 NDIS_STATUS OvsAddConfiguredSwitchPorts(struct _OVS_SWITCH_CONTEXT *switchContext);
158 NDIS_STATUS OvsInitConfiguredSwitchNics(struct _OVS_SWITCH_CONTEXT *switchContext);
160 VOID OvsClearAllSwitchVports(struct _OVS_SWITCH_CONTEXT *switchContext);
162 NDIS_STATUS HvCreateNic(POVS_SWITCH_CONTEXT switchContext,
163 PNDIS_SWITCH_NIC_PARAMETERS nicParam);
164 NDIS_STATUS HvCreatePort(POVS_SWITCH_CONTEXT switchContext,
165 PNDIS_SWITCH_PORT_PARAMETERS portParam,
166 NDIS_SWITCH_NIC_INDEX nicIndex);
167 NDIS_STATUS HvUpdatePort(POVS_SWITCH_CONTEXT switchContext,
168 PNDIS_SWITCH_PORT_PARAMETERS portParam);
169 VOID HvTeardownPort(POVS_SWITCH_CONTEXT switchContext,
170 PNDIS_SWITCH_PORT_PARAMETERS portParam);
171 VOID HvDeletePort(POVS_SWITCH_CONTEXT switchContext,
172 PNDIS_SWITCH_PORT_PARAMETERS portParam);
173 VOID HvConnectNic(POVS_SWITCH_CONTEXT switchContext,
174 PNDIS_SWITCH_NIC_PARAMETERS nicParam);
175 VOID HvUpdateNic(POVS_SWITCH_CONTEXT switchContext,
176 PNDIS_SWITCH_NIC_PARAMETERS nicParam);
177 VOID HvDeleteNic(POVS_SWITCH_CONTEXT switchContext,
178 PNDIS_SWITCH_NIC_PARAMETERS nicParam);
179 VOID HvDisconnectNic(POVS_SWITCH_CONTEXT switchContext,
180 PNDIS_SWITCH_NIC_PARAMETERS nicParam);
182 static __inline BOOLEAN
183 OvsIsTunnelVportType(OVS_VPORT_TYPE ovsType)
185 return ovsType == OVS_VPORT_TYPE_VXLAN ||
186 ovsType == OVS_VPORT_TYPE_STT ||
187 ovsType == OVS_VPORT_TYPE_GRE;
191 static __inline PVOID
192 GetOvsVportPriv(POVS_VPORT_ENTRY ovsVport)
194 return ovsVport->priv;
197 static __inline BOOLEAN
198 OvsIsInternalVportType(OVS_VPORT_TYPE ovsType)
200 return ovsType == OVS_VPORT_TYPE_INTERNAL;
203 static __inline BOOLEAN
204 OvsIsVirtualExternalVport(POVS_VPORT_ENTRY vport)
206 return vport->nicType == NdisSwitchNicTypeExternal &&
207 vport->nicIndex == 0;
210 static __inline BOOLEAN
211 OvsIsRealExternalVport(POVS_VPORT_ENTRY vport)
213 return vport->nicType == NdisSwitchNicTypeExternal &&
214 vport->nicIndex != 0;
217 static __inline BOOLEAN
218 OvsIsBridgeInternalVport(POVS_VPORT_ENTRY vport)
220 ASSERT(vport->isBridgeInternal != TRUE ||
221 vport->ovsType == OVS_VPORT_TYPE_INTERNAL);
222 return vport->isBridgeInternal == TRUE;
225 static __inline BOOLEAN
226 OvsIsInternalNIC(NDIS_SWITCH_NIC_TYPE nicType)
228 return nicType == NdisSwitchNicTypeInternal;
231 static __inline BOOLEAN
232 OvsIsRealExternalNIC(NDIS_SWITCH_NIC_TYPE nicType,
233 NDIS_SWITCH_NIC_INDEX nicIndex)
235 return nicType == NdisSwitchNicTypeExternal &&
239 NTSTATUS OvsRemoveAndDeleteVport(PVOID usrParamsCtx,
240 POVS_SWITCH_CONTEXT switchContext,
241 POVS_VPORT_ENTRY vport,
242 BOOLEAN hvDelete, BOOLEAN ovsDelete);
243 static __inline POVS_VPORT_ENTRY
244 OvsGetExternalVport(POVS_SWITCH_CONTEXT switchContext)
246 return switchContext->virtualExternalVport;
249 static __inline UINT32
250 OvsGetExternalMtu(POVS_SWITCH_CONTEXT switchContext)
252 ASSERT(OvsGetExternalVport(switchContext));
253 return ((POVS_VPORT_ENTRY) OvsGetExternalVport(switchContext))->mtu;
256 static __inline UINT16
257 GetPortFromPriv(POVS_VPORT_ENTRY vport)
260 PVOID vportPriv = GetOvsVportPriv(vport);
262 /* XXX would better to have a commom tunnel "parent" structure */
264 switch(vport->ovsType) {
265 case OVS_VPORT_TYPE_GRE:
267 case OVS_VPORT_TYPE_STT:
268 dstPort = ((POVS_STT_VPORT)vportPriv)->dstPort;
270 case OVS_VPORT_TYPE_VXLAN:
271 dstPort = ((POVS_VXLAN_VPORT)vportPriv)->dstPort;
274 ASSERT(! "Port is not a tunnel port");
276 ASSERT(dstPort || vport->ovsType == OVS_VPORT_TYPE_GRE);
280 NDIS_STATUS InitOvsVportCommon(POVS_SWITCH_CONTEXT switchContext,
281 POVS_VPORT_ENTRY vport);
282 NTSTATUS OvsInitTunnelVport(PVOID usrParamsCtx, POVS_VPORT_ENTRY vport,
283 OVS_VPORT_TYPE ovsType, UINT16 dstport);
284 NTSTATUS OvsInitBridgeInternalVport(POVS_VPORT_ENTRY vport);
286 POVS_VPORT_ENTRY OvsAllocateVport(VOID);
288 #endif /* __VPORT_H_ */