@@ -26,28 +26,45 @@
#include "Debug.h"
/*
- * Fow now, we assume only one internal adapter
+ * IpHelper supports multiple internal adapters.
*/
KSTART_ROUTINE OvsStartIpHelper;
+/* Contains the entries of internal adapter objects. */
+static LIST_ENTRY ovsInstanceList;
+
+/* Passive-level lock used to protect the internal adapter object list. */
+static ERESOURCE ovsInstanceListLock;
+
/*
+ * This structure is used to define each adapter instance.
+ *
+ * Note:
* Only when the internal IP is configured and virtual
* internal port is connected, the IP helper request can be
* queued.
+ *
+ * We only keep internal IP for reference, it will not be used for determining
+ * SRC IP of the Tunnel.
+ *
+ * The lock must not raise the IRQL higher than PASSIVE_LEVEL in order for the
+ * route manipulation functions, i.e. GetBestRoute, to work.
*/
-static BOOLEAN ovsInternalIPConfigured;
-static UINT32 ovsInternalPortNo;
-static GUID ovsInternalNetCfgId;
-static MIB_IF_ROW2 ovsInternalRow;
-static MIB_IPINTERFACE_ROW ovsInternalIPRow;
-
-/* we only keep one internal IP for reference, it will not be used for
- * determining SRC IP of Tunnel
- */
-static UINT32 ovsInternalIP;
+typedef struct _OVS_IPHELPER_INSTANCE
+{
+ LIST_ENTRY link;
+
+ BOOLEAN isIpConfigured;
+ UINT32 portNo;
+ GUID netCfgId;
+ MIB_IF_ROW2 internalRow;
+ MIB_IPINTERFACE_ROW internalIPRow;
+ UINT32 ipAddress;
+ ERESOURCE lock;
+} OVS_IPHELPER_INSTANCE, *POVS_IPHELPER_INSTANCE;
/*
* FWD_ENTRY --------> IPFORWARD_ENTRY
@@ -85,6 +102,9 @@ static VOID OvsRemoveAllFwdEntriesWithSrc(UINT32 ipAddr);
static VOID OvsCleanupIpHelperRequestList(VOID);
static VOID OvsCleanupFwdTable(VOID);
static VOID OvsAddToSortedNeighList(POVS_IPNEIGH_ENTRY ipn);
+static POVS_IPHELPER_INSTANCE OvsIpHelperAllocateInstance(
+ POVS_IP_HELPER_REQUEST request);
+static VOID OvsIpHelperDeleteInstance(POVS_IPHELPER_INSTANCE instance);
static VOID
OvsDumpIfRow(PMIB_IF_ROW2 ifRow)
@@ -325,30 +345,53 @@ OvsDumpRoute(const SOCKADDR_INET *sourceAddress,
NTSTATUS
-OvsGetRoute(NET_LUID interfaceLuid,
- const SOCKADDR_INET *destinationAddress,
+OvsGetRoute(SOCKADDR_INET *destinationAddress,
PMIB_IPFORWARD_ROW2 route,
- SOCKADDR_INET *sourceAddress)
+ SOCKADDR_INET *sourceAddress,
+ POVS_IPHELPER_INSTANCE *instance)
{
- NTSTATUS status;
+ NTSTATUS status = STATUS_NETWORK_UNREACHABLE;
+ NTSTATUS result = STATUS_SUCCESS;
+ PLIST_ENTRY head, link, next;
if (destinationAddress == NULL || route == NULL) {
return STATUS_INVALID_PARAMETER;
}
- status = GetBestRoute2(&interfaceLuid, 0,
- NULL, destinationAddress,
- 0, route, sourceAddress);
+ ExAcquireResourceSharedLite(&ovsInstanceListLock, TRUE);
+ head = &(ovsInstanceList);
+ LIST_FORALL_SAFE(head, link, next) {
+ ULONG minMetric = (ULONG)-1;
+ SOCKADDR_INET crtSrcAddr = { 0 };
+ MIB_IPFORWARD_ROW2 crtRoute = { 0 };
+ POVS_IPHELPER_INSTANCE crtInstance = NULL;
- if (status != STATUS_SUCCESS) {
- UINT32 ipAddr = destinationAddress->Ipv4.sin_addr.s_addr;
- OVS_LOG_INFO("Fail to get route to %d.%d.%d.%d, status: %x",
- ipAddr & 0xff, (ipAddr >> 8) & 0xff,
- (ipAddr >> 16) & 0xff, (ipAddr >> 24) & 0xff, status);
- return status;
+ crtInstance = CONTAINING_RECORD(link, OVS_IPHELPER_INSTANCE, link);
+
+ ExAcquireResourceSharedLite(&crtInstance->lock, TRUE);
+ result = GetBestRoute2(&crtInstance->internalRow.InterfaceLuid, 0,
+ NULL, destinationAddress, 0, &crtRoute,
+ &crtSrcAddr);
+ if (result != STATUS_SUCCESS) {
+ ExReleaseResourceLite(&crtInstance->lock);
+ continue;
+ }
+
+ if (minMetric > crtRoute.Metric) {
+ minMetric = crtRoute.Metric;
+
+ RtlCopyMemory(sourceAddress, &crtSrcAddr, sizeof(*sourceAddress));
+ RtlCopyMemory(route, &crtRoute, sizeof(*route));
+ *instance = crtInstance;
+
+ status = STATUS_SUCCESS;
+ }
+ ExReleaseResourceLite(&crtInstance->lock);
}
+ ExReleaseResourceLite(&ovsInstanceListLock);
OvsDumpRoute(sourceAddress, destinationAddress, route);
+
return status;
}
@@ -358,8 +401,8 @@ OvsDumpIPNeigh(PMIB_IPNET_ROW2 ipNeigh)
UINT32 ipAddr = ipNeigh->Address.Ipv4.sin_addr.s_addr;
OVS_LOG_INFO("Neigh: %d.%d.%d.%d",
- ipAddr & 0xff, (ipAddr >> 8) & 0xff,
- (ipAddr >> 16) & 0xff, (ipAddr >> 24) & 0xff);
+ ipAddr & 0xff, (ipAddr >> 8) & 0xff,
+ (ipAddr >> 16) & 0xff, (ipAddr >> 24) & 0xff);
OVS_LOG_INFO("MAC Address: %02x:%02x:%02x:%02x:%02x:%02x",
ipNeigh->PhysicalAddress[0],
ipNeigh->PhysicalAddress[1],
@@ -421,7 +464,8 @@ OvsResolveIPNeighEntry(PMIB_IPNET_ROW2 ipNeigh)
NTSTATUS
-OvsGetOrResolveIPNeigh(UINT32 ipAddr,
+OvsGetOrResolveIPNeigh(MIB_IF_ROW2 ipRow,
+ UINT32 ipAddr,
PMIB_IPNET_ROW2 ipNeigh)
{
NTSTATUS status;
@@ -429,8 +473,8 @@ OvsGetOrResolveIPNeigh(UINT32 ipAddr,
ASSERT(ipNeigh);
RtlZeroMemory(ipNeigh, sizeof (*ipNeigh));
- ipNeigh->InterfaceLuid.Value = ovsInternalRow.InterfaceLuid.Value;
- ipNeigh->InterfaceIndex = ovsInternalRow.InterfaceIndex;
+ ipNeigh->InterfaceLuid.Value = ipRow.InterfaceLuid.Value;
+ ipNeigh->InterfaceIndex = ipRow.InterfaceIndex;
ipNeigh->Address.si_family = AF_INET;
ipNeigh->Address.Ipv4.sin_addr.s_addr = ipAddr;
@@ -438,8 +482,8 @@ OvsGetOrResolveIPNeigh(UINT32 ipAddr,
if (status != STATUS_SUCCESS) {
RtlZeroMemory(ipNeigh, sizeof (*ipNeigh));
- ipNeigh->InterfaceLuid.Value = ovsInternalRow.InterfaceLuid.Value;
- ipNeigh->InterfaceIndex = ovsInternalRow.InterfaceIndex;
+ ipNeigh->InterfaceLuid.Value = ipRow.InterfaceLuid.Value;
+ ipNeigh->InterfaceIndex = ipRow.InterfaceIndex;
ipNeigh->Address.si_family = AF_INET;
ipNeigh->Address.Ipv4.sin_addr.s_addr = ipAddr;
status = OvsResolveIPNeighEntry(ipNeigh);
@@ -457,47 +501,91 @@ OvsChangeCallbackIpInterface(PVOID context,
switch (notificationType) {
case MibParameterNotification:
case MibAddInstance:
- if (ipRow->InterfaceLuid.Info.NetLuidIndex ==
- ovsInternalRow.InterfaceLuid.Info.NetLuidIndex &&
- ipRow->InterfaceLuid.Info.IfType ==
- ovsInternalRow.InterfaceLuid.Info.IfType &&
- ipRow->InterfaceIndex == ovsInternalRow.InterfaceIndex) {
- /*
- * Update the IP Interface Row
- */
- NdisAcquireSpinLock(&ovsIpHelperLock);
- RtlCopyMemory(&ovsInternalIPRow, ipRow,
- sizeof (PMIB_IPINTERFACE_ROW));
- ovsInternalIPConfigured = TRUE;
- NdisReleaseSpinLock(&ovsIpHelperLock);
+ {
+ PLIST_ENTRY head, link, next;
+
+ ExAcquireResourceSharedLite(&ovsInstanceListLock, TRUE);
+ head = &(ovsInstanceList);
+ LIST_FORALL_SAFE(head, link, next) {
+ POVS_IPHELPER_INSTANCE instance = NULL;
+
+ instance = CONTAINING_RECORD(link, OVS_IPHELPER_INSTANCE, link);
+
+ ExAcquireResourceExclusiveLite(&instance->lock, TRUE);
+ if (instance->internalRow.InterfaceLuid.Info.NetLuidIndex ==
+ ipRow->InterfaceLuid.Info.NetLuidIndex &&
+ instance->internalRow.InterfaceLuid.Info.IfType ==
+ ipRow->InterfaceLuid.Info.IfType &&
+ instance->internalRow.InterfaceIndex ==
+ ipRow->InterfaceIndex) {
+
+ /*
+ * Update the IP Interface Row
+ */
+ RtlCopyMemory(&instance->internalIPRow, ipRow,
+ sizeof(PMIB_IPINTERFACE_ROW));
+ instance->isIpConfigured = TRUE;
+
+ OVS_LOG_INFO("IP Interface with NetLuidIndex: %d, type: %d is %s",
+ ipRow->InterfaceLuid.Info.NetLuidIndex,
+ ipRow->InterfaceLuid.Info.IfType,
+ notificationType == MibAddInstance ?
+ "added" : "modified");
+
+ ExReleaseResourceLite(&instance->lock);
+ break;
+ }
+ ExReleaseResourceLite(&instance->lock);
}
- OVS_LOG_INFO("IP Interface with NetLuidIndex: %d, type: %d is %s",
- ipRow->InterfaceLuid.Info.NetLuidIndex,
- ipRow->InterfaceLuid.Info.IfType,
- notificationType == MibAddInstance ? "added" : "modified");
+ ExReleaseResourceLite(&ovsInstanceListLock);
+
break;
+ }
+
case MibDeleteInstance:
- OVS_LOG_INFO("IP Interface with NetLuidIndex: %d, type: %d, deleted",
- ipRow->InterfaceLuid.Info.NetLuidIndex,
- ipRow->InterfaceLuid.Info.IfType);
- if (ipRow->InterfaceLuid.Info.NetLuidIndex ==
- ovsInternalRow.InterfaceLuid.Info.NetLuidIndex &&
- ipRow->InterfaceLuid.Info.IfType ==
- ovsInternalRow.InterfaceLuid.Info.IfType &&
- ipRow->InterfaceIndex == ovsInternalRow.InterfaceIndex) {
+ {
+ PLIST_ENTRY head, link, next;
- NdisAcquireSpinLock(&ovsIpHelperLock);
- ovsInternalIPConfigured = FALSE;
- NdisReleaseSpinLock(&ovsIpHelperLock);
+ ExAcquireResourceExclusiveLite(&ovsInstanceListLock, TRUE);
+ head = &(ovsInstanceList);
+ LIST_FORALL_SAFE(head, link, next) {
+ POVS_IPHELPER_INSTANCE instance = NULL;
- OvsCleanupIpHelperRequestList();
+ instance = CONTAINING_RECORD(link, OVS_IPHELPER_INSTANCE, link);
+
+ ExAcquireResourceExclusiveLite(&instance->lock, TRUE);
+ if (instance->internalRow.InterfaceLuid.Info.NetLuidIndex ==
+ ipRow->InterfaceLuid.Info.NetLuidIndex &&
+ instance->internalRow.InterfaceLuid.Info.IfType ==
+ ipRow->InterfaceLuid.Info.IfType &&
+ instance->internalRow.InterfaceIndex ==
+ ipRow->InterfaceIndex) {
+
+ instance->isIpConfigured = FALSE;
+ ExReleaseResourceLite(&instance->lock);
+
+ RemoveEntryList(&instance->link);
+ OvsIpHelperDeleteInstance(instance);
+
+ OVS_LOG_INFO("IP Interface with NetLuidIndex: %d, type: %d is deleted",
+ ipRow->InterfaceLuid.Info.NetLuidIndex,
+ ipRow->InterfaceLuid.Info.IfType);
+ break;
+ }
+ ExReleaseResourceLite(&instance->lock);
+ }
+ ExReleaseResourceLite(&ovsInstanceListLock);
+
+ if (IsListEmpty(&ovsInstanceList)) {
+ OvsCleanupIpHelperRequestList();
OvsCleanupFwdTable();
}
break;
+ }
case MibInitialNotification:
- OVS_LOG_INFO("Get Initial notification for IP Interface change.");
+ OVS_LOG_INFO("Got Initial notification for IP Interface change.");
default:
return;
}
@@ -529,25 +617,40 @@ OvsChangeCallbackIpRoute(PVOID context,
case MibParameterNotification:
case MibDeleteInstance:
+ {
+ PLIST_ENTRY head, link, next;
+ BOOLEAN found = FALSE;
+
ASSERT(ipRoute);
ipAddr = ipRoute->DestinationPrefix.Prefix.Ipv4.sin_addr.s_addr;
nextHop = ipRoute->NextHop.Ipv4.sin_addr.s_addr;
- OVS_LOG_INFO("IPRoute: To %d.%d.%d.%d/%d through %d.%d.%d.%d %s.",
- ipAddr & 0xff, (ipAddr >> 8) & 0xff,
- (ipAddr >> 16) & 0xff, (ipAddr >> 24) & 0xff,
- ipRoute->DestinationPrefix.PrefixLength,
- nextHop & 0xff, (nextHop >> 8) & 0xff,
- (nextHop >> 16) & 0xff, (nextHop >> 24) & 0xff,
- notificationType == MibDeleteInstance ? "deleted" :
- "modified");
+ ExAcquireResourceSharedLite(&ovsInstanceListLock, TRUE);
+ head = &(ovsInstanceList);
+ LIST_FORALL_SAFE(head, link, next) {
+ POVS_IPHELPER_INSTANCE instance = NULL;
- if (ipRoute->InterfaceLuid.Info.NetLuidIndex ==
- ovsInternalRow.InterfaceLuid.Info.NetLuidIndex &&
- ipRoute->InterfaceLuid.Info.IfType ==
- ovsInternalRow.InterfaceLuid.Info.IfType &&
- ipRoute->InterfaceIndex == ovsInternalRow.InterfaceIndex) {
+ instance = CONTAINING_RECORD(link, OVS_IPHELPER_INSTANCE, link);
+
+ ExAcquireResourceSharedLite(&instance->lock, TRUE);
+ if (instance->isIpConfigured &&
+ instance->internalRow.InterfaceLuid.Info.NetLuidIndex ==
+ ipRoute->InterfaceLuid.Info.NetLuidIndex &&
+ instance->internalRow.InterfaceLuid.Info.IfType ==
+ ipRoute->InterfaceLuid.Info.IfType &&
+ instance->internalRow.InterfaceIndex ==
+ ipRoute->InterfaceIndex) {
+
+ found = TRUE;
+
+ ExReleaseResourceLite(&instance->lock);
+ break;
+ }
+ ExReleaseResourceLite(&instance->lock);
+ }
+ ExReleaseResourceLite(&ovsInstanceListLock);
+ if (found) {
POVS_IPFORWARD_ENTRY ipf;
LOCK_STATE_EX lockState;
@@ -557,8 +660,18 @@ OvsChangeCallbackIpRoute(PVOID context,
OvsRemoveIPForwardEntry(ipf);
}
NdisReleaseRWLock(ovsTableLock, &lockState);
+
+ OVS_LOG_INFO("IPRoute: To %d.%d.%d.%d/%d through %d.%d.%d.%d %s.",
+ ipAddr & 0xff, (ipAddr >> 8) & 0xff,
+ (ipAddr >> 16) & 0xff, (ipAddr >> 24) & 0xff,
+ ipRoute->DestinationPrefix.PrefixLength,
+ nextHop & 0xff, (nextHop >> 8) & 0xff,
+ (nextHop >> 16) & 0xff, (nextHop >> 24) & 0xff,
+ notificationType == MibDeleteInstance ? "deleted" :
+ "modified");
}
break;
+ }
case MibInitialNotification:
OVS_LOG_INFO("Get Initial notification for IP Route change.");
@@ -579,40 +692,91 @@ OvsChangeCallbackUnicastIpAddress(PVOID context,
switch (notificationType) {
case MibParameterNotification:
case MibAddInstance:
+ {
+ PLIST_ENTRY head, link, next;
+
ASSERT(unicastRow);
ipAddr = unicastRow->Address.Ipv4.sin_addr.s_addr;
- if (unicastRow->InterfaceLuid.Info.NetLuidIndex ==
- ovsInternalRow.InterfaceLuid.Info.NetLuidIndex &&
- unicastRow->InterfaceLuid.Info.IfType ==
- ovsInternalRow.InterfaceLuid.Info.IfType &&
- unicastRow->InterfaceIndex == ovsInternalRow.InterfaceIndex) {
- ovsInternalIP = ipAddr;
+
+ ExAcquireResourceSharedLite(&ovsInstanceListLock, TRUE);
+ head = &(ovsInstanceList);
+ LIST_FORALL_SAFE(head, link, next) {
+ POVS_IPHELPER_INSTANCE instance = NULL;
+
+ instance = CONTAINING_RECORD(link, OVS_IPHELPER_INSTANCE, link);
+
+ ExAcquireResourceExclusiveLite(&instance->lock, TRUE);
+ if (instance->isIpConfigured &&
+ instance->internalRow.InterfaceLuid.Info.NetLuidIndex ==
+ unicastRow->InterfaceLuid.Info.NetLuidIndex &&
+ instance->internalRow.InterfaceLuid.Info.IfType ==
+ unicastRow->InterfaceLuid.Info.IfType &&
+ instance->internalRow.InterfaceIndex ==
+ unicastRow->InterfaceIndex) {
+
+ instance->ipAddress = ipAddr;
+
+ OVS_LOG_INFO("IP Address: %d.%d.%d.%d is %s",
+ ipAddr & 0xff, (ipAddr >> 8) & 0xff,
+ (ipAddr >> 16) & 0xff, (ipAddr >> 24) & 0xff,
+ notificationType == MibAddInstance ? "added": "modified");
+
+ ExReleaseResourceLite(&instance->lock);
+ break;
+ }
+ ExReleaseResourceLite(&instance->lock);
}
- OVS_LOG_INFO("IP Address: %d.%d.%d.%d is %s",
- ipAddr & 0xff, (ipAddr >> 8) & 0xff,
- (ipAddr >> 16) & 0xff, (ipAddr >> 24) & 0xff,
- notificationType == MibAddInstance ? "added": "modified");
+ ExReleaseResourceLite(&ovsInstanceListLock);
+
break;
+ }
case MibDeleteInstance:
+ {
+ PLIST_ENTRY head, link, next;
+ LOCK_STATE_EX lockState;
+ BOOLEAN found = FALSE;
+
ASSERT(unicastRow);
ipAddr = unicastRow->Address.Ipv4.sin_addr.s_addr;
- OVS_LOG_INFO("IP Address removed: %d.%d.%d.%d",
- ipAddr & 0xff, (ipAddr >> 8) & 0xff,
- (ipAddr >> 16) & 0xff, (ipAddr >> 24) & 0xff);
- if (unicastRow->InterfaceLuid.Info.NetLuidIndex ==
- ovsInternalRow.InterfaceLuid.Info.NetLuidIndex &&
- unicastRow->InterfaceLuid.Info.IfType ==
- ovsInternalRow.InterfaceLuid.Info.IfType &&
- unicastRow->InterfaceIndex == ovsInternalRow.InterfaceIndex) {
- LOCK_STATE_EX lockState;
+ ExAcquireResourceSharedLite(&ovsInstanceListLock, TRUE);
+ head = &(ovsInstanceList);
+ LIST_FORALL_SAFE(head, link, next) {
+ POVS_IPHELPER_INSTANCE instance = NULL;
+
+ instance = CONTAINING_RECORD(link, OVS_IPHELPER_INSTANCE, link);
+
+ ExAcquireResourceSharedLite(&instance->lock, TRUE);
+ if (instance->isIpConfigured &&
+ instance->internalRow.InterfaceLuid.Info.NetLuidIndex ==
+ unicastRow->InterfaceLuid.Info.NetLuidIndex &&
+ instance->internalRow.InterfaceLuid.Info.IfType ==
+ unicastRow->InterfaceLuid.Info.IfType &&
+ instance->internalRow.InterfaceIndex ==
+ unicastRow->InterfaceIndex) {
+
+ found = TRUE;
+
+ ExReleaseResourceLite(&instance->lock);
+ break;
+ }
+ ExReleaseResourceLite(&instance->lock);
+ }
+ ExReleaseResourceLite(&ovsInstanceListLock);
+
+ if (found) {
NdisAcquireRWLockWrite(ovsTableLock, &lockState, 0);
OvsRemoveAllFwdEntriesWithSrc(ipAddr);
NdisReleaseRWLock(ovsTableLock, &lockState);
+ OVS_LOG_INFO("IP Address removed: %d.%d.%d.%d",
+ ipAddr & 0xff, (ipAddr >> 8) & 0xff,
+ (ipAddr >> 16) & 0xff, (ipAddr >> 24) & 0xff);
}
+
break;
+ }
case MibInitialNotification:
OVS_LOG_INFO("Get Initial notification for Unicast IP Address change.");
@@ -651,7 +815,7 @@ OvsRegisterChangeNotification()
&ipInterfaceNotificationHandle);
if (status != STATUS_SUCCESS) {
OVS_LOG_ERROR("Fail to register Notify IP interface change, status:%x.",
- status);
+ status);
return status;
}
@@ -659,7 +823,7 @@ OvsRegisterChangeNotification()
TRUE, &ipRouteNotificationHandle);
if (status != STATUS_SUCCESS) {
OVS_LOG_ERROR("Fail to regiter ip route change, status: %x.",
- status);
+ status);
goto register_cleanup;
}
status = NotifyUnicastIpAddressChange(AF_INET,
@@ -682,10 +846,11 @@ static POVS_IPNEIGH_ENTRY
OvsLookupIPNeighEntry(UINT32 ipAddr)
{
PLIST_ENTRY link;
- POVS_IPNEIGH_ENTRY entry;
UINT32 hash = OvsJhashWords(&ipAddr, 1, OVS_HASH_BASIS);
LIST_FORALL(&ovsNeighHashTable[hash & OVS_NEIGH_HASH_TABLE_MASK], link) {
+ POVS_IPNEIGH_ENTRY entry;
+
entry = CONTAINING_RECORD(link, OVS_IPNEIGH_ENTRY, link);
if (entry->ipAddr == ipAddr) {
return entry;
@@ -709,7 +874,6 @@ OvsLookupIPForwardEntry(PIP_ADDRESS_PREFIX prefix)
{
PLIST_ENTRY link;
- POVS_IPFORWARD_ENTRY ipfEntry;
UINT32 hash;
ASSERT(prefix->Prefix.si_family == AF_INET);
@@ -720,6 +884,8 @@ OvsLookupIPForwardEntry(PIP_ADDRESS_PREFIX prefix)
hash = OvsHashIPPrefix(prefix);
LIST_FORALL(&ovsRouteHashTable[hash & OVS_ROUTE_HASH_TABLE_MASK], link) {
+ POVS_IPFORWARD_ENTRY ipfEntry;
+
ipfEntry = CONTAINING_RECORD(link, OVS_IPFORWARD_ENTRY, link);
if (ipfEntry->prefix.PrefixLength == prefix->PrefixLength &&
ipfEntry->prefix.Prefix.Ipv4.sin_addr.s_addr ==
@@ -735,10 +901,11 @@ static POVS_FWD_ENTRY
OvsLookupIPFwdEntry(UINT32 dstIp)
{
PLIST_ENTRY link;
- POVS_FWD_ENTRY entry;
UINT32 hash = OvsJhashWords(&dstIp, 1, OVS_HASH_BASIS);
LIST_FORALL(&ovsFwdHashTable[hash & OVS_FWD_HASH_TABLE_MASK], link) {
+ POVS_FWD_ENTRY entry;
+
entry = CONTAINING_RECORD(link, OVS_FWD_ENTRY, link);
if (entry->info.dstIpAddr == dstIp) {
return entry;
@@ -770,7 +937,8 @@ OvsLookupIPFwdInfo(UINT32 dstIp,
static POVS_IPNEIGH_ENTRY
-OvsCreateIPNeighEntry(PMIB_IPNET_ROW2 ipNeigh)
+OvsCreateIPNeighEntry(PMIB_IPNET_ROW2 ipNeigh,
+ POVS_IPHELPER_INSTANCE instance)
{
POVS_IPNEIGH_ENTRY entry;
@@ -790,6 +958,7 @@ OvsCreateIPNeighEntry(PMIB_IPNET_ROW2 ipNeigh)
RtlCopyMemory(entry->macAddr, ipNeigh->PhysicalAddress,
ETH_ADDR_LEN);
InitializeListHead(&entry->fwdList);
+ entry->context = (PVOID)instance;
return entry;
}
@@ -798,7 +967,6 @@ OvsCreateIPNeighEntry(PMIB_IPNET_ROW2 ipNeigh)
static POVS_IPFORWARD_ENTRY
OvsCreateIPForwardEntry(PMIB_IPFORWARD_ROW2 ipRoute)
{
-
POVS_IPFORWARD_ENTRY entry;
ASSERT(ipRoute);
@@ -876,12 +1044,13 @@ OvsRemoveFwdEntry(POVS_FWD_ENTRY fwdEntry)
static VOID
OvsRemoveIPForwardEntry(POVS_IPFORWARD_ENTRY ipf)
{
- POVS_FWD_ENTRY fwdEntry;
PLIST_ENTRY link, next;
ipf->refCount++;
LIST_FORALL_SAFE(&ipf->fwdList, link, next) {
+ POVS_FWD_ENTRY fwdEntry;
+
fwdEntry = CONTAINING_RECORD(link, OVS_FWD_ENTRY, ipfLink);
OvsRemoveFwdEntry(fwdEntry);
}
@@ -896,11 +1065,12 @@ static VOID
OvsRemoveIPNeighEntry(POVS_IPNEIGH_ENTRY ipn)
{
PLIST_ENTRY link, next;
- POVS_FWD_ENTRY fwdEntry;
ipn->refCount++;
LIST_FORALL_SAFE(&ipn->fwdList, link, next) {
+ POVS_FWD_ENTRY fwdEntry;
+
fwdEntry = CONTAINING_RECORD(link, OVS_FWD_ENTRY, ipnLink);
OvsRemoveFwdEntry(fwdEntry);
}
@@ -973,11 +1143,12 @@ static VOID
OvsRemoveAllFwdEntriesWithSrc(UINT32 ipAddr)
{
UINT32 i;
- POVS_FWD_ENTRY fwdEntry;
PLIST_ENTRY link, next;
for (i = 0; i < OVS_FWD_HASH_TABLE_SIZE; i++) {
LIST_FORALL_SAFE(&ovsFwdHashTable[i], link, next) {
+ POVS_FWD_ENTRY fwdEntry;
+
fwdEntry = CONTAINING_RECORD(link, OVS_FWD_ENTRY, link);
if (fwdEntry->info.srcIpAddr == ipAddr) {
OvsRemoveFwdEntry(fwdEntry);
@@ -991,13 +1162,14 @@ static VOID
OvsCleanupFwdTable(VOID)
{
PLIST_ENTRY link, next;
- POVS_IPNEIGH_ENTRY ipn;
UINT32 i;
LOCK_STATE_EX lockState;
NdisAcquireRWLockWrite(ovsTableLock, &lockState, 0);
if (ovsNumFwdEntries) {
LIST_FORALL_SAFE(&ovsSortedIPNeighList, link, next) {
+ POVS_IPNEIGH_ENTRY ipn;
+
ipn = CONTAINING_RECORD(link, OVS_IPNEIGH_ENTRY, slink);
OvsRemoveIPNeighEntry(ipn);
}
@@ -1017,7 +1189,6 @@ OvsCleanupIpHelperRequestList(VOID)
{
LIST_ENTRY list;
PLIST_ENTRY next, link;
- POVS_IP_HELPER_REQUEST request;
NdisAcquireSpinLock(&ovsIpHelperLock);
if (ovsNumIpHelperRequests == 0) {
@@ -1031,6 +1202,8 @@ OvsCleanupIpHelperRequestList(VOID)
NdisReleaseSpinLock(&ovsIpHelperLock);
LIST_FORALL_SAFE(&list, link, next) {
+ POVS_IP_HELPER_REQUEST request;
+
request = CONTAINING_RECORD(link, OVS_IP_HELPER_REQUEST, link);
if (request->command == OVS_IP_HELPER_FWD_REQUEST &&
@@ -1056,16 +1229,38 @@ OvsWakeupIPHelper(VOID)
}
VOID
-OvsInternalAdapterDown(VOID)
+OvsInternalAdapterDown(UINT32 portNo,
+ GUID netCfgInstanceId)
{
- NdisAcquireSpinLock(&ovsIpHelperLock);
- ovsInternalPortNo = OVS_DEFAULT_PORT_NO;
- ovsInternalIPConfigured = FALSE;
- NdisReleaseSpinLock(&ovsIpHelperLock);
+ PLIST_ENTRY head, link, next;
- OvsCleanupIpHelperRequestList();
+ ExAcquireResourceExclusiveLite(&ovsInstanceListLock, TRUE);
+ head = &ovsInstanceList;
+ LIST_FORALL_SAFE(head, link, next) {
+ POVS_IPHELPER_INSTANCE instance = NULL;
- OvsCleanupFwdTable();
+ instance = CONTAINING_RECORD(link, OVS_IPHELPER_INSTANCE, link);
+
+ ExAcquireResourceExclusiveLite(&instance->lock, TRUE);
+ if (instance->portNo == portNo &&
+ IsEqualGUID(&instance->netCfgId, &netCfgInstanceId)) {
+
+ RemoveEntryList(&instance->link);
+
+ ExReleaseResourceLite(&instance->lock);
+
+ OvsIpHelperDeleteInstance(instance);
+ break;
+ }
+ ExReleaseResourceLite(&instance->lock);
+ }
+ ExReleaseResourceLite(&ovsInstanceListLock);
+
+ if (IsListEmpty(&ovsInstanceList)) {
+ OvsCleanupIpHelperRequestList();
+
+ OvsCleanupFwdTable();
+ }
}
@@ -1075,9 +1270,6 @@ OvsInternalAdapterUp(UINT32 portNo,
{
POVS_IP_HELPER_REQUEST request;
- RtlCopyMemory(&ovsInternalNetCfgId, netCfgInstanceId, sizeof (GUID));
- RtlZeroMemory(&ovsInternalRow, sizeof (MIB_IF_ROW2));
-
request = (POVS_IP_HELPER_REQUEST)OvsAllocateMemoryWithTag(
sizeof(OVS_IP_HELPER_REQUEST), OVS_IPHELPER_POOL_TAG);
if (request == NULL) {
@@ -1085,10 +1277,13 @@ OvsInternalAdapterUp(UINT32 portNo,
return;
}
RtlZeroMemory(request, sizeof (OVS_IP_HELPER_REQUEST));
+ RtlCopyMemory(&request->instanceReq.netCfgInstanceId,
+ netCfgInstanceId,
+ sizeof(*netCfgInstanceId));
request->command = OVS_IP_HELPER_INTERNAL_ADAPTER_UP;
+ request->instanceReq.portNo = portNo;
NdisAcquireSpinLock(&ovsIpHelperLock);
- ovsInternalPortNo = portNo;
InsertHeadList(&ovsIpHelperRequestList, &request->link);
ovsNumIpHelperRequests++;
if (ovsNumIpHelperRequests == 1) {
@@ -1098,58 +1293,134 @@ OvsInternalAdapterUp(UINT32 portNo,
}
+static POVS_IPHELPER_INSTANCE
+OvsIpHelperAllocateInstance(POVS_IP_HELPER_REQUEST request)
+{
+ POVS_IPHELPER_INSTANCE instance = NULL;
+
+ instance = (POVS_IPHELPER_INSTANCE)OvsAllocateMemoryWithTag(
+ sizeof(*instance), OVS_IPHELPER_POOL_TAG);
+ if (instance) {
+ RtlZeroMemory(instance, sizeof(*instance));
+
+ RtlCopyMemory(&instance->netCfgId,
+ &request->instanceReq.netCfgInstanceId,
+ sizeof(instance->netCfgId));
+ instance->portNo = request->instanceReq.portNo;
+
+ InitializeListHead(&instance->link);
+ ExInitializeResourceLite(&instance->lock);
+ }
+
+ return instance;
+}
+
+
+static VOID
+OvsIpHelperDeleteInstance(POVS_IPHELPER_INSTANCE instance)
+{
+ if (instance) {
+ ExDeleteResourceLite(&instance->lock);
+ OvsFreeMemoryWithTag(instance, OVS_IPHELPER_POOL_TAG);
+ }
+}
+
+
+static VOID
+OvsIpHelperDeleteAllInstances()
+{
+ PLIST_ENTRY head, link, next;
+
+ ExAcquireResourceExclusiveLite(&ovsInstanceListLock, TRUE);
+ head = &ovsInstanceList;
+ if (!IsListEmpty(head)) {
+ LIST_FORALL_SAFE(head, link, next) {
+ POVS_IPHELPER_INSTANCE instance = NULL;
+ instance = CONTAINING_RECORD(link, OVS_IPHELPER_INSTANCE, link);
+
+ ExAcquireResourceExclusiveLite(&instance->lock, TRUE);
+ instance->isIpConfigured = FALSE;
+ ExReleaseResourceLite(&instance->lock);
+
+ RemoveEntryList(&instance->link);
+
+ OvsIpHelperDeleteInstance(instance);
+ instance = NULL;
+ }
+ }
+ ExReleaseResourceLite(&ovsInstanceListLock);
+}
+
+
static VOID
OvsHandleInternalAdapterUp(POVS_IP_HELPER_REQUEST request)
{
NTSTATUS status;
+ POVS_IPHELPER_INSTANCE instance = NULL;
MIB_UNICASTIPADDRESS_ROW ipEntry;
- GUID *netCfgInstanceId = &ovsInternalNetCfgId;
+ BOOLEAN error = TRUE;
- OvsFreeMemoryWithTag(request, OVS_IPHELPER_POOL_TAG);
+ do {
+ instance = OvsIpHelperAllocateInstance(request);
+ if (instance == NULL) {
+ break;
+ }
- status = OvsGetIfEntry(&ovsInternalNetCfgId, &ovsInternalRow);
+ status = OvsGetIfEntry(&instance->netCfgId,
+ &instance->internalRow);
- if (status != STATUS_SUCCESS) {
- OVS_LOG_ERROR("Fali to get IF entry for internal port with GUID"
- " %08x-%04x-%04x-%04x-%02x%02x%02x%02x%02x%02x",
- netCfgInstanceId->Data1,
- netCfgInstanceId->Data2,
- netCfgInstanceId->Data3,
- *(UINT16 *)netCfgInstanceId->Data4,
- netCfgInstanceId->Data4[2],
- netCfgInstanceId->Data4[3],
- netCfgInstanceId->Data4[4],
- netCfgInstanceId->Data4[5],
- netCfgInstanceId->Data4[6],
- netCfgInstanceId->Data4[7]);
- return;
- }
+ if (status != STATUS_SUCCESS) {
+ OVS_LOG_ERROR("Fail to get IF entry for internal port with GUID"
+ " %08x-%04x-%04x-%04x-%02x%02x%02x%02x%02x%02x",
+ instance->netCfgId.Data1,
+ instance->netCfgId.Data2,
+ instance->netCfgId.Data3,
+ *(UINT16 *)instance->netCfgId.Data4,
+ instance->netCfgId.Data4[2],
+ instance->netCfgId.Data4[3],
+ instance->netCfgId.Data4[4],
+ instance->netCfgId.Data4[5],
+ instance->netCfgId.Data4[6],
+ instance->netCfgId.Data4[7]);
+ break;
+ }
- status = OvsGetIPInterfaceEntry(ovsInternalRow.InterfaceLuid,
- &ovsInternalIPRow);
+ status = OvsGetIPInterfaceEntry(instance->internalRow.InterfaceLuid,
+ &instance->internalIPRow);
- if (status == STATUS_SUCCESS) {
- NdisAcquireSpinLock(&ovsIpHelperLock);
- ovsInternalIPConfigured = TRUE;
- NdisReleaseSpinLock(&ovsIpHelperLock);
- } else {
- return;
- }
+ if (status == STATUS_SUCCESS) {
+ instance->isIpConfigured = TRUE;
+ } else {
+ break;
+ }
- status = OvsGetIPEntry(ovsInternalRow.InterfaceLuid, &ipEntry);
- if (status != STATUS_SUCCESS) {
- OVS_LOG_INFO("Fali to get IP entry for internal port with GUID"
- " %08x-%04x-%04x-%04x-%02x%02x%02x%02x%02x%02x",
- netCfgInstanceId->Data1,
- netCfgInstanceId->Data2,
- netCfgInstanceId->Data3,
- *(UINT16 *)netCfgInstanceId->Data4,
- netCfgInstanceId->Data4[2],
- netCfgInstanceId->Data4[3],
- netCfgInstanceId->Data4[4],
- netCfgInstanceId->Data4[5],
- netCfgInstanceId->Data4[6],
- netCfgInstanceId->Data4[7]);
+ status = OvsGetIPEntry(instance->internalRow.InterfaceLuid, &ipEntry);
+ if (status != STATUS_SUCCESS) {
+ OVS_LOG_INFO("Fail to get IP entry for internal port with GUID"
+ " %08x-%04x-%04x-%04x-%02x%02x%02x%02x%02x%02x",
+ instance->netCfgId.Data1,
+ instance->netCfgId.Data2,
+ instance->netCfgId.Data3,
+ *(UINT16 *)instance->netCfgId.Data4,
+ instance->netCfgId.Data4[2],
+ instance->netCfgId.Data4[3],
+ instance->netCfgId.Data4[4],
+ instance->netCfgId.Data4[5],
+ instance->netCfgId.Data4[6],
+ instance->netCfgId.Data4[7]);
+ break;
+ }
+
+ ExAcquireResourceExclusiveLite(&ovsInstanceListLock, TRUE);
+ InsertHeadList(&ovsInstanceList, &instance->link);
+ ExReleaseResourceLite(&ovsInstanceListLock);
+
+ error = FALSE;
+ } while (error);
+
+ OvsFreeMemoryWithTag(request, OVS_IPHELPER_POOL_TAG);
+ if (error) {
+ OvsIpHelperDeleteInstance(instance);
}
}
@@ -1157,15 +1428,11 @@ OvsHandleInternalAdapterUp(POVS_IP_HELPER_REQUEST request)
static NTSTATUS
OvsEnqueueIpHelperRequest(POVS_IP_HELPER_REQUEST request)
{
-
- NdisAcquireSpinLock(&ovsIpHelperLock);
-
- if (ovsInternalPortNo == OVS_DEFAULT_PORT_NO ||
- ovsInternalIPConfigured == FALSE) {
- NdisReleaseSpinLock(&ovsIpHelperLock);
+ if (IsListEmpty(&ovsInstanceList)) {
OvsFreeMemoryWithTag(request, OVS_IPHELPER_POOL_TAG);
return STATUS_NDIS_ADAPTER_NOT_READY;
} else {
+ NdisAcquireSpinLock(&ovsIpHelperLock);
InsertHeadList(&ovsIpHelperRequestList, &request->link);
ovsNumIpHelperRequests++;
if (ovsNumIpHelperRequests == 1) {
@@ -1223,6 +1490,7 @@ OvsHandleFwdRequest(POVS_IP_HELPER_REQUEST request)
BOOLEAN newIPF = FALSE;
BOOLEAN newIPN = FALSE;
BOOLEAN newFWD = FALSE;
+ POVS_IPHELPER_INSTANCE instance = NULL;
status = OvsLookupIPFwdInfo(request->fwdReq.tunnelKey.dst,
&fwdInfo);
@@ -1237,10 +1505,16 @@ OvsHandleFwdRequest(POVS_IP_HELPER_REQUEST request)
dst.si_family = AF_INET;
dst.Ipv4.sin_addr.s_addr = request->fwdReq.tunnelKey.dst;
- status = OvsGetRoute(ovsInternalRow.InterfaceLuid, &dst, &ipRoute, &src);
+ status = OvsGetRoute(&dst, &ipRoute, &src, &instance);
if (status != STATUS_SUCCESS) {
+ UINT32 ipAddr = dst.Ipv4.sin_addr.s_addr;
+ OVS_LOG_INFO("Fail to get route to %d.%d.%d.%d, status: %x",
+ ipAddr & 0xff, (ipAddr >> 8) & 0xff,
+ (ipAddr >> 16) & 0xff, (ipAddr >> 24) & 0xff, status);
goto fwd_handle_nbl;
}
+
+ ExAcquireResourceSharedLite(&instance->lock, TRUE);
srcAddr = src.Ipv4.sin_addr.s_addr;
/* find IPNeigh */
@@ -1253,13 +1527,16 @@ OvsHandleFwdRequest(POVS_IP_HELPER_REQUEST request)
}
NdisReleaseRWLock(ovsTableLock, &lockState);
}
+
RtlZeroMemory(&ipNeigh, sizeof (ipNeigh));
- ipNeigh.InterfaceLuid.Value = ovsInternalRow.InterfaceLuid.Value;
+ ipNeigh.InterfaceLuid.Value = instance->internalRow.InterfaceLuid.Value;
if (ipAddr == 0) {
ipAddr = request->fwdReq.tunnelKey.dst;
}
- status = OvsGetOrResolveIPNeigh(ipAddr, &ipNeigh);
+ status = OvsGetOrResolveIPNeigh(instance->internalRow,
+ ipAddr, &ipNeigh);
if (status != STATUS_SUCCESS) {
+ ExReleaseResourceLite(&instance->lock);
goto fwd_handle_nbl;
}
@@ -1275,6 +1552,7 @@ fwd_request_done:
ipf = OvsCreateIPForwardEntry(&ipRoute);
if (ipf == NULL) {
NdisReleaseRWLock(ovsTableLock, &lockState);
+ ExReleaseResourceLite(&instance->lock);
status = STATUS_INSUFFICIENT_RESOURCES;
goto fwd_handle_nbl;
}
@@ -1292,9 +1570,10 @@ fwd_request_done:
if (ipn == NULL) {
ipn = OvsLookupIPNeighEntry(ipAddr);
if (ipn == NULL) {
- ipn = OvsCreateIPNeighEntry(&ipNeigh);
+ ipn = OvsCreateIPNeighEntry(&ipNeigh, instance);
if (ipn == NULL) {
NdisReleaseRWLock(ovsTableLock, &lockState);
+ ExReleaseResourceLite(&instance->lock);
status = STATUS_INSUFFICIENT_RESOURCES;
goto fwd_handle_nbl;
}
@@ -1308,13 +1587,14 @@ fwd_request_done:
fwdInfo.dstIpAddr = request->fwdReq.tunnelKey.dst;
fwdInfo.srcIpAddr = srcAddr;
RtlCopyMemory(fwdInfo.dstMacAddr, ipn->macAddr, ETH_ADDR_LEN);
- RtlCopyMemory(fwdInfo.srcMacAddr, ovsInternalRow.PhysicalAddress,
+ RtlCopyMemory(fwdInfo.srcMacAddr, instance->internalRow.PhysicalAddress,
ETH_ADDR_LEN);
fwdInfo.srcPortNo = request->fwdReq.inPort;
fwdEntry = OvsCreateFwdEntry(&fwdInfo);
if (fwdEntry == NULL) {
NdisReleaseRWLock(ovsTableLock, &lockState);
+ ExReleaseResourceLite(&instance->lock);
status = STATUS_INSUFFICIENT_RESOURCES;
goto fwd_handle_nbl;
}
@@ -1324,6 +1604,7 @@ fwd_request_done:
*/
OvsAddIPFwdCache(fwdEntry, ipf, ipn);
NdisReleaseRWLock(ovsTableLock, &lockState);
+ ExReleaseResourceLite(&instance->lock);
fwd_handle_nbl:
@@ -1426,12 +1707,17 @@ OvsUpdateIPNeighEntry(UINT32 ipAddr,
static VOID
-OvsHandleIPNeighTimeout(UINT32 ipAddr)
+OvsHandleIPNeighTimeout(UINT32 ipAddr,
+ PVOID context)
{
MIB_IPNET_ROW2 ipNeigh;
NTSTATUS status;
+ POVS_IPHELPER_INSTANCE instance = (POVS_IPHELPER_INSTANCE)context;
- status = OvsGetOrResolveIPNeigh(ipAddr, &ipNeigh);
+ ExAcquireResourceSharedLite(&instance->lock, TRUE);
+ status = OvsGetOrResolveIPNeigh(instance->internalRow,
+ ipAddr, &ipNeigh);
+ ExReleaseResourceLite(&instance->lock);
OvsUpdateIPNeighEntry(ipAddr, &ipNeigh, status);
}
@@ -1439,13 +1725,13 @@ OvsHandleIPNeighTimeout(UINT32 ipAddr)
/*
*----------------------------------------------------------------------------
- * IP Helper system threash handle following request
+ * IP Helper system thread handles the following requests:
* 1. Intialize Internal port row when internal port is connected
* 2. Handle FWD request
* 3. Handle IP Neigh timeout
*
* IP Interface, unicast address, and IP route change will be handled
- * by the revelant callback.
+ * by the revelant callbacks.
*----------------------------------------------------------------------------
*/
VOID
@@ -1455,7 +1741,7 @@ OvsStartIpHelper(PVOID data)
POVS_IP_HELPER_REQUEST req;
POVS_IPNEIGH_ENTRY ipn;
PLIST_ENTRY link;
- UINT64 timeVal, timeout;
+ UINT64 timeVal, timeout;
OVS_LOG_INFO("Start the IP Helper Thread, context: %p", context);
@@ -1504,7 +1790,7 @@ OvsStartIpHelper(PVOID data)
NdisReleaseSpinLock(&ovsIpHelperLock);
- OvsHandleIPNeighTimeout(ipAddr);
+ OvsHandleIPNeighTimeout(ipAddr, ipn->context);
NdisAcquireSpinLock(&ovsIpHelperLock);
}
@@ -1550,12 +1836,6 @@ OvsInitIpHelper(NDIS_HANDLE ndisFilterHandle)
ovsNeighHashTable = (PLIST_ENTRY)OvsAllocateMemoryWithTag(
sizeof(LIST_ENTRY) * OVS_NEIGH_HASH_TABLE_SIZE, OVS_IPHELPER_POOL_TAG);
- RtlZeroMemory(&ovsInternalRow, sizeof(MIB_IF_ROW2));
- RtlZeroMemory(&ovsInternalIPRow, sizeof (MIB_IPINTERFACE_ROW));
- ovsInternalIP = 0;
-
- ovsInternalPortNo = OVS_DEFAULT_PORT_NO;
-
InitializeListHead(&ovsSortedIPNeighList);
ovsTableLock = NdisAllocateRWLock(ndisFilterHandle);
@@ -1567,6 +1847,9 @@ OvsInitIpHelper(NDIS_HANDLE ndisFilterHandle)
ipRouteNotificationHandle = NULL;
unicastIPNotificationHandle = NULL;
+ ExInitializeResourceLite(&ovsInstanceListLock);
+ InitializeListHead(&ovsInstanceList);
+
if (ovsFwdHashTable == NULL ||
ovsRouteHashTable == NULL ||
ovsNeighHashTable == NULL ||
@@ -1587,7 +1870,6 @@ OvsInitIpHelper(NDIS_HANDLE ndisFilterHandle)
InitializeListHead(&ovsNeighHashTable[i]);
}
-
KeInitializeEvent(&ovsIpHelperThreadContext.event, NotificationEvent,
FALSE);
status = OvsRegisterChangeNotification();
@@ -1626,6 +1908,7 @@ init_cleanup:
NdisFreeRWLock(ovsTableLock);
ovsTableLock = NULL;
}
+ ExDeleteResourceLite(&ovsInstanceListLock);
NdisFreeSpinLock(&ovsIpHelperLock);
}
return STATUS_SUCCESS;
@@ -1652,6 +1935,9 @@ OvsCleanupIpHelper(VOID)
NdisFreeRWLock(ovsTableLock);
NdisFreeSpinLock(&ovsIpHelperLock);
+
+ OvsIpHelperDeleteAllInstances();
+ ExDeleteResourceLite(&ovsInstanceListLock);
}
VOID
@@ -41,6 +41,7 @@ typedef struct _OVS_IPNEIGH_ENTRY {
LIST_ENTRY link;
LIST_ENTRY slink;
LIST_ENTRY fwdList;
+ PVOID context;
} OVS_IPNEIGH_ENTRY, *POVS_IPNEIGH_ENTRY;
typedef struct _OVS_IPFORWARD_ENTRY {
@@ -94,13 +95,17 @@ typedef struct _OVS_FWD_REQUEST_INFO {
PVOID cbData2;
} OVS_FWD_REQUEST_INFO, *POVS_FWD_REQUEST_INFO;
+typedef struct _OVS_INSTANCE_REQUEST_INFO {
+ GUID netCfgInstanceId;
+ UINT32 portNo;
+} OVS_INSTANCE_REQUEST_INFO, *POVS_INSTANCE_REQUEST_INFO;
typedef struct _OVS_IP_HELPER_REQUEST {
LIST_ENTRY link;
UINT32 command;
union {
- OVS_FWD_REQUEST_INFO fwdReq;
- UINT32 dummy;
+ OVS_FWD_REQUEST_INFO fwdReq;
+ OVS_INSTANCE_REQUEST_INFO instanceReq;
};
} OVS_IP_HELPER_REQUEST, *POVS_IP_HELPER_REQUEST;
@@ -115,7 +120,7 @@ NTSTATUS OvsInitIpHelper(NDIS_HANDLE ndisFilterHandle);
VOID OvsCleanupIpHelper(VOID);
VOID OvsInternalAdapterUp(UINT32 portNo, GUID *netCfgInstanceId);
-VOID OvsInternalAdapterDown(VOID);
+VOID OvsInternalAdapterDown(UINT32 portNo, GUID netCfgInstanceId);
NTSTATUS OvsFwdIPHelperRequest(PNET_BUFFER_LIST nbl, UINT32 inPort,
const PVOID tunnelKey,
@@ -524,7 +524,7 @@ HvDisconnectNic(POVS_SWITCH_CONTEXT switchContext,
OvsPostEvent(portNo, OVS_EVENT_LINK_DOWN);
if (isInternalPort) {
- OvsInternalAdapterDown();
+ OvsInternalAdapterDown(vport->portNo, vport->netCfgInstanceId);
}
done:
@@ -1168,7 +1168,7 @@ OvsRemoveAndDeleteVport(PVOID usrParamsContext,
if (hvDelete && vport->isAbsentOnHv == FALSE) {
switchContext->internalPortId = 0;
switchContext->internalVport = NULL;
- OvsInternalAdapterDown();
+ OvsInternalAdapterDown(vport->portNo, vport->netCfgInstanceId);
}
hvSwitchPort = TRUE;
}
Added support for multiple internal adapter instances to the IpHelper module. Signed-off-by: Sorin Vinturis <svinturis@cloudbasesolutions.com> Reported-by: Sorin Vinturis <svinturis@cloudbasesolutions.com> Reported-at: https://github.com/openvswitch/ovs-issues/issues/101 --- datapath-windows/ovsext/IpHelper.c | 648 ++++++++++++++++++++++++++----------- datapath-windows/ovsext/IpHelper.h | 11 +- datapath-windows/ovsext/Vport.c | 4 +- 3 files changed, 477 insertions(+), 186 deletions(-)