hi Sorin/Alin, I suppose this is a patch that helps with supporting multiple hyper-v switches in one datapath.
We had spoken about this a couple of weeks ago during the IRC meeting. I was proposing a solution involves writing a teaming driver that can connect to multiple physical adapters. In order to support multiple internal adapters, we can write another driver similar to a TUN/TAP driver that allows us to create as many virtual adapters as we want. On the backend these virtual adapters can inject packets directly into the hyper-v switch. We had signed off by saying we’ll writeup the proposal that talks about the workflow end-to-end, and take it from there. Would it be possible to send out the proposal before we make heavy duty changes? Some concerns I have with supporting multiple switches are: 1. I am not sure how sound/great it is to forward packets from one hyper-v switch to another. Would it be possible to get a technical clarification from MSFT about this? I’ll ask around if we have any contacts. 2. How would compute provisioning work? With the current workflow we have, we pick a particular hyper-v switch (Eg. Overlay Switch) and connect all of the VMs to that switch, and OVS would take care of networking them up. If we support multiple Hyper-V switches, what would be the basis for connecting VMs to different Hyper-V switches? 3. It does not take away the need for a teaming driver. thanks, -- Nithin > On Sep 3, 2015, at 4:54 AM, Sorin Vinturis <svintu...@cloudbasesolutions.com> > wrote: > > Added support for multiple internal adapter instances to the IpHelper > module. > > Signed-off-by: Sorin Vinturis <svintu...@cloudbasesolutions.com> > Reported-by: Sorin Vinturis <svintu...@cloudbasesolutions.com> > Reported-at: > https://urldefense.proofpoint.com/v2/url?u=https-3A__github.com_openvswitch_ovs-2Dissues_issues_101&d=BQIGaQ&c=Sqcl0Ez6M0X8aeM67LKIiDJAXVeAw-YihVMNtXt-uEs&r=pNHQcdr7B40b4h6Yb7FIedI1dnBsxdDuTLBYD3JqV80&m=qGum5o5AOAacL3zQu_AHdhnVXoD8hib7nyXXg1JuQr8&s=iXoc-btgG4cPIdPKi_vFiw9g6JJS-Beqf0HUA6_dz2o&e= > > --- > 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(-) > > diff --git a/datapath-windows/ovsext/IpHelper.c > b/datapath-windows/ovsext/IpHelper.c > index de0d457..964b675 100644 > --- a/datapath-windows/ovsext/IpHelper.c > +++ b/datapath-windows/ovsext/IpHelper.c > @@ -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 > diff --git a/datapath-windows/ovsext/IpHelper.h > b/datapath-windows/ovsext/IpHelper.h > index 19702a2..4d8d034 100644 > --- a/datapath-windows/ovsext/IpHelper.h > +++ b/datapath-windows/ovsext/IpHelper.h > @@ -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, > diff --git a/datapath-windows/ovsext/Vport.c b/datapath-windows/ovsext/Vport.c > index 65a4134..dbd9a50 100644 > --- a/datapath-windows/ovsext/Vport.c > +++ b/datapath-windows/ovsext/Vport.c > @@ -525,7 +525,7 @@ HvDisconnectNic(POVS_SWITCH_CONTEXT switchContext, > OvsPostEvent(portNo, OVS_EVENT_LINK_DOWN); > > if (isInternalPort) { > - OvsInternalAdapterDown(); > + OvsInternalAdapterDown(vport->portNo, vport->netCfgInstanceId); > } > > done: > @@ -1160,7 +1160,7 @@ OvsRemoveAndDeleteVport(PVOID usrParamsContext, > if (hvDelete && vport->isAbsentOnHv == FALSE) { > switchContext->internalPortId = 0; > switchContext->internalVport = NULL; > - OvsInternalAdapterDown(); > + OvsInternalAdapterDown(vport->portNo, > vport->netCfgInstanceId); > } > hvSwitchPort = TRUE; > } > -- > 1.9.0.msysgit.0 > > _______________________________________________ > dev mailing list > dev@openvswitch.org > https://urldefense.proofpoint.com/v2/url?u=http-3A__openvswitch.org_mailman_listinfo_dev&d=BQIGaQ&c=Sqcl0Ez6M0X8aeM67LKIiDJAXVeAw-YihVMNtXt-uEs&r=pNHQcdr7B40b4h6Yb7FIedI1dnBsxdDuTLBYD3JqV80&m=qGum5o5AOAacL3zQu_AHdhnVXoD8hib7nyXXg1JuQr8&s=Fe2_m9sZZzPkihUJPIQXx4AGUwFZ8bnPCv6X0nh0Lfg&e= > _______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev