]>
Commit | Line | Data |
---|---|---|
c803536e SS |
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 | ||
fa1324c9 SG |
17 | #ifndef __VPORT_H_ |
18 | #define __VPORT_H_ 1 | |
c803536e | 19 | |
fa1324c9 | 20 | #include "Switch.h" |
022c2040 EE |
21 | #include "VxLan.h" |
22 | #include "Stt.h" | |
c803536e | 23 | |
429d4556 AS |
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 | |
29a5b29f | 36 | |
7434992b NR |
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 | ||
c803536e SS |
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 { | |
c803536e | 62 | UINT64 rxPackets; |
c803536e | 63 | UINT64 txPackets; |
17c6a05f SG |
64 | UINT64 rxBytes; |
65 | UINT64 txBytes; | |
c803536e SS |
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; | |
17c6a05f SG |
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; | |
c803536e SS |
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 { | |
147c91db | 86 | LIST_ENTRY ovsNameLink; |
91c261cd | 87 | LIST_ENTRY portIdLink; |
429d4556 | 88 | LIST_ENTRY portNoLink; |
ffde5f8f | 89 | LIST_ENTRY tunnelVportLink; |
c803536e SS |
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; | |
8d9f1e0c | 97 | /* ovsName is the ovs (datapath) port name - it is null terminated. */ |
c803536e | 98 | CHAR ovsName[OVS_MAX_PORT_NAME_LENGTH]; |
c803536e SS |
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; | |
c803536e | 107 | |
b3123b20 NR |
108 | UINT8 permMacAddress[ETH_ADDR_LEN]; |
109 | UINT8 currMacAddress[ETH_ADDR_LEN]; | |
110 | UINT8 vmMacAddress[ETH_ADDR_LEN]; | |
c803536e | 111 | |
1b859c58 AS |
112 | NDIS_SWITCH_PORT_NAME hvPortName; |
113 | IF_COUNTED_STRING portFriendlyName; | |
c803536e SS |
114 | NDIS_SWITCH_NIC_NAME nicName; |
115 | NDIS_VM_NAME vmName; | |
116 | GUID netCfgInstanceId; | |
7434992b NR |
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; | |
e00afcf6 | 132 | BOOLEAN isExternal; |
17c6a05f | 133 | UINT32 upcallPid; /* netlink upcall port id */ |
8d9f1e0c | 134 | PNL_ATTR portOptions; |
66d9484f NR |
135 | BOOLEAN isPresentOnHv; /* Is this port present on the |
136 | Hyper-V switch? */ | |
c803536e SS |
137 | } OVS_VPORT_ENTRY, *POVS_VPORT_ENTRY; |
138 | ||
139 | struct _OVS_SWITCH_CONTEXT; | |
140 | ||
ffde5f8f SV |
141 | POVS_VPORT_ENTRY OvsFindVportByPortNo(POVS_SWITCH_CONTEXT switchContext, |
142 | UINT32 portNo); | |
8d9f1e0c | 143 | /* "name" is null-terminated */ |
70e56250 NR |
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); | |
ffde5f8f | 151 | POVS_VPORT_ENTRY OvsFindTunnelVportByDstPort(POVS_SWITCH_CONTEXT switchContext, |
022c2040 EE |
152 | UINT16 dstPort, |
153 | OVS_VPORT_TYPE ovsVportType); | |
c803536e SS |
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 | ||
fa048323 AS |
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); | |
b5af03d7 EE |
164 | NDIS_STATUS HvUpdatePort(POVS_SWITCH_CONTEXT switchContext, |
165 | PNDIS_SWITCH_PORT_PARAMETERS portParam); | |
fa048323 AS |
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, | |
c803536e | 171 | PNDIS_SWITCH_NIC_PARAMETERS nicParam); |
fa048323 AS |
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); | |
c803536e SS |
178 | |
179 | static __inline BOOLEAN | |
180 | OvsIsTunnelVportType(OVS_VPORT_TYPE ovsType) | |
181 | { | |
e00afcf6 | 182 | return ovsType == OVS_VPORT_TYPE_VXLAN || |
022c2040 | 183 | ovsType == OVS_VPORT_TYPE_STT || |
e00afcf6 SG |
184 | ovsType == OVS_VPORT_TYPE_GRE || |
185 | ovsType == OVS_VPORT_TYPE_GRE64; | |
c803536e SS |
186 | } |
187 | ||
022c2040 EE |
188 | |
189 | static __inline PVOID | |
190 | GetOvsVportPriv(POVS_VPORT_ENTRY ovsVport) | |
191 | { | |
192 | return ovsVport->priv; | |
193 | } | |
194 | ||
c803536e SS |
195 | static __inline BOOLEAN |
196 | OvsIsInternalVportType(OVS_VPORT_TYPE ovsType) | |
197 | { | |
e00afcf6 | 198 | return ovsType == OVS_VPORT_TYPE_INTERNAL; |
c803536e SS |
199 | } |
200 | ||
7434992b NR |
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 | ||
5e82ceef SV |
210 | NTSTATUS OvsRemoveAndDeleteVport(PVOID usrParamsCtx, |
211 | POVS_SWITCH_CONTEXT switchContext, | |
212 | POVS_VPORT_ENTRY vport, | |
213 | BOOLEAN hvDelete, BOOLEAN ovsDelete); | |
022c2040 EE |
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 | } | |
8d9f1e0c | 248 | |
f1613007 | 249 | NDIS_STATUS InitOvsVportCommon(POVS_SWITCH_CONTEXT switchContext, |
8d9f1e0c | 250 | POVS_VPORT_ENTRY vport); |
5e82ceef SV |
251 | NTSTATUS OvsInitTunnelVport(PVOID usrParamsCtx, POVS_VPORT_ENTRY vport, |
252 | OVS_VPORT_TYPE ovsType, UINT16 dstport); | |
b3b8a9c3 | 253 | NTSTATUS OvsInitBridgeInternalVport(POVS_VPORT_ENTRY vport); |
8d9f1e0c NR |
254 | |
255 | POVS_VPORT_ENTRY OvsAllocateVport(VOID); | |
256 | ||
fa1324c9 | 257 | #endif /* __VPORT_H_ */ |