*/
#include "precomp.h"
+
+#include "Datapath.h"
+#include "Event.h"
+#include "Gre.h"
+#include "IpHelper.h"
#include "Jhash.h"
+#include "Oid.h"
+#include "Stt.h"
#include "Switch.h"
-#include "Vport.h"
-#include "Event.h"
#include "User.h"
+#include "Vport.h"
#include "Vxlan.h"
-#include "Stt.h"
-#include "IpHelper.h"
-#include "Oid.h"
-#include "Datapath.h"
#ifdef OVS_DBG_MOD
#undef OVS_DBG_MOD
static VOID OvsTunnelVportPendingRemove(PVOID context,
NTSTATUS status,
UINT32 *replyLen);
-static VOID AssignNicNameSpecial(POVS_VPORT_ENTRY vport);
+static NTSTATUS GetNICAlias(GUID *netCfgInstanceId,
+ IF_COUNTED_STRING *portFriendlyName);
/*
* --------------------------------------------------------------------------
{
POVS_VPORT_ENTRY vport;
NDIS_STATUS status = NDIS_STATUS_SUCCESS;
-
+ IF_COUNTED_STRING portFriendlyName = {0};
LOCK_STATE_EX lockState;
VPORT_NIC_ENTER(nicParam);
goto done;
}
+ if (OvsIsInternalNIC(nicParam->NicType) ||
+ OvsIsRealExternalNIC(nicParam->NicType, nicParam->NicIndex)) {
+ GetNICAlias(&nicParam->NetCfgInstanceId, &portFriendlyName);
+ }
+
NdisAcquireRWLockWrite(switchContext->dispatchLock, &lockState, 0);
/*
* There can be one or more NICs for the external port. We create a vport
* structure for each such NIC, and each NIC inherits a lot of properties
* from the parent external port.
*/
- if (nicParam->NicType == NdisSwitchNicTypeExternal &&
- nicParam->NicIndex != 0) {
+ if (OvsIsRealExternalNIC(nicParam->NicType, nicParam->NicIndex)) {
+ NDIS_SWITCH_PORT_PARAMETERS portParam;
POVS_VPORT_ENTRY virtExtVport =
(POVS_VPORT_ENTRY)switchContext->virtualExternalVport;
- vport = OvsFindVportByPortIdAndNicIndex(switchContext,
- nicParam->PortId,
- nicParam->NicIndex);
- if (vport == NULL) {
- NDIS_SWITCH_PORT_PARAMETERS portParam;
- /* Find by interface name */
- WCHAR interfaceName[IF_MAX_STRING_SIZE] = { 0 };
- NET_LUID interfaceLuid = { 0 };
- size_t len = 0;
- status = ConvertInterfaceGuidToLuid(&nicParam->NetCfgInstanceId,
- &interfaceLuid);
- if (status == STATUS_SUCCESS) {
- status = ConvertInterfaceLuidToAlias(&interfaceLuid,
- interfaceName,
- IF_MAX_STRING_SIZE + 1);
- if (status == STATUS_SUCCESS) {
- RtlStringCbLengthW(interfaceName,
- IF_MAX_STRING_SIZE,
- &len);
- vport = OvsFindVportByHvNameW(switchContext,
- interfaceName,
- len);
- }
- }
-
- OvsCopyPortParamsFromVport(virtExtVport, &portParam);
- NdisReleaseRWLock(switchContext->dispatchLock, &lockState);
- status = HvCreatePort(switchContext, &portParam,
- nicParam->NicIndex);
- NdisAcquireRWLockWrite(switchContext->dispatchLock, &lockState, 0);
- if (status != NDIS_STATUS_SUCCESS) {
- goto add_nic_done;
- }
+ ASSERT(virtExtVport);
+ ASSERT(OvsFindVportByPortIdAndNicIndex(switchContext,
+ nicParam->PortId,
+ nicParam->NicIndex) == NULL);
+ OvsCopyPortParamsFromVport(virtExtVport, &portParam);
+ NdisReleaseRWLock(switchContext->dispatchLock, &lockState);
+ status = HvCreatePort(switchContext, &portParam,
+ nicParam->NicIndex);
+ NdisAcquireRWLockWrite(switchContext->dispatchLock, &lockState, 0);
+ if (status != NDIS_STATUS_SUCCESS) {
+ goto add_nic_done;
}
}
goto add_nic_done;
}
OvsInitVportWithNicParam(switchContext, vport, nicParam);
- if (nicParam->NicType == NdisSwitchNicTypeInternal ||
- (nicParam->NicType == NdisSwitchNicTypeExternal &&
- nicParam->NicIndex != 0)) {
- AssignNicNameSpecial(vport);
+ if (OvsIsInternalNIC(nicParam->NicType) ||
+ OvsIsRealExternalNIC(nicParam->NicType, nicParam->NicIndex)) {
+ RtlCopyMemory(&vport->portFriendlyName, &portFriendlyName,
+ sizeof portFriendlyName);
}
add_nic_done:
NdisReleaseRWLock(switchContext->dispatchLock, &lockState);
- if (status == STATUS_SUCCESS &&
- (vport->portType == NdisSwitchPortTypeInternal ||
- (vport->portType == NdisSwitchPortTypeExternal &&
- nicParam->NicIndex != 0))) {
- AssignNicNameSpecial(vport);
- }
done:
VPORT_NIC_EXIT(nicParam);
NdisReleaseRWLock(switchContext->dispatchLock, &lockState);
if (nicParam->NicType == NdisSwitchNicTypeInternal) {
- OvsInternalAdapterUp(portNo, &nicParam->NetCfgInstanceId);
+ OvsInternalAdapterUp(&nicParam->NetCfgInstanceId);
}
done:
POVS_VPORT_ENTRY vport;
LOCK_STATE_EX lockState;
UINT32 event = 0;
+ IF_COUNTED_STRING portFriendlyName = {0};
+ BOOLEAN nameChanged = FALSE;
+ BOOLEAN aliasLookup = FALSE;
VPORT_NIC_ENTER(nicParam);
goto update_nic_done;
}
+ /* GetNICAlias() must be called outside of a lock. */
+ if (nicParam->NicType == NdisSwitchNicTypeInternal ||
+ OvsIsRealExternalNIC(nicParam->NicType, nicParam->NicIndex)) {
+ GetNICAlias(&nicParam->NetCfgInstanceId, &portFriendlyName);
+ aliasLookup = TRUE;
+ }
+
NdisAcquireRWLockWrite(switchContext->dispatchLock, &lockState, 0);
vport = OvsFindVportByPortIdAndNicIndex(switchContext,
nicParam->PortId,
case NdisSwitchNicTypeInternal:
RtlCopyMemory(&vport->netCfgInstanceId, &nicParam->NetCfgInstanceId,
sizeof (GUID));
- AssignNicNameSpecial(vport);
+ if (aliasLookup) {
+ if (RtlCompareMemory(&vport->portFriendlyName,
+ &portFriendlyName, vport->portFriendlyName.Length) !=
+ vport->portFriendlyName.Length) {
+ RtlCopyMemory(&vport->portFriendlyName, &portFriendlyName,
+ sizeof portFriendlyName);
+ nameChanged = TRUE;
+ }
+ }
break;
case NdisSwitchNicTypeSynthetic:
case NdisSwitchNicTypeEmulated:
}
vport->numaNodeId = nicParam->NumaNodeId;
+ if (nameChanged) {
+ OVS_EVENT_ENTRY event;
+ event.portNo = vport->portNo;
+ event.ovsType = vport->ovsType;
+ event.upcallPid = vport->upcallPid;
+ RtlCopyMemory(&event.ovsName, &vport->ovsName, sizeof event.ovsName);
+ event.type = OVS_EVENT_LINK_DOWN;
+ OvsRemoveAndDeleteVport(NULL, switchContext, vport, FALSE, TRUE);
+ OvsPostEvent(&event);
+ }
+
NdisReleaseRWLock(switchContext->dispatchLock, &lockState);
/*
RtlCopyMemory(&event.ovsName, &vport->ovsName, sizeof event.ovsName);
event.type = OVS_EVENT_LINK_DOWN;
- NdisReleaseRWLock(switchContext->dispatchLock, &lockState);
-
/*
* Delete the port from the hash tables accessible to userspace. After this
* point, userspace should not be able to access this port.
*/
- OvsRemoveAndDeleteVport(NULL, switchContext, vport, FALSE, TRUE);
- OvsPostEvent(&event);
+ if (OvsIsRealExternalVport(vport)) {
+ OvsRemoveAndDeleteVport(NULL, switchContext, vport, FALSE, TRUE);
+ OvsPostEvent(&event);
+ }
+ NdisReleaseRWLock(switchContext->dispatchLock, &lockState);
if (isInternalPort) {
OvsInternalAdapterDown();
vport->nicState = NdisSwitchNicStateUnknown;
vport->ovsState = OVS_STATE_PORT_CREATED;
- if (vport->portType == NdisSwitchPortTypeExternal &&
- vport->nicIndex != 0) {
+ if (OvsIsRealExternalVport(vport)) {
+ /* This vport was created in HvCreateNic(). */
OvsRemoveAndDeleteVport(NULL, switchContext, vport, TRUE, FALSE);
}
return NULL;
}
+POVS_VPORT_ENTRY
+OvsFindTunnelVportByPortType(POVS_SWITCH_CONTEXT switchContext,
+ OVS_VPORT_TYPE ovsPortType)
+{
+ POVS_VPORT_ENTRY vport;
+ PLIST_ENTRY head, link;
+ UINT16 dstPort = 0;
+ UINT32 hash = OvsJhashBytes((const VOID *)&dstPort, sizeof(dstPort),
+ OVS_HASH_BASIS);
+ head = &(switchContext->tunnelVportsArray[hash & OVS_VPORT_MASK]);
+ LIST_FORALL(head, link) {
+ vport = CONTAINING_RECORD(link, OVS_VPORT_ENTRY, tunnelVportLink);
+ if (vport->ovsType == ovsPortType) {
+ return vport;
+ }
+ }
+ return NULL;
+}
POVS_VPORT_ENTRY
OvsFindVportByOvsName(POVS_SWITCH_CONTEXT switchContext,
vport->mtu = nicParam->MTU;
vport->nicState = nicParam->NicState;
vport->nicIndex = nicParam->NicIndex;
+ vport->nicType = nicParam->NicType;
vport->numaNodeId = nicParam->NumaNodeId;
switch (vport->nicState) {
vport->ovsState = OVS_STATE_PORT_CREATED;
switch (ovsType) {
case OVS_VPORT_TYPE_GRE:
+ status = OvsInitGreTunnel(vport);
break;
case OVS_VPORT_TYPE_VXLAN:
{
* Hyper-V, is overwritten with the interface alias name.
* --------------------------------------------------------------------------
*/
-static VOID
-AssignNicNameSpecial(POVS_VPORT_ENTRY vport)
+static NTSTATUS
+GetNICAlias(GUID *netCfgInstanceId,
+ IF_COUNTED_STRING *portFriendlyName)
{
NTSTATUS status = STATUS_SUCCESS;
WCHAR interfaceName[IF_MAX_STRING_SIZE] = { 0 };
NET_LUID interfaceLuid = { 0 };
size_t len = 0;
- ASSERT(vport->portType == NdisSwitchPortTypeExternal ||
- vport->portType == NdisSwitchPortTypeInternal);
-
- status = ConvertInterfaceGuidToLuid(&vport->netCfgInstanceId,
+ status = ConvertInterfaceGuidToLuid(netCfgInstanceId,
&interfaceLuid);
if (status == STATUS_SUCCESS) {
/*
status = ConvertInterfaceLuidToAlias(&interfaceLuid, interfaceName,
IF_MAX_STRING_SIZE + 1);
if (status == STATUS_SUCCESS) {
- if (vport->portType == NdisSwitchPortTypeExternal &&
- vport->nicIndex == 0) {
- RtlStringCbPrintfW(vport->portFriendlyName.String, IF_MAX_STRING_SIZE,
- L"%s.virtualAdapter", interfaceName);
- } else {
- RtlStringCbPrintfW(vport->portFriendlyName.String,
- IF_MAX_STRING_SIZE, L"%s", interfaceName);
- }
-
- RtlStringCbLengthW(vport->portFriendlyName.String, IF_MAX_STRING_SIZE,
+ RtlStringCbPrintfW(portFriendlyName->String,
+ IF_MAX_STRING_SIZE, L"%s", interfaceName);
+ RtlStringCbLengthW(portFriendlyName->String, IF_MAX_STRING_SIZE,
&len);
- vport->portFriendlyName.Length = (USHORT)len;
+ portFriendlyName->Length = (USHORT)len;
} else {
- OVS_LOG_INFO("Fail to convert interface LUID to alias, status: %x",
+ OVS_LOG_ERROR("Fail to convert interface LUID to alias, status: %x",
status);
}
} else {
- OVS_LOG_INFO("Fail to convert interface GUID to LUID, status: %x",
+ OVS_LOG_ERROR("Fail to convert interface GUID to LUID, status: %x",
status);
}
+
+ return status;
}
UINT32 hash;
switch(vport->ovsType) {
+ case OVS_VPORT_TYPE_GRE:
case OVS_VPORT_TYPE_VXLAN:
case OVS_VPORT_TYPE_STT:
{
OvsCleanupSttTunnel(vport);
break;
case OVS_VPORT_TYPE_GRE:
+ OvsCleanupGreTunnel(vport);
break;
case OVS_VPORT_TYPE_NETDEV:
if (vport->isExternal) {
RemoveEntryList(&vport->portNoLink);
InitializeListHead(&vport->portNoLink);
if (OVS_VPORT_TYPE_VXLAN == vport->ovsType ||
- OVS_VPORT_TYPE_STT == vport->ovsType) {
+ OVS_VPORT_TYPE_STT == vport->ovsType ||
+ OVS_VPORT_TYPE_GRE == vport->ovsType) {
RemoveEntryList(&vport->tunnelVportLink);
InitializeListHead(&vport->tunnelVportLink);
}
UINT16 transportPortDest = 0;
switch (portType) {
+ case OVS_VPORT_TYPE_GRE:
+ break;
case OVS_VPORT_TYPE_VXLAN:
transportPortDest = VXLAN_UDP_PORT;
break;