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.
22 #define OVS_MAX_DPPORTS MAXUINT16
23 #define OVS_DPPORT_NUMBER_INVALID OVS_MAX_DPPORTS
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.
33 #define OVS_DPPORT_NUMBER_LOCAL 0
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"
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,
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.
52 OVS_STATE_PORT_CREATED,
53 OVS_STATE_NIC_CREATED,
55 OVS_STATE_PORT_TEAR_DOWN,
56 OVS_STATE_PORT_DELETED,
59 typedef struct _OVS_VPORT_STATS {
66 typedef struct _OVS_VPORT_ERR_STATS {
71 } OVS_VPORT_ERR_STATS;
73 /* used for vport netlink commands. */
74 typedef struct _OVS_VPORT_FULL_STATS {
77 }OVS_VPORT_FULL_STATS;
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
83 typedef struct _OVS_VPORT_ENTRY {
84 LIST_ENTRY ovsNameLink;
85 LIST_ENTRY portIdLink;
86 LIST_ENTRY portNoLink;
87 LIST_ENTRY tunnelVportLink;
89 OVS_VPORT_STATE ovsState;
90 OVS_VPORT_TYPE ovsType;
91 OVS_VPORT_STATS stats;
92 OVS_VPORT_ERR_STATS errStats;
95 /* ovsName is the ovs (datapath) port name - it is null terminated. */
96 CHAR ovsName[OVS_MAX_PORT_NAME_LENGTH];
99 NDIS_SWITCH_PORT_ID portId;
100 NDIS_SWITCH_NIC_INDEX nicIndex;
102 NDIS_SWITCH_PORT_STATE portState;
103 NDIS_SWITCH_NIC_STATE nicState;
104 NDIS_SWITCH_PORT_TYPE portType;
106 UINT8 permMacAddress[ETH_ADDR_LEN];
107 UINT8 currMacAddress[ETH_ADDR_LEN];
108 UINT8 vmMacAddress[ETH_ADDR_LEN];
110 NDIS_SWITCH_PORT_NAME hvPortName;
111 IF_COUNTED_STRING portFriendlyName;
112 NDIS_SWITCH_NIC_NAME nicName;
114 GUID netCfgInstanceId;
116 * OVS userpace has a notion of bridges which basically defines an
117 * L2-domain. Each "bridge" has an "internal" port of type
118 * OVS_VPORT_TYPE_INTERNAL. Such a port is connected to the OVS datapath in
119 * one end, and the other end is a virtual adapter on the hypervisor host.
120 * This is akin to the Hyper-V "internal" NIC. It is intuitive to map the
121 * Hyper-V "internal" NIC to the OVS bridge's "internal" port, but there's
122 * only one Hyper-V NIC but multiple bridges. To support multiple OVS bridge
123 * "internal" ports, we use the flag 'isBridgeInternal' in each vport. We
124 * support addition of multiple bridge-internal ports. A vport with
125 * 'isBridgeInternal' == TRUE is a dummy port and has no backing currently.
126 * If a flow actions specifies the output port to be a bridge-internal port,
127 * the port is silently ignored.
129 BOOLEAN isBridgeInternal;
131 UINT32 upcallPid; /* netlink upcall port id */
132 PNL_ATTR portOptions;
133 BOOLEAN isPresentOnHv; /* Is this port present on the
135 } OVS_VPORT_ENTRY, *POVS_VPORT_ENTRY;
137 struct _OVS_SWITCH_CONTEXT;
139 POVS_VPORT_ENTRY OvsFindVportByPortNo(POVS_SWITCH_CONTEXT switchContext,
141 /* "name" is null-terminated */
142 POVS_VPORT_ENTRY OvsFindVportByOvsName(POVS_SWITCH_CONTEXT switchContext,
144 POVS_VPORT_ENTRY OvsFindVportByHvNameA(POVS_SWITCH_CONTEXT switchContext,
146 POVS_VPORT_ENTRY OvsFindVportByPortIdAndNicIndex(POVS_SWITCH_CONTEXT switchContext,
147 NDIS_SWITCH_PORT_ID portId,
148 NDIS_SWITCH_NIC_INDEX index);
149 POVS_VPORT_ENTRY OvsFindTunnelVportByDstPort(POVS_SWITCH_CONTEXT switchContext,
152 NDIS_STATUS OvsAddConfiguredSwitchPorts(struct _OVS_SWITCH_CONTEXT *switchContext);
153 NDIS_STATUS OvsInitConfiguredSwitchNics(struct _OVS_SWITCH_CONTEXT *switchContext);
155 VOID OvsClearAllSwitchVports(struct _OVS_SWITCH_CONTEXT *switchContext);
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 NDIS_STATUS HvUpdatePort(POVS_SWITCH_CONTEXT switchContext,
162 PNDIS_SWITCH_PORT_PARAMETERS portParam);
163 VOID HvTeardownPort(POVS_SWITCH_CONTEXT switchContext,
164 PNDIS_SWITCH_PORT_PARAMETERS portParam);
165 VOID HvDeletePort(POVS_SWITCH_CONTEXT switchContext,
166 PNDIS_SWITCH_PORT_PARAMETERS portParam);
167 VOID HvConnectNic(POVS_SWITCH_CONTEXT switchContext,
168 PNDIS_SWITCH_NIC_PARAMETERS nicParam);
169 VOID HvUpdateNic(POVS_SWITCH_CONTEXT switchContext,
170 PNDIS_SWITCH_NIC_PARAMETERS nicParam);
171 VOID HvDeleteNic(POVS_SWITCH_CONTEXT switchContext,
172 PNDIS_SWITCH_NIC_PARAMETERS nicParam);
173 VOID HvDisconnectNic(POVS_SWITCH_CONTEXT switchContext,
174 PNDIS_SWITCH_NIC_PARAMETERS nicParam);
176 static __inline BOOLEAN
177 OvsIsTunnelVportType(OVS_VPORT_TYPE ovsType)
179 return ovsType == OVS_VPORT_TYPE_VXLAN ||
180 ovsType == OVS_VPORT_TYPE_GRE ||
181 ovsType == OVS_VPORT_TYPE_GRE64;
184 static __inline BOOLEAN
185 OvsIsInternalVportType(OVS_VPORT_TYPE ovsType)
187 return ovsType == OVS_VPORT_TYPE_INTERNAL;
190 static __inline BOOLEAN
191 OvsIsBridgeInternalVport(POVS_VPORT_ENTRY vport)
193 if (vport->isBridgeInternal) {
194 ASSERT(vport->ovsType == OVS_VPORT_TYPE_INTERNAL);
196 return vport->isBridgeInternal == TRUE;
199 NTSTATUS OvsRemoveAndDeleteVport(PVOID usrParamsCtx,
200 POVS_SWITCH_CONTEXT switchContext,
201 POVS_VPORT_ENTRY vport,
202 BOOLEAN hvDelete, BOOLEAN ovsDelete);
204 NDIS_STATUS InitOvsVportCommon(POVS_SWITCH_CONTEXT switchContext,
205 POVS_VPORT_ENTRY vport);
206 NTSTATUS OvsInitTunnelVport(PVOID usrParamsCtx, POVS_VPORT_ENTRY vport,
207 OVS_VPORT_TYPE ovsType, UINT16 dstport);
208 NTSTATUS OvsInitBridgeInternalVport(POVS_VPORT_ENTRY vport);
210 POVS_VPORT_ENTRY OvsAllocateVport(VOID);
212 #endif /* __VPORT_H_ */