datapath-windows: Update vport add code.
[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
22 #define OVS_MAX_DPPORTS             MAXUINT16
23 #define OVS_DPPORT_NUMBER_INVALID   OVS_MAX_DPPORTS
24 /*
25  * The local port (0) is a reserved port, that is not allowed to be be
26  * created by the netlink command vport add. On linux, this port is created
27  * at netlink command datapath new. However, on windows, we do not need to
28  * create it, and more, we shouldn't. The userspace attempts to create two
29  * internal vports, the LOCAL port (0) and the internal port (with any other
30  * port number). The non-LOCAL internal port is used in the userspace when it
31  * requests the internal port.
32  */
33 #define OVS_DPPORT_NUMBER_LOCAL    0
34
35 #define OVS_DPPORT_INTERNAL_NAME_A  "internal"
36 #define OVS_DPPORT_INTERNAL_NAME_W  L"internal"
37 #define OVS_DPPORT_EXTERNAL_NAME_A   "external"
38 #define OVS_DPPORT_EXTERNAL_NAME_W  L"external"
39
40 /*
41  * A Vport, or Virtual Port, is a port on the OVS. It can be one of the
42  * following types. Some of the Vports are "real" ports on the hyper-v switch,
43  * and some are not:
44  * - VIF port (VM's NIC)
45  * - External Adapters (physical NIC)
46  * - Internal Adapter (Virtual adapter exposed on the host).
47  * - Tunnel ports created by OVS userspace.
48  */
49
50 typedef enum {
51     OVS_STATE_UNKNOWN,
52     OVS_STATE_PORT_CREATED,
53     OVS_STATE_NIC_CREATED,
54     OVS_STATE_CONNECTED,
55     OVS_STATE_PORT_TEAR_DOWN,
56     OVS_STATE_PORT_DELETED,
57 } OVS_VPORT_STATE;
58
59 typedef struct _OVS_VPORT_STATS {
60     UINT64 rxPackets;
61     UINT64 txPackets;
62     UINT64 rxBytes;
63     UINT64 txBytes;
64 } OVS_VPORT_STATS;
65
66 typedef struct _OVS_VPORT_ERR_STATS {
67     UINT64  rxErrors;
68     UINT64  txErrors;
69     UINT64  rxDropped;
70     UINT64  txDropped;
71 } OVS_VPORT_ERR_STATS;
72
73 /* used for vport netlink commands. */
74 typedef struct _OVS_VPORT_FULL_STATS {
75     OVS_VPORT_STATS;
76     OVS_VPORT_ERR_STATS;
77 }OVS_VPORT_FULL_STATS;
78 /*
79  * Each internal, external adapter or vritual adapter has
80  * one vport entry. In addition, we have one vport for each
81  * tunnel type, such as vxlan, gre, gre64
82  */
83 typedef struct _OVS_VPORT_ENTRY {
84     LIST_ENTRY             ovsNameLink;
85     LIST_ENTRY             portIdLink;
86     LIST_ENTRY             portNoLink;
87
88     OVS_VPORT_STATE        ovsState;
89     OVS_VPORT_TYPE         ovsType;
90     OVS_VPORT_STATS        stats;
91     OVS_VPORT_ERR_STATS    errStats;
92     UINT32                 portNo;
93     UINT32                 mtu;
94     /* ovsName is the ovs (datapath) port name - it is null terminated. */
95     CHAR                   ovsName[OVS_MAX_PORT_NAME_LENGTH];
96
97     PVOID                  priv;
98     NDIS_SWITCH_PORT_ID    portId;
99     NDIS_SWITCH_NIC_INDEX  nicIndex;
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[MAC_ADDRESS_LEN];
106     UINT8                  currMacAddress[MAC_ADDRESS_LEN];
107     UINT8                  vmMacAddress[MAC_ADDRESS_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                hvDeleted; /* is the hyper-v switch port deleted? */
133 } OVS_VPORT_ENTRY, *POVS_VPORT_ENTRY;
134
135 struct _OVS_SWITCH_CONTEXT;
136
137 POVS_VPORT_ENTRY
138 OvsFindVportByPortNo(struct _OVS_SWITCH_CONTEXT *switchContext,
139                      UINT32 portNo);
140
141 /* "name" is null-terminated */
142 POVS_VPORT_ENTRY
143 OvsFindVportByOvsName(POVS_SWITCH_CONTEXT switchContext,
144                       PSTR name);
145 POVS_VPORT_ENTRY
146 OvsFindVportByHvName(POVS_SWITCH_CONTEXT switchContext, PSTR name);
147 POVS_VPORT_ENTRY
148 OvsFindVportByPortIdAndNicIndex(struct _OVS_SWITCH_CONTEXT *switchContext,
149                                 NDIS_SWITCH_PORT_ID portId,
150                                 NDIS_SWITCH_NIC_INDEX index);
151
152 NDIS_STATUS OvsAddConfiguredSwitchPorts(struct _OVS_SWITCH_CONTEXT *switchContext);
153 NDIS_STATUS OvsInitConfiguredSwitchNics(struct _OVS_SWITCH_CONTEXT *switchContext);
154
155 VOID OvsClearAllSwitchVports(struct _OVS_SWITCH_CONTEXT *switchContext);
156
157 NDIS_STATUS HvCreateNic(POVS_SWITCH_CONTEXT switchContext,
158                         PNDIS_SWITCH_NIC_PARAMETERS nicParam);
159 NDIS_STATUS HvCreatePort(POVS_SWITCH_CONTEXT switchContext,
160                          PNDIS_SWITCH_PORT_PARAMETERS portParam);
161 VOID HvTeardownPort(POVS_SWITCH_CONTEXT switchContext,
162                     PNDIS_SWITCH_PORT_PARAMETERS portParam);
163 VOID HvDeletePort(POVS_SWITCH_CONTEXT switchContext,
164                   PNDIS_SWITCH_PORT_PARAMETERS portParam);
165 VOID HvConnectNic(POVS_SWITCH_CONTEXT switchContext,
166                   PNDIS_SWITCH_NIC_PARAMETERS nicParam);
167 VOID HvUpdateNic(POVS_SWITCH_CONTEXT switchContext,
168                  PNDIS_SWITCH_NIC_PARAMETERS nicParam);
169 VOID HvDeleteNic(POVS_SWITCH_CONTEXT switchContext,
170                  PNDIS_SWITCH_NIC_PARAMETERS nicParam);
171 VOID HvDisconnectNic(POVS_SWITCH_CONTEXT switchContext,
172                      PNDIS_SWITCH_NIC_PARAMETERS nicParam);
173
174 static __inline BOOLEAN
175 OvsIsTunnelVportType(OVS_VPORT_TYPE ovsType)
176 {
177     return ovsType == OVS_VPORT_TYPE_VXLAN ||
178            ovsType == OVS_VPORT_TYPE_GRE ||
179            ovsType == OVS_VPORT_TYPE_GRE64;
180 }
181
182 static __inline POVS_VPORT_ENTRY
183 OvsGetTunnelVport(POVS_SWITCH_CONTEXT switchContext,
184                   OVS_VPORT_TYPE ovsType)
185 {
186     switch(ovsType) {
187     case OVS_VPORT_TYPE_VXLAN:
188         return switchContext->vxlanVport;
189     default:
190         return NULL;
191     }
192 }
193
194 static __inline BOOLEAN
195 OvsIsInternalVportType(OVS_VPORT_TYPE ovsType)
196 {
197     return ovsType == OVS_VPORT_TYPE_INTERNAL;
198 }
199
200 static __inline BOOLEAN
201 OvsIsBridgeInternalVport(POVS_VPORT_ENTRY vport)
202 {
203     if (vport->isBridgeInternal) {
204        ASSERT(vport->ovsType == OVS_VPORT_TYPE_INTERNAL);
205     }
206     return vport->isBridgeInternal == TRUE;
207 }
208
209 VOID OvsRemoveAndDeleteVport(POVS_SWITCH_CONTEXT switchContext,
210                              POVS_VPORT_ENTRY vport);
211
212 NDIS_STATUS InitHvVportCommon(POVS_SWITCH_CONTEXT switchContext,
213                               POVS_VPORT_ENTRY vport);
214 NDIS_STATUS InitOvsVportCommon(POVS_SWITCH_CONTEXT switchContext,
215                                POVS_VPORT_ENTRY vport);
216 NTSTATUS OvsInitTunnelVport(POVS_VPORT_ENTRY vport, OVS_VPORT_TYPE ovsType,
217                             UINT16 dstport);
218 NTSTATUS OvsInitBridgeInternalVport(POVS_VPORT_ENTRY vport);
219
220 POVS_VPORT_ENTRY OvsAllocateVport(VOID);
221
222 #endif /* __VPORT_H_ */