4c6e858b133342e6a6c7998ad31b2994a263d411
[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 "Switch.h"
21 #include "VxLan.h"
22 #include "Stt.h"
23
24 #define OVS_MAX_DPPORTS             MAXUINT16
25 #define OVS_DPPORT_NUMBER_INVALID   OVS_MAX_DPPORTS
26 /*
27  * The local port (0) is a reserved port, that is not allowed to be be
28  * created by the netlink command vport add. On linux, this port is created
29  * at netlink command datapath new. However, on windows, we do not need to
30  * create it, and more, we shouldn't. The userspace attempts to create two
31  * internal vports, the LOCAL port (0) and the internal port (with any other
32  * port number). The non-LOCAL internal port is used in the userspace when it
33  * requests the internal port.
34  */
35 #define OVS_DPPORT_NUMBER_LOCAL    0
36
37 #define OVS_DPPORT_INTERNAL_NAME_A  "internal"
38 #define OVS_DPPORT_INTERNAL_NAME_W  L"internal"
39 #define OVS_DPPORT_EXTERNAL_NAME_A   "external"
40 #define OVS_DPPORT_EXTERNAL_NAME_W  L"external"
41
42 /*
43  * A Vport, or Virtual Port, is a port on the OVS. It can be one of the
44  * following types. Some of the Vports are "real" ports on the hyper-v switch,
45  * and some are not:
46  * - VIF port (VM's NIC)
47  * - External Adapters (physical NIC)
48  * - Internal Adapter (Virtual adapter exposed on the host).
49  * - Tunnel ports created by OVS userspace.
50  */
51
52 typedef enum {
53     OVS_STATE_UNKNOWN,
54     OVS_STATE_PORT_CREATED,
55     OVS_STATE_NIC_CREATED,
56     OVS_STATE_CONNECTED,
57     OVS_STATE_PORT_TEAR_DOWN,
58     OVS_STATE_PORT_DELETED,
59 } OVS_VPORT_STATE;
60
61 typedef struct _OVS_VPORT_STATS {
62     UINT64 rxPackets;
63     UINT64 txPackets;
64     UINT64 rxBytes;
65     UINT64 txBytes;
66 } OVS_VPORT_STATS;
67
68 typedef struct _OVS_VPORT_ERR_STATS {
69     UINT64  rxErrors;
70     UINT64  txErrors;
71     UINT64  rxDropped;
72     UINT64  txDropped;
73 } OVS_VPORT_ERR_STATS;
74
75 /* used for vport netlink commands. */
76 typedef struct _OVS_VPORT_FULL_STATS {
77     OVS_VPORT_STATS;
78     OVS_VPORT_ERR_STATS;
79 }OVS_VPORT_FULL_STATS;
80 /*
81  * Each internal, external adapter or vritual adapter has
82  * one vport entry. In addition, we have one vport for each
83  * tunnel type, such as vxlan, gre, gre64
84  */
85 typedef struct _OVS_VPORT_ENTRY {
86     LIST_ENTRY             ovsNameLink;
87     LIST_ENTRY             portIdLink;
88     LIST_ENTRY             portNoLink;
89     LIST_ENTRY             tunnelVportLink;
90
91     OVS_VPORT_STATE        ovsState;
92     OVS_VPORT_TYPE         ovsType;
93     OVS_VPORT_STATS        stats;
94     OVS_VPORT_ERR_STATS    errStats;
95     UINT32                 portNo;
96     UINT32                 mtu;
97     /* ovsName is the ovs (datapath) port name - it is null terminated. */
98     CHAR                   ovsName[OVS_MAX_PORT_NAME_LENGTH];
99
100     PVOID                  priv;
101     NDIS_SWITCH_PORT_ID    portId;
102     NDIS_SWITCH_NIC_INDEX  nicIndex;
103     UINT16                 numaNodeId;
104     NDIS_SWITCH_PORT_STATE portState;
105     NDIS_SWITCH_NIC_STATE  nicState;
106     NDIS_SWITCH_PORT_TYPE  portType;
107
108     UINT8                  permMacAddress[ETH_ADDR_LEN];
109     UINT8                  currMacAddress[ETH_ADDR_LEN];
110     UINT8                  vmMacAddress[ETH_ADDR_LEN];
111
112     NDIS_SWITCH_PORT_NAME  hvPortName;
113     IF_COUNTED_STRING      portFriendlyName;
114     NDIS_SWITCH_NIC_NAME   nicName;
115     NDIS_VM_NAME           vmName;
116     GUID                   netCfgInstanceId;
117     /*
118      * OVS userpace has a notion of bridges which basically defines an
119      * L2-domain. Each "bridge" has an "internal" port of type
120      * OVS_VPORT_TYPE_INTERNAL. Such a port is connected to the OVS datapath in
121      * one end, and the other end is a virtual adapter on the hypervisor host.
122      * This is akin to the Hyper-V "internal" NIC. It is intuitive to map the
123      * Hyper-V "internal" NIC to the OVS bridge's "internal" port, but there's
124      * only one Hyper-V NIC but multiple bridges. To support multiple OVS bridge
125      * "internal" ports, we use the flag 'isBridgeInternal' in each vport. We
126      * support addition of multiple bridge-internal ports. A vport with
127      * 'isBridgeInternal' == TRUE is a dummy port and has no backing currently.
128      * If a flow actions specifies the output port to be a bridge-internal port,
129      * the port is silently ignored.
130      */
131     BOOLEAN                isBridgeInternal;
132     BOOLEAN                isExternal;
133     UINT32                 upcallPid; /* netlink upcall port id */
134     PNL_ATTR               portOptions;
135     BOOLEAN                isAbsentOnHv; /* Is this port present on the
136                                              Hyper-V switch? */
137 } OVS_VPORT_ENTRY, *POVS_VPORT_ENTRY;
138
139 struct _OVS_SWITCH_CONTEXT;
140
141 POVS_VPORT_ENTRY OvsFindVportByPortNo(POVS_SWITCH_CONTEXT switchContext,
142                                       UINT32 portNo);
143 /* "name" is null-terminated */
144 POVS_VPORT_ENTRY OvsFindVportByOvsName(POVS_SWITCH_CONTEXT switchContext,
145                                        PSTR name);
146 POVS_VPORT_ENTRY OvsFindVportByHvNameA(POVS_SWITCH_CONTEXT switchContext,
147                                        PSTR name);
148 POVS_VPORT_ENTRY OvsFindVportByPortIdAndNicIndex(POVS_SWITCH_CONTEXT switchContext,
149                                                  NDIS_SWITCH_PORT_ID portId,
150                                                  NDIS_SWITCH_NIC_INDEX index);
151 POVS_VPORT_ENTRY OvsFindTunnelVportByDstPort(POVS_SWITCH_CONTEXT switchContext,
152                                              UINT16 dstPort,
153                                              OVS_VPORT_TYPE ovsVportType);
154
155 NDIS_STATUS OvsAddConfiguredSwitchPorts(struct _OVS_SWITCH_CONTEXT *switchContext);
156 NDIS_STATUS OvsInitConfiguredSwitchNics(struct _OVS_SWITCH_CONTEXT *switchContext);
157
158 VOID OvsClearAllSwitchVports(struct _OVS_SWITCH_CONTEXT *switchContext);
159
160 NDIS_STATUS HvCreateNic(POVS_SWITCH_CONTEXT switchContext,
161                         PNDIS_SWITCH_NIC_PARAMETERS nicParam);
162 NDIS_STATUS HvCreatePort(POVS_SWITCH_CONTEXT switchContext,
163                          PNDIS_SWITCH_PORT_PARAMETERS portParam);
164 NDIS_STATUS HvUpdatePort(POVS_SWITCH_CONTEXT switchContext,
165                          PNDIS_SWITCH_PORT_PARAMETERS portParam);
166 VOID HvTeardownPort(POVS_SWITCH_CONTEXT switchContext,
167                     PNDIS_SWITCH_PORT_PARAMETERS portParam);
168 VOID HvDeletePort(POVS_SWITCH_CONTEXT switchContext,
169                   PNDIS_SWITCH_PORT_PARAMETERS portParam);
170 VOID HvConnectNic(POVS_SWITCH_CONTEXT switchContext,
171                   PNDIS_SWITCH_NIC_PARAMETERS nicParam);
172 VOID HvUpdateNic(POVS_SWITCH_CONTEXT switchContext,
173                  PNDIS_SWITCH_NIC_PARAMETERS nicParam);
174 VOID HvDeleteNic(POVS_SWITCH_CONTEXT switchContext,
175                  PNDIS_SWITCH_NIC_PARAMETERS nicParam);
176 VOID HvDisconnectNic(POVS_SWITCH_CONTEXT switchContext,
177                      PNDIS_SWITCH_NIC_PARAMETERS nicParam);
178
179 static __inline BOOLEAN
180 OvsIsTunnelVportType(OVS_VPORT_TYPE ovsType)
181 {
182     return ovsType == OVS_VPORT_TYPE_VXLAN ||
183            ovsType == OVS_VPORT_TYPE_STT ||
184            ovsType == OVS_VPORT_TYPE_GRE ||
185            ovsType == OVS_VPORT_TYPE_GRE64;
186 }
187
188
189 static __inline PVOID
190 GetOvsVportPriv(POVS_VPORT_ENTRY ovsVport)
191 {
192     return ovsVport->priv;
193 }
194
195 static __inline BOOLEAN
196 OvsIsInternalVportType(OVS_VPORT_TYPE ovsType)
197 {
198     return ovsType == OVS_VPORT_TYPE_INTERNAL;
199 }
200
201 static __inline BOOLEAN
202 OvsIsBridgeInternalVport(POVS_VPORT_ENTRY vport)
203 {
204     if (vport->isBridgeInternal) {
205        ASSERT(vport->ovsType == OVS_VPORT_TYPE_INTERNAL);
206     }
207     return vport->isBridgeInternal == TRUE;
208 }
209
210 NTSTATUS OvsRemoveAndDeleteVport(PVOID usrParamsCtx,
211                                  POVS_SWITCH_CONTEXT switchContext,
212                                  POVS_VPORT_ENTRY vport,
213                                  BOOLEAN hvDelete, BOOLEAN ovsDelete);
214 static __inline POVS_VPORT_ENTRY
215 OvsGetExternalVport(POVS_SWITCH_CONTEXT switchContext)
216 {
217     return switchContext->virtualExternalVport;
218 }
219
220 static __inline UINT32
221 OvsGetExternalMtu(POVS_SWITCH_CONTEXT switchContext)
222 {
223     ASSERT(OvsGetExternalVport(switchContext));
224     return ((POVS_VPORT_ENTRY) OvsGetExternalVport(switchContext))->mtu;
225 }
226
227 static __inline UINT16
228 GetPortFromPriv(POVS_VPORT_ENTRY vport)
229 {
230     UINT16 dstPort = 0;
231     PVOID vportPriv = GetOvsVportPriv(vport);
232
233     /* XXX would better to have a commom tunnel "parent" structure */
234     ASSERT(vportPriv);
235     switch(vport->ovsType) {
236     case OVS_VPORT_TYPE_VXLAN:
237         dstPort = ((POVS_VXLAN_VPORT)vportPriv)->dstPort;
238         break;
239     case OVS_VPORT_TYPE_STT:
240         dstPort = ((POVS_STT_VPORT)vportPriv)->dstPort;
241         break;
242     default:
243         ASSERT(! "Port is not a tunnel port");
244     }
245     ASSERT(dstPort);
246     return dstPort;
247 }
248
249 NDIS_STATUS InitOvsVportCommon(POVS_SWITCH_CONTEXT switchContext,
250                                POVS_VPORT_ENTRY vport);
251 NTSTATUS OvsInitTunnelVport(PVOID usrParamsCtx, POVS_VPORT_ENTRY vport,
252                             OVS_VPORT_TYPE ovsType, UINT16 dstport);
253 NTSTATUS OvsInitBridgeInternalVport(POVS_VPORT_ENTRY vport);
254
255 POVS_VPORT_ENTRY OvsAllocateVport(VOID);
256
257 #endif /* __VPORT_H_ */