f0a9acd9ef87c7b399c3b82aa33f24b0730b8bd1
[cascardo/ovs.git] / datapath-windows / ovsext / Vport.h
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 #ifndef __VPORT_H_
18 #define __VPORT_H_ 1
19
20 #include "Gre.h"
21 #include "Stt.h"
22 #include "Switch.h"
23 #include "VxLan.h"
24
25 #define OVS_MAX_DPPORTS             MAXUINT16
26 #define OVS_DPPORT_NUMBER_INVALID   OVS_MAX_DPPORTS
27 /*
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.
35  */
36 #define OVS_DPPORT_NUMBER_LOCAL    0
37
38 /*
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,
41  * and some are not:
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.
46  */
47
48 typedef enum {
49     OVS_STATE_UNKNOWN,
50     OVS_STATE_PORT_CREATED,
51     OVS_STATE_NIC_CREATED,
52     OVS_STATE_CONNECTED,
53     OVS_STATE_PORT_TEAR_DOWN,
54     OVS_STATE_PORT_DELETED,
55 } OVS_VPORT_STATE;
56
57 typedef struct _OVS_VPORT_STATS {
58     UINT64 rxPackets;
59     UINT64 txPackets;
60     UINT64 rxBytes;
61     UINT64 txBytes;
62 } OVS_VPORT_STATS;
63
64 typedef struct _OVS_VPORT_ERR_STATS {
65     UINT64  rxErrors;
66     UINT64  txErrors;
67     UINT64  rxDropped;
68     UINT64  txDropped;
69 } OVS_VPORT_ERR_STATS;
70
71 /* used for vport netlink commands. */
72 typedef struct _OVS_VPORT_FULL_STATS {
73     OVS_VPORT_STATS;
74     OVS_VPORT_ERR_STATS;
75 }OVS_VPORT_FULL_STATS;
76 /*
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
80  */
81 typedef struct _OVS_VPORT_ENTRY {
82     LIST_ENTRY             ovsNameLink;
83     LIST_ENTRY             portIdLink;
84     LIST_ENTRY             portNoLink;
85     LIST_ENTRY             tunnelVportLink;
86
87     OVS_VPORT_STATE        ovsState;
88     OVS_VPORT_TYPE         ovsType;
89     OVS_VPORT_STATS        stats;
90     OVS_VPORT_ERR_STATS    errStats;
91     UINT32                 portNo;
92     UINT32                 mtu;
93     /* ovsName is the ovs (datapath) port name - it is null terminated. */
94     CHAR                   ovsName[OVS_MAX_PORT_NAME_LENGTH];
95
96     PVOID                  priv;
97     NDIS_SWITCH_PORT_ID    portId;
98     NDIS_SWITCH_NIC_INDEX  nicIndex;
99     NDIS_SWITCH_NIC_TYPE   nicType;
100     UINT16                 numaNodeId;
101     NDIS_SWITCH_PORT_STATE portState;
102     NDIS_SWITCH_NIC_STATE  nicState;
103     NDIS_SWITCH_PORT_TYPE  portType;
104
105     UINT8                  permMacAddress[ETH_ADDR_LEN];
106     UINT8                  currMacAddress[ETH_ADDR_LEN];
107     UINT8                  vmMacAddress[ETH_ADDR_LEN];
108
109     NDIS_SWITCH_PORT_NAME  hvPortName;
110     IF_COUNTED_STRING      portFriendlyName;
111     NDIS_SWITCH_NIC_NAME   nicName;
112     NDIS_VM_NAME           vmName;
113     GUID                   netCfgInstanceId;
114     /*
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.
127      */
128     BOOLEAN                isBridgeInternal;
129     BOOLEAN                isExternal;
130     UINT32                 upcallPid; /* netlink upcall port id */
131     PNL_ATTR               portOptions;
132     BOOLEAN                isAbsentOnHv; /* Is this port present on the
133                                              Hyper-V switch? */
134 } OVS_VPORT_ENTRY, *POVS_VPORT_ENTRY;
135
136 struct _OVS_SWITCH_CONTEXT;
137
138 POVS_VPORT_ENTRY OvsFindVportByPortNo(POVS_SWITCH_CONTEXT switchContext,
139                                       UINT32 portNo);
140 /* "name" is null-terminated */
141 POVS_VPORT_ENTRY OvsFindVportByOvsName(POVS_SWITCH_CONTEXT switchContext,
142                                        PSTR name);
143 POVS_VPORT_ENTRY OvsFindVportByHvNameA(POVS_SWITCH_CONTEXT switchContext,
144                                        PSTR name);
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,
149                                                     UINT16 dstPort,
150                                                     OVS_VPORT_TYPE ovsPortType);
151 POVS_VPORT_ENTRY OvsFindTunnelVportByDstPortAndNWProto(POVS_SWITCH_CONTEXT switchContext,
152                                                        UINT16 dstPort,
153                                                        UINT8 nwProto);
154 POVS_VPORT_ENTRY OvsFindTunnelVportByPortType(POVS_SWITCH_CONTEXT switchContext,
155                                               OVS_VPORT_TYPE ovsPortType);
156
157 NDIS_STATUS OvsAddConfiguredSwitchPorts(struct _OVS_SWITCH_CONTEXT *switchContext);
158 NDIS_STATUS OvsInitConfiguredSwitchNics(struct _OVS_SWITCH_CONTEXT *switchContext);
159
160 VOID OvsClearAllSwitchVports(struct _OVS_SWITCH_CONTEXT *switchContext);
161
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);
181
182 static __inline BOOLEAN
183 OvsIsTunnelVportType(OVS_VPORT_TYPE ovsType)
184 {
185     return ovsType == OVS_VPORT_TYPE_VXLAN ||
186            ovsType == OVS_VPORT_TYPE_STT ||
187            ovsType == OVS_VPORT_TYPE_GRE;
188 }
189
190
191 static __inline PVOID
192 GetOvsVportPriv(POVS_VPORT_ENTRY ovsVport)
193 {
194     return ovsVport->priv;
195 }
196
197 static __inline BOOLEAN
198 OvsIsInternalVportType(OVS_VPORT_TYPE ovsType)
199 {
200     return ovsType == OVS_VPORT_TYPE_INTERNAL;
201 }
202
203 static __inline BOOLEAN
204 OvsIsVirtualExternalVport(POVS_VPORT_ENTRY vport)
205 {
206     return vport->nicType == NdisSwitchNicTypeExternal &&
207            vport->nicIndex == 0;
208 }
209
210 static __inline BOOLEAN
211 OvsIsRealExternalVport(POVS_VPORT_ENTRY vport)
212 {
213     return vport->nicType == NdisSwitchNicTypeExternal &&
214            vport->nicIndex != 0;
215 }
216
217 static __inline BOOLEAN
218 OvsIsBridgeInternalVport(POVS_VPORT_ENTRY vport)
219 {
220     ASSERT(vport->isBridgeInternal != TRUE ||
221            vport->ovsType == OVS_VPORT_TYPE_INTERNAL);
222     return vport->isBridgeInternal == TRUE;
223 }
224
225 static __inline BOOLEAN
226 OvsIsInternalNIC(NDIS_SWITCH_NIC_TYPE   nicType)
227 {
228     return nicType == NdisSwitchNicTypeInternal;
229 }
230
231 static __inline BOOLEAN
232 OvsIsRealExternalNIC(NDIS_SWITCH_NIC_TYPE   nicType,
233                      NDIS_SWITCH_NIC_INDEX  nicIndex)
234 {
235     return nicType == NdisSwitchNicTypeExternal &&
236            nicIndex != 0;
237 }
238
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)
245 {
246     return switchContext->virtualExternalVport;
247 }
248
249 static __inline UINT32
250 OvsGetExternalMtu(POVS_SWITCH_CONTEXT switchContext)
251 {
252     ASSERT(OvsGetExternalVport(switchContext));
253     return ((POVS_VPORT_ENTRY) OvsGetExternalVport(switchContext))->mtu;
254 }
255
256 static __inline UINT16
257 GetPortFromPriv(POVS_VPORT_ENTRY vport)
258 {
259     UINT16 dstPort = 0;
260     PVOID vportPriv = GetOvsVportPriv(vport);
261
262     /* XXX would better to have a commom tunnel "parent" structure */
263     ASSERT(vportPriv);
264     switch(vport->ovsType) {
265     case OVS_VPORT_TYPE_GRE:
266         break;
267     case OVS_VPORT_TYPE_STT:
268         dstPort = ((POVS_STT_VPORT)vportPriv)->dstPort;
269         break;
270     case OVS_VPORT_TYPE_VXLAN:
271         dstPort = ((POVS_VXLAN_VPORT)vportPriv)->dstPort;
272         break;
273     default:
274         ASSERT(! "Port is not a tunnel port");
275     }
276     ASSERT(dstPort || vport->ovsType == OVS_VPORT_TYPE_GRE);
277     return dstPort;
278 }
279
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);
285
286 POVS_VPORT_ENTRY OvsAllocateVport(VOID);
287
288 #endif /* __VPORT_H_ */