summaryrefslogtreecommitdiff
path: root/datapath-windows/ovsext/IpHelper.c
diff options
context:
space:
mode:
Diffstat (limited to 'datapath-windows/ovsext/IpHelper.c')
-rw-r--r--datapath-windows/ovsext/IpHelper.c482
1 files changed, 315 insertions, 167 deletions
diff --git a/datapath-windows/ovsext/IpHelper.c b/datapath-windows/ovsext/IpHelper.c
index d7fa2ca84..b8866bed9 100644
--- a/datapath-windows/ovsext/IpHelper.c
+++ b/datapath-windows/ovsext/IpHelper.c
@@ -18,6 +18,7 @@
#include "IpHelper.h"
#include "Switch.h"
#include "Jhash.h"
+#include <ip2string.h>
extern POVS_SWITCH_CONTEXT gOvsSwitchContext;
@@ -71,7 +72,7 @@ static OVS_IP_HELPER_THREAD_CONTEXT ovsIpHelperThreadContext;
static POVS_IPFORWARD_ENTRY OvsLookupIPForwardEntry(PIP_ADDRESS_PREFIX prefix);
static VOID OvsRemoveIPForwardEntry(POVS_IPFORWARD_ENTRY ipf);
-static VOID OvsRemoveAllFwdEntriesWithSrc(UINT32 ipAddr);
+static VOID OvsRemoveAllFwdEntriesWithSrc(SOCKADDR_INET ipAddr);
static VOID OvsRemoveIPNeighEntriesWithInstance(POVS_IPHELPER_INSTANCE instance);
static VOID OvsCleanupIpHelperRequestList(VOID);
static VOID OvsCleanupFwdTable(VOID);
@@ -196,24 +197,83 @@ OvsGetIPInterfaceEntry(NET_LUID luid,
return status;
}
+static __inline VOID
+OvsDumpIpAddrDesc(char *desc, char *andMsg, char *tailMsg,
+ const SOCKADDR_INET *IpAddress)
+{
+ if (IpAddress->si_family == AF_INET) {
+ UINT32 ipAddr = 0;
+ ipAddr = IpAddress->Ipv4.sin_addr.s_addr;
+ OVS_LOG_INFO("%s: %d.%d.%d.%d%s%s", desc,
+ ipAddr & 0xff, (ipAddr >> 8) & 0xff,
+ (ipAddr >> 16) & 0xff, ipAddr >> 24,
+ andMsg?andMsg:"", tailMsg?tailMsg:"");
+ } else if (IpAddress->si_family == AF_INET6) {
+ struct in6_addr *pAddr = NULL;
+ char wszAddr[256] = {0};
+
+ pAddr = (struct in6_addr *)&(IpAddress->Ipv6.sin6_addr);
+ if (!RtlIpv6AddressToStringA(pAddr, wszAddr)) {
+ OVS_LOG_INFO("%s Ipv6 Address got failed\n", desc);
+ } else {
+ OVS_LOG_INFO("%s(IPv6): %s%s%s", desc, wszAddr,
+ andMsg?andMsg:"", tailMsg?tailMsg:"");
+ }
+ }
+}
+
+static __inline VOID
+OvsDumpIpAddrMsg(char *desc, const SOCKADDR_INET *IpAddress)
+{
+ OvsDumpIpAddrDesc(desc, NULL, NULL, IpAddress);
+}
+
+static __inline VOID
+OvsDumpIpAddrMsgStatus(char *descV4, char *descV6, NTSTATUS status,
+ const SOCKADDR_INET *IpAddress)
+{
+ if (!descV4 || !descV6 || !IpAddress) {
+ return;
+ }
+
+ if (IpAddress->si_family == AF_INET) {
+ UINT32 ipAddr = IpAddress->Ipv4.sin_addr.s_addr;
+ OVS_LOG_INFO("%s: %d.%d.%d.%d, status: %x", descV4,
+ ipAddr & 0xff, (ipAddr >> 8) & 0xff,
+ (ipAddr >> 16) & 0xff, (ipAddr >> 24) & 0xff, status);
+ } else if (IpAddress->si_family == AF_INET6) {
+ struct in6_addr *pAddr = NULL;
+ char wszAddr[256] = {0};
+ pAddr = (struct in6_addr*)&(IpAddress->Ipv6.sin6_addr);
+ if (!RtlIpv6AddressToStringA(pAddr, wszAddr)) {
+ OVS_LOG_INFO("Ipv6 Address got failed\n");
+ } else {
+ OVS_LOG_INFO("%s: %s, status: %x",
+ descV6, wszAddr, status);
+ }
+ }
+
+}
+
+static __inline VOID
+OvsDumpIpAddrDescStatus(char *desc, NTSTATUS status,
+ const SOCKADDR_INET *IpAddress)
+{
+ OvsDumpIpAddrMsgStatus(desc, desc, status, IpAddress);
+}
+
static VOID
OvsDumpIPEntry(PMIB_UNICASTIPADDRESS_ROW ipRow)
{
- UINT32 ipAddr;
-
OVS_LOG_INFO("InterfaceLuid: NetLuidIndex: %d, type: %d",
ipRow->InterfaceLuid.Info.NetLuidIndex,
ipRow->InterfaceLuid.Info.IfType);
OVS_LOG_INFO("InterfaceIndex: %d", ipRow->InterfaceIndex);
- ASSERT(ipRow->Address.si_family == AF_INET);
-
- ipAddr = ipRow->Address.Ipv4.sin_addr.s_addr;
- OVS_LOG_INFO("Unicast Address: %d.%d.%d.%d\n",
- ipAddr & 0xff, (ipAddr >> 8) & 0xff,
- (ipAddr >> 16) & 0xff, ipAddr >> 24);
+ OVS_LOG_INFO("Address.si_family: %d", ipRow->Address.si_family);
+ OvsDumpIpAddrMsg("Unicast Address", &(ipRow->Address));
}
@@ -229,7 +289,7 @@ OvsGetIPEntry(NET_LUID interfaceLuid,
return STATUS_INVALID_PARAMETER;
}
- status = GetUnicastIpAddressTable(AF_INET, &ipTable);
+ status = GetUnicastIpAddressTable(AF_UNSPEC, &ipTable);
if (status != STATUS_SUCCESS) {
OVS_LOG_INFO("Fail to get unicast address table, status: %x", status);
@@ -300,37 +360,25 @@ OvsDumpRoute(const SOCKADDR_INET *sourceAddress,
const SOCKADDR_INET *destinationAddress,
PMIB_IPFORWARD_ROW2 route)
{
- UINT32 ipAddr = destinationAddress->Ipv4.sin_addr.s_addr;
-
- OVS_LOG_INFO("Destination: %d.%d.%d.%d",
- ipAddr & 0xff, (ipAddr >> 8) & 0xff,
- (ipAddr >> 16) & 0xff, (ipAddr >> 24) & 0xff);
-
- ipAddr = sourceAddress->Ipv4.sin_addr.s_addr;
- OVS_LOG_INFO("Source: %d.%d.%d.%d",
- ipAddr & 0xff, (ipAddr >> 8) & 0xff,
- (ipAddr >> 16) & 0xff, (ipAddr >> 24) & 0xff);
-
- ipAddr = route->NextHop.Ipv4.sin_addr.s_addr;
- OVS_LOG_INFO("NextHop: %d.%d.%d.%d",
- ipAddr & 0xff, (ipAddr >> 8) & 0xff,
- (ipAddr >> 16) & 0xff, (ipAddr >> 24) & 0xff);
+ OvsDumpIpAddrMsg("Destination", destinationAddress);
+ OvsDumpIpAddrMsg("Source", sourceAddress);
+ OvsDumpIpAddrMsg("NextHop", &(route->NextHop));
}
-
NTSTATUS
OvsGetRoute(SOCKADDR_INET *destinationAddress,
PMIB_IPFORWARD_ROW2 route,
SOCKADDR_INET *sourceAddress,
POVS_IPHELPER_INSTANCE *instance,
POVS_VPORT_ENTRY* vport,
- UINT32 srcIp)
+ SOCKADDR_INET srcIp)
{
NTSTATUS status = STATUS_NETWORK_UNREACHABLE;
NTSTATUS result = STATUS_SUCCESS;
PLIST_ENTRY head, link, next;
ULONG minMetric = MAXULONG;
+
if (destinationAddress == NULL || route == NULL) {
return STATUS_INVALID_PARAMETER;
}
@@ -342,7 +390,10 @@ OvsGetRoute(SOCKADDR_INET *destinationAddress,
MIB_IPFORWARD_ROW2 crtRoute = { 0 };
POVS_IPHELPER_INSTANCE crtInstance = NULL;
WCHAR interfaceName[IF_MAX_STRING_SIZE + 1];
-
+#ifdef DBG
+ char ansiIfname[256] = { 0 };
+ size_t strLen = 0;
+#endif
crtInstance = CONTAINING_RECORD(link, OVS_IPHELPER_INSTANCE, link);
ExAcquireResourceExclusiveLite(&crtInstance->lock, TRUE);
@@ -355,8 +406,24 @@ OvsGetRoute(SOCKADDR_INET *destinationAddress,
continue;
}
+#ifdef DBG
+ RtlZeroMemory(ansiIfname, 256);
+
+ status =
+ ConvertInterfaceLuidToAlias(&crtInstance->internalRow.InterfaceLuid,
+ interfaceName,
+ IF_MAX_STRING_SIZE + 1);
+
+ if (NT_SUCCESS(status)) {
+ status = RtlStringCbLengthW(interfaceName, IF_MAX_STRING_SIZE,
+ &strLen);
+ }
+
+ OvsConvertWcharToAnsiStr(interfaceName, strLen, ansiIfname, 256);
+ OVS_LOG_INFO("the interface name is %s", ansiIfname);
+#endif
if (minMetric > crtRoute.Metric &&
- (!srcIp || srcIp == crtSrcAddr.Ipv4.sin_addr.S_un.S_addr)) {
+ (OvsIphIsZero(&srcIp) || OvsIphAddrEquals(&srcIp, &crtSrcAddr))) {
status = STATUS_SUCCESS;
size_t len = 0;
minMetric = crtRoute.Metric;
@@ -374,13 +441,24 @@ OvsGetRoute(SOCKADDR_INET *destinationAddress,
status = RtlStringCbLengthW(interfaceName, IF_MAX_STRING_SIZE,
&len);
}
-
+#ifdef DBG
+ RtlZeroMemory(ansiIfname, 256);
+ OvsConvertWcharToAnsiStr(interfaceName, len, ansiIfname, 256);
+ OVS_LOG_INFO("the found interface name is %s", ansiIfname);
+#endif
if (gOvsSwitchContext != NULL && NT_SUCCESS(status)) {
NdisAcquireRWLockRead(gOvsSwitchContext->dispatchLock,
- &lockState, 0);
+ &lockState, 0);
*vport = OvsFindVportByHvNameW(gOvsSwitchContext,
interfaceName,
len);
+#ifdef DBG
+ if (*vport) {
+ OVS_LOG_INFO("match the ovs port ovsName: %s", (*vport)->ovsName);
+ } else {
+ OVS_LOG_INFO("not get the ovs port");
+ }
+#endif
NdisReleaseRWLock(gOvsSwitchContext->dispatchLock, &lockState);
}
}
@@ -396,11 +474,7 @@ OvsGetRoute(SOCKADDR_INET *destinationAddress,
static VOID
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);
+ OvsDumpIpAddrMsg("Neigh", &(ipNeigh->Address));
OVS_LOG_INFO("MAC Address: %02x:%02x:%02x:%02x:%02x:%02x",
ipNeigh->PhysicalAddress[0],
ipNeigh->PhysicalAddress[1],
@@ -421,11 +495,10 @@ OvsGetIPNeighEntry(PMIB_IPNET_ROW2 ipNeigh)
status = GetIpNetEntry2(ipNeigh);
if (status != STATUS_SUCCESS) {
- UINT32 ipAddr = ipNeigh->Address.Ipv4.sin_addr.s_addr;
- OVS_LOG_INFO("Fail to get ARP entry: %d.%d.%d.%d, status: %x",
- ipAddr & 0xff, (ipAddr >> 8) & 0xff,
- (ipAddr >> 16) & 0xff, (ipAddr >> 24) & 0xff, status);
- return status;
+ OvsDumpIpAddrMsgStatus("Fail to get ARP entry",
+ "Fail to get neighbour entry",
+ status, &(ipNeigh->Address));
+ return status;
}
if (ipNeigh->State == NlnsReachable ||
ipNeigh->State == NlnsPermanent) {
@@ -445,10 +518,9 @@ OvsResolveIPNeighEntry(PMIB_IPNET_ROW2 ipNeigh)
status = ResolveIpNetEntry2(ipNeigh, NULL);
if (status != STATUS_SUCCESS) {
- UINT32 ipAddr = ipNeigh->Address.Ipv4.sin_addr.s_addr;
- OVS_LOG_INFO("Fail to resolve ARP entry: %d.%d.%d.%d, status: %x",
- ipAddr & 0xff, (ipAddr >> 8) & 0xff,
- (ipAddr >> 16) & 0xff, (ipAddr >> 24) & 0xff, status);
+ OvsDumpIpAddrMsgStatus("Fail to get ARP entry",
+ "Fail to get neighbour entry",
+ status, &(ipNeigh->Address));
return status;
}
@@ -463,7 +535,7 @@ OvsResolveIPNeighEntry(PMIB_IPNET_ROW2 ipNeigh)
NTSTATUS
OvsGetOrResolveIPNeigh(PMIB_IF_ROW2 ipRow,
- UINT32 ipAddr,
+ SOCKADDR_INET ipAddr,
PMIB_IPNET_ROW2 ipNeigh)
{
NTSTATUS status;
@@ -473,8 +545,7 @@ OvsGetOrResolveIPNeigh(PMIB_IF_ROW2 ipRow,
RtlZeroMemory(ipNeigh, sizeof (*ipNeigh));
ipNeigh->InterfaceLuid.Value = ipRow->InterfaceLuid.Value;
ipNeigh->InterfaceIndex = ipRow->InterfaceIndex;
- ipNeigh->Address.si_family = AF_INET;
- ipNeigh->Address.Ipv4.sin_addr.s_addr = ipAddr;
+ OvsCopyIphAddress(&(ipNeigh->Address), &ipAddr);
status = OvsGetIPNeighEntry(ipNeigh);
@@ -482,8 +553,7 @@ OvsGetOrResolveIPNeigh(PMIB_IF_ROW2 ipRow,
RtlZeroMemory(ipNeigh, sizeof (*ipNeigh));
ipNeigh->InterfaceLuid.Value = ipRow->InterfaceLuid.Value;
ipNeigh->InterfaceIndex = ipRow->InterfaceIndex;
- ipNeigh->Address.si_family = AF_INET;
- ipNeigh->Address.Ipv4.sin_addr.s_addr = ipAddr;
+ OvsCopyIphAddress(&(ipNeigh->Address), &ipAddr);
status = OvsResolveIPNeighEntry(ipNeigh);
}
return status;
@@ -714,29 +784,45 @@ OvsChangeCallbackIpRoute(PVOID context,
MIB_NOTIFICATION_TYPE notificationType)
{
UINT32 ipAddr, nextHop;
+ struct in6_addr *pAddr = NULL, *pNextHop = NULL;
+ char wszAddr[256] = { 0 };
+ char wszNextHop[256] = { 0 };
UNREFERENCED_PARAMETER(context);
switch (notificationType) {
case MibAddInstance:
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 added",
- 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);
+ if (ipRoute->DestinationPrefix.Prefix.si_family == AF_INET) {
+ 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 added",
+ 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);
+ } else if (ipRoute->DestinationPrefix.Prefix.si_family == AF_INET6) {
+ pAddr = (struct in6_addr *)&(ipRoute->DestinationPrefix.Prefix.Ipv6.sin6_addr);
+ if (!RtlIpv6AddressToStringA(pAddr, wszAddr)) {
+ OVS_LOG_INFO("DestinationPrefix Ipv6 Address got failed\n");
+ } else {
+ pNextHop = (struct in6_addr *)&(ipRoute->NextHop.Ipv6.sin6_addr);
+ if (!RtlIpv6AddressToStringA(pNextHop, wszNextHop)) {
+ OVS_LOG_INFO("NextHop Ipv6 Address got failed\n");
+ } else {
+ OVS_LOG_INFO("IPRoute: To %s/%d through %s added",
+ wszAddr, ipRoute->DestinationPrefix.PrefixLength,
+ wszNextHop);
+ }
+ }
+ }
break;
case MibParameterNotification:
case MibDeleteInstance:
{
ASSERT(ipRoute);
- ipAddr = ipRoute->DestinationPrefix.Prefix.Ipv4.sin_addr.s_addr;
- nextHop = ipRoute->NextHop.Ipv4.sin_addr.s_addr;
POVS_IPFORWARD_ENTRY ipf;
LOCK_STATE_EX lockState;
@@ -748,14 +834,34 @@ OvsChangeCallbackIpRoute(PVOID context,
}
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");
+ if (ipRoute->DestinationPrefix.Prefix.si_family == AF_INET) {
+ 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");
+ } else if (ipRoute->DestinationPrefix.Prefix.si_family == AF_INET6) {
+ pAddr = (struct in6_addr *)&(ipRoute->DestinationPrefix.Prefix.Ipv6.sin6_addr);
+ if (!RtlIpv6AddressToStringA(pAddr, wszAddr)) {
+ OVS_LOG_INFO("DestinationPrefix Ipv6 Address got failed\n");
+ } else {
+ pNextHop = (struct in6_addr *)&(ipRoute->NextHop.Ipv6.sin6_addr);
+ if (!RtlIpv6AddressToStringA(pNextHop, wszNextHop)) {
+ OVS_LOG_INFO("NextHop Ipv6 Address got failed\n");
+ } else {
+ OVS_LOG_INFO("IPRoute: To %s/%d through %s %s.",
+ wszAddr, ipRoute->DestinationPrefix.PrefixLength,
+ wszNextHop, notificationType == MibDeleteInstance ? "deleted" :
+ "modified");
+ }
+ }
+ }
break;
}
@@ -772,7 +878,7 @@ OvsChangeCallbackUnicastIpAddress(PVOID context,
PMIB_UNICASTIPADDRESS_ROW unicastRow,
MIB_NOTIFICATION_TYPE notificationType)
{
- UINT32 ipAddr;
+ SOCKADDR_INET iphAddr = { 0 };
UNREFERENCED_PARAMETER(context);
switch (notificationType) {
@@ -782,7 +888,7 @@ OvsChangeCallbackUnicastIpAddress(PVOID context,
PLIST_ENTRY head, link, next;
ASSERT(unicastRow);
- ipAddr = unicastRow->Address.Ipv4.sin_addr.s_addr;
+ OvsCopyIphAddress(&iphAddr, &(unicastRow->Address));
ExAcquireResourceExclusiveLite(&ovsInstanceListLock, TRUE);
head = &(ovsInstanceList);
@@ -796,14 +902,12 @@ OvsChangeCallbackUnicastIpAddress(PVOID context,
OvsCheckInstanceRow(&instance->internalRow,
&unicastRow->InterfaceLuid,
unicastRow->InterfaceIndex)) {
+ OvsCopyIphAddress(&(instance->ipAddress), &(unicastRow->Address));
- 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");
-
+ OvsDumpIpAddrDesc("IP Address", " is ",
+ notificationType == MibAddInstance ?
+ "added": "modified",
+ &(unicastRow->Address));
ExReleaseResourceLite(&instance->lock);
break;
}
@@ -821,7 +925,7 @@ OvsChangeCallbackUnicastIpAddress(PVOID context,
BOOLEAN found = FALSE;
ASSERT(unicastRow);
- ipAddr = unicastRow->Address.Ipv4.sin_addr.s_addr;
+ OvsCopyIphAddress(&iphAddr, &(unicastRow->Address));
ExAcquireResourceExclusiveLite(&ovsInstanceListLock, TRUE);
head = &(ovsInstanceList);
@@ -847,12 +951,10 @@ OvsChangeCallbackUnicastIpAddress(PVOID context,
if (found) {
NdisAcquireRWLockWrite(ovsTableLock, &lockState, 0);
- OvsRemoveAllFwdEntriesWithSrc(ipAddr);
+ OvsRemoveAllFwdEntriesWithSrc(iphAddr);
NdisReleaseRWLock(ovsTableLock, &lockState);
- OVS_LOG_INFO("IP Address removed: %d.%d.%d.%d",
- ipAddr & 0xff, (ipAddr >> 8) & 0xff,
- (ipAddr >> 16) & 0xff, (ipAddr >> 24) & 0xff);
+ OvsDumpIpAddrMsg("IP Address removed", &(unicastRow->Address));
}
break;
@@ -891,7 +993,7 @@ OvsRegisterChangeNotification()
UINT dummy = 0;
- status = NotifyIpInterfaceChange(AF_INET, OvsChangeCallbackIpInterface,
+ status = NotifyIpInterfaceChange(AF_UNSPEC, OvsChangeCallbackIpInterface,
NULL, TRUE,
&ipInterfaceNotificationHandle);
if (status != STATUS_SUCCESS) {
@@ -901,14 +1003,14 @@ OvsRegisterChangeNotification()
}
/* The CallerContext is dummy and should never be used */
- status = NotifyRouteChange2(AF_INET, OvsChangeCallbackIpRoute, &dummy,
+ status = NotifyRouteChange2(AF_UNSPEC, OvsChangeCallbackIpRoute, &dummy,
TRUE, &ipRouteNotificationHandle);
if (status != STATUS_SUCCESS) {
OVS_LOG_ERROR("Failed to register IP route change, status: %x.",
status);
goto register_cleanup;
}
- status = NotifyUnicastIpAddressChange(AF_INET,
+ status = NotifyUnicastIpAddressChange(AF_UNSPEC,
OvsChangeCallbackUnicastIpAddress,
NULL, TRUE,
&unicastIPNotificationHandle);
@@ -926,53 +1028,53 @@ register_cleanup:
static POVS_IPNEIGH_ENTRY
-OvsLookupIPNeighEntry(UINT32 ipAddr)
+OvsLookupIPNeighEntry(SOCKADDR_INET ipAddr)
{
PLIST_ENTRY link;
- UINT32 hash = OvsJhashWords(&ipAddr, 1, OVS_HASH_BASIS);
+
+ UINT32 hash = OvsJhashIphHdr(&ipAddr);
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) {
+ if (OvsIphAddrEquals(&(entry->ipAddr), &ipAddr)) {
return entry;
}
}
return NULL;
}
-
static UINT32
OvsHashIPPrefix(PIP_ADDRESS_PREFIX prefix)
{
- UINT64 words = (UINT64)prefix->Prefix.Ipv4.sin_addr.s_addr << 32 |
- (UINT32)prefix->PrefixLength;
- return OvsJhashWords((UINT32 *)&words, 2, OVS_HASH_BASIS);
+ UINT32 hash = 0;
+
+ if (prefix->Prefix.si_family == AF_INET) {
+ UINT64 words = (UINT64)prefix->Prefix.Ipv4.sin_addr.s_addr << 32 |
+ (UINT32)prefix->PrefixLength;
+ hash = OvsJhashWords((UINT32 *)&words, 2, OVS_HASH_BASIS);
+ } else if (prefix->Prefix.si_family == AF_INET6) {
+ UCHAR words[20] = { 0 };
+ RtlCopyMemory(words, prefix->Prefix.Ipv6.sin6_addr.u.Byte,
+ sizeof(prefix->Prefix.Ipv6.sin6_addr.u.Byte));
+ *((UINT32*)(&words[16])) = (UINT32)prefix->PrefixLength;
+ hash = OvsJhashBytes((UINT32 *)words, 5, OVS_HASH_BASIS);
+ }
+ return hash;
}
-
static POVS_IPFORWARD_ENTRY
OvsLookupIPForwardEntry(PIP_ADDRESS_PREFIX prefix)
{
-
PLIST_ENTRY link;
UINT32 hash;
- ASSERT(prefix->Prefix.si_family == AF_INET);
-
- hash = RtlUlongByteSwap(prefix->Prefix.Ipv4.sin_addr.s_addr);
-
- ASSERT(prefix->PrefixLength >= 32 ||
- (hash & (((UINT32)1 << (32 - prefix->PrefixLength)) - 1)) == 0);
-
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 ==
- prefix->Prefix.Ipv4.sin_addr.s_addr) {
+ if (OvsIphAddrEquals(&ipfEntry->prefix.Prefix, &prefix->Prefix)) {
return ipfEntry;
}
}
@@ -981,17 +1083,19 @@ OvsLookupIPForwardEntry(PIP_ADDRESS_PREFIX prefix)
static POVS_FWD_ENTRY
-OvsLookupIPFwdEntry(UINT32 srcIp, UINT32 dstIp)
+OvsLookupIPFwdEntry(SOCKADDR_INET srcIp, SOCKADDR_INET dstIp)
{
PLIST_ENTRY link;
- UINT32 hash = OvsJhashWords(&dstIp, 1, OVS_HASH_BASIS);
+ UINT32 hash = 0;
+ hash = OvsJhashIphHdr(&dstIp);
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 &&
- (!srcIp || entry->info.srcIpAddr == srcIp)) {
+
+ if (OvsIphAddrEquals(&(entry->info.dstIphAddr), &dstIp) &&
+ (OvsIphIsZero(&srcIp) || OvsIphAddrEquals(&(entry->info.srcIphAddr), &srcIp))) {
return entry;
}
}
@@ -1000,9 +1104,9 @@ OvsLookupIPFwdEntry(UINT32 srcIp, UINT32 dstIp)
NTSTATUS
-OvsLookupIPFwdInfo(UINT32 srcIp,
- UINT32 dstIp,
- POVS_FWD_INFO info)
+OvsLookupIPhFwdInfo(SOCKADDR_INET srcIp,
+ SOCKADDR_INET dstIp,
+ POVS_FWD_INFO info)
{
POVS_FWD_ENTRY entry;
LOCK_STATE_EX lockState;
@@ -1013,13 +1117,13 @@ OvsLookupIPFwdInfo(UINT32 srcIp,
if (entry) {
RtlCopyMemory(info->value, entry->info.value,
sizeof entry->info.value);
+ OvsCopyIphAddress(&info->dstIphAddr, &(entry->info.dstIphAddr));
status = STATUS_SUCCESS;
}
NdisReleaseRWLock(ovsTableLock, &lockState);
return status;
}
-
static POVS_IPNEIGH_ENTRY
OvsCreateIPNeighEntry(PMIB_IPNET_ROW2 ipNeigh,
POVS_IPHELPER_INSTANCE instance)
@@ -1036,7 +1140,7 @@ OvsCreateIPNeighEntry(PMIB_IPNET_ROW2 ipNeigh,
}
RtlZeroMemory(entry, sizeof (OVS_IPNEIGH_ENTRY));
- entry->ipAddr = ipNeigh->Address.Ipv4.sin_addr.s_addr;
+ OvsCopyIphAddress(&(entry->ipAddr), &(ipNeigh->Address));
KeQuerySystemTime((LARGE_INTEGER *)&timeVal);
entry->timeout = timeVal + OVS_IPNEIGH_TIMEOUT;
RtlCopyMemory(entry->macAddr, ipNeigh->PhysicalAddress,
@@ -1064,7 +1168,7 @@ OvsCreateIPForwardEntry(PMIB_IPFORWARD_ROW2 ipRoute)
RtlZeroMemory(entry, sizeof (OVS_IPFORWARD_ENTRY));
RtlCopyMemory(&entry->prefix, &ipRoute->DestinationPrefix,
sizeof (IP_ADDRESS_PREFIX));
- entry->nextHop = ipRoute->NextHop.Ipv4.sin_addr.s_addr;
+ OvsCopyIphAddress(&(entry->nextHop), &(ipRoute->NextHop));
InitializeListHead(&entry->fwdList);
return entry;
@@ -1198,7 +1302,8 @@ OvsAddIPFwdCache(POVS_FWD_ENTRY fwdEntry,
NdisAcquireSpinLock(&ovsIpHelperLock);
OvsAddToSortedNeighList(ipn);
NdisReleaseSpinLock(&ovsIpHelperLock);
- hash = OvsJhashWords(&ipn->ipAddr, 1, OVS_HASH_BASIS);
+ hash = OvsJhashIphHdr(&ipn->ipAddr);
+
InsertHeadList(&ovsNeighHashTable[hash & OVS_NEIGH_HASH_TABLE_MASK],
&ipn->link);
}
@@ -1216,15 +1321,15 @@ OvsAddIPFwdCache(POVS_FWD_ENTRY fwdEntry,
ipn->refCount++;
fwdEntry->ipn = ipn;
- hash = OvsJhashWords(&fwdEntry->info.dstIpAddr, 1, OVS_HASH_BASIS);
+ hash = OvsJhashIphHdr(&(fwdEntry->info.dstIphAddr));
+
InsertHeadList(&ovsFwdHashTable[hash & OVS_FWD_HASH_TABLE_MASK],
&fwdEntry->link);
ovsNumFwdEntries++;
}
-
static VOID
-OvsRemoveAllFwdEntriesWithSrc(UINT32 ipAddr)
+OvsRemoveAllFwdEntriesWithSrc(SOCKADDR_INET ipAddr)
{
UINT32 i;
PLIST_ENTRY link, next;
@@ -1234,14 +1339,14 @@ OvsRemoveAllFwdEntriesWithSrc(UINT32 ipAddr)
POVS_FWD_ENTRY fwdEntry;
fwdEntry = CONTAINING_RECORD(link, OVS_FWD_ENTRY, link);
- if (fwdEntry->info.srcIpAddr == ipAddr) {
+
+ if (OvsIphAddrEquals(&(fwdEntry->info.srcIphAddr), &ipAddr)) {
OvsRemoveFwdEntry(fwdEntry);
}
}
}
}
-
static VOID
OvsRemoveIPNeighEntriesWithInstance(POVS_IPHELPER_INSTANCE instance)
{
@@ -1519,7 +1624,7 @@ OvsEnqueueIpHelperRequest(POVS_IP_HELPER_REQUEST request)
NTSTATUS
OvsFwdIPHelperRequest(PNET_BUFFER_LIST nbl,
UINT32 inPort,
- const OvsIPv4TunnelKey *tunnelKey,
+ const OvsIPTunnelKey *tunnelKey,
OvsIPHelperCallback cb,
PVOID cbData1,
PVOID cbData2)
@@ -1540,21 +1645,18 @@ OvsFwdIPHelperRequest(PNET_BUFFER_LIST nbl,
request->fwdReq.cb = cb;
request->fwdReq.cbData1 = cbData1;
request->fwdReq.cbData2 = cbData2;
-
return OvsEnqueueIpHelperRequest(request);
}
-
static VOID
OvsHandleFwdRequest(POVS_IP_HELPER_REQUEST request)
{
- SOCKADDR_INET dst, src;
NTSTATUS status;
MIB_IPFORWARD_ROW2 ipRoute;
MIB_IPNET_ROW2 ipNeigh;
- OVS_FWD_INFO fwdInfo = { 0 };
- UINT32 ipAddr;
- UINT32 srcAddr;
+ OVS_FWD_INFO fwdInfo;
+ SOCKADDR_INET iphAddr;
+ SOCKADDR_INET srcAddr;
POVS_FWD_ENTRY fwdEntry = NULL;
POVS_IPFORWARD_ENTRY ipf = NULL;
POVS_IPNEIGH_ENTRY ipn = NULL;
@@ -1564,44 +1666,40 @@ OvsHandleFwdRequest(POVS_IP_HELPER_REQUEST request)
BOOLEAN newFWD = FALSE;
POVS_IPHELPER_INSTANCE instance = NULL;
- status = OvsLookupIPFwdInfo(request->fwdReq.tunnelKey.src,
- request->fwdReq.tunnelKey.dst,
- &fwdInfo);
+ RtlZeroMemory(&fwdInfo, sizeof(OVS_FWD_INFO));
+
+ status = OvsLookupIPhFwdInfo(request->fwdReq.tunnelKey.src,
+ request->fwdReq.tunnelKey.dst,
+ &fwdInfo);
if (status == STATUS_SUCCESS) {
goto fwd_handle_nbl;
}
/* find IPRoute */
- RtlZeroMemory(&dst, sizeof(dst));
- RtlZeroMemory(&src, sizeof(src));
+ RtlZeroMemory(&srcAddr, sizeof(srcAddr));
+ RtlZeroMemory(&iphAddr, sizeof(iphAddr));
RtlZeroMemory(&ipRoute, sizeof (MIB_IPFORWARD_ROW2));
- dst.si_family = AF_INET;
- dst.Ipv4.sin_addr.s_addr = request->fwdReq.tunnelKey.dst;
-
- status = OvsGetRoute(&dst, &ipRoute, &src, &instance, &fwdInfo.vport, request->fwdReq.tunnelKey.src);
- if (request->fwdReq.tunnelKey.src && request->fwdReq.tunnelKey.src != src.Ipv4.sin_addr.s_addr) {
- UINT32 tempAddr = dst.Ipv4.sin_addr.s_addr;
- OVS_LOG_INFO("Fail to get route to %d.%d.%d.%d, status: %x",
- tempAddr & 0xff, (tempAddr >> 8) & 0xff,
- (tempAddr >> 16) & 0xff, (tempAddr >> 24) & 0xff, status);
+ status = OvsGetRoute(&request->fwdReq.tunnelKey.dst, &ipRoute, &srcAddr,
+ &instance, &fwdInfo.vport,
+ request->fwdReq.tunnelKey.src);
+ if (!OvsIphIsZero(&(request->fwdReq.tunnelKey.src)) &&
+ !OvsIphAddrEquals(&(request->fwdReq.tunnelKey.src), &srcAddr)) {
+ OvsDumpIpAddrDescStatus("Fail to get route to",
+ status, &(request->fwdReq.tunnelKey.dst));
goto fwd_handle_nbl;
}
if (status != STATUS_SUCCESS || instance == NULL) {
- UINT32 tempAddr = dst.Ipv4.sin_addr.s_addr;
- OVS_LOG_INFO("Fail to get route to %d.%d.%d.%d, status: %x",
- tempAddr & 0xff, (tempAddr >> 8) & 0xff,
- (tempAddr >> 16) & 0xff, (tempAddr >> 24) & 0xff, status);
+ OvsDumpIpAddrDescStatus("Fail to get route to",
+ status, &(request->fwdReq.tunnelKey.dst));
goto fwd_handle_nbl;
}
ExAcquireResourceExclusiveLite(&instance->lock, TRUE);
- srcAddr = src.Ipv4.sin_addr.s_addr;
-
/* find IPNeigh */
- ipAddr = ipRoute.NextHop.Ipv4.sin_addr.s_addr;
- if (ipAddr != 0) {
+ OvsCopyIphAddress(&iphAddr, &(ipRoute.NextHop));
+ if (!OvsIphIsZero(&iphAddr)) {
NdisAcquireRWLockWrite(ovsTableLock, &lockState, 0);
- ipn = OvsLookupIPNeighEntry(ipAddr);
+ ipn = OvsLookupIPNeighEntry(iphAddr);
if (ipn) {
goto fwd_request_done;
}
@@ -1610,11 +1708,11 @@ OvsHandleFwdRequest(POVS_IP_HELPER_REQUEST request)
RtlZeroMemory(&ipNeigh, sizeof (ipNeigh));
ipNeigh.InterfaceLuid.Value = instance->internalRow.InterfaceLuid.Value;
- if (ipAddr == 0) {
- ipAddr = request->fwdReq.tunnelKey.dst;
+ if (OvsIphIsZero(&iphAddr)) {
+ OvsCopyIphAddress(&iphAddr, &(request->fwdReq.tunnelKey.dst));
}
status = OvsGetOrResolveIPNeigh(&instance->internalRow,
- ipAddr, &ipNeigh);
+ iphAddr, &ipNeigh);
if (status != STATUS_SUCCESS) {
ExReleaseResourceLite(&instance->lock);
goto fwd_handle_nbl;
@@ -1641,21 +1739,21 @@ fwd_request_done:
PLIST_ENTRY link;
link = ipf->fwdList.Flink;
fwdEntry = CONTAINING_RECORD(link, OVS_FWD_ENTRY, ipfLink);
- if (fwdEntry->info.srcIpAddr != srcAddr) {
+ if (!OvsIphAddrEquals(&(fwdEntry->info.srcIphAddr), &srcAddr)) {
OvsRemoveFwdEntry(fwdEntry);
NdisReleaseRWLock(ovsTableLock, &lockState);
ExReleaseResourceLite(&instance->lock);
status = STATUS_INSUFFICIENT_RESOURCES;
goto fwd_handle_nbl;
}
- srcAddr = fwdEntry->info.srcIpAddr;
+ OvsCopyIphAddress(&srcAddr, &(fwdEntry->info.srcIphAddr));
}
/*
* initialize ipn
*/
if (ipn == NULL) {
- ipn = OvsLookupIPNeighEntry(ipAddr);
+ ipn = OvsLookupIPNeighEntry(iphAddr);
if (ipn == NULL) {
ipn = OvsCreateIPNeighEntry(&ipNeigh, instance);
if (ipn == NULL) {
@@ -1671,8 +1769,8 @@ fwd_request_done:
/*
* initialize fwdEntry
*/
- fwdInfo.dstIpAddr = request->fwdReq.tunnelKey.dst;
- fwdInfo.srcIpAddr = srcAddr;
+ OvsCopyIphAddress(&fwdInfo.dstIphAddr, &(request->fwdReq.tunnelKey.dst));
+ OvsCopyIphAddress(&fwdInfo.srcIphAddr, &srcAddr);
RtlCopyMemory(fwdInfo.dstMacAddr, ipn->macAddr, ETH_ADDR_LEN);
RtlCopyMemory(fwdInfo.srcMacAddr, instance->internalRow.PhysicalAddress,
ETH_ADDR_LEN);
@@ -1686,6 +1784,7 @@ fwd_request_done:
goto fwd_handle_nbl;
}
newFWD = TRUE;
+
if (status == STATUS_SUCCESS) {
/*
* Cache the result
@@ -1710,10 +1809,8 @@ fwd_handle_nbl:
ASSERT(ipn && ipn->refCount == 0);
OvsFreeMemoryWithTag(ipn, OVS_IPHELPER_POOL_TAG);
}
- ipAddr = request->fwdReq.tunnelKey.dst;
- OVS_LOG_INFO("Fail to handle IP helper request for dst: %d.%d.%d.%d",
- ipAddr & 0xff, (ipAddr >> 8) & 0xff,
- (ipAddr >> 16) & 0xff, (ipAddr >> 24) & 0xff);
+ OvsCopyIphAddress(&iphAddr, &(request->fwdReq.tunnelKey.dst));
+ OvsDumpIpAddrMsg("Fail to handle IP helper request for dst", &iphAddr);
}
if (request->fwdReq.cb) {
request->fwdReq.cb(request->fwdReq.nbl,
@@ -1727,9 +1824,8 @@ fwd_handle_nbl:
OvsFreeMemoryWithTag(request, OVS_IPHELPER_POOL_TAG);
}
-
static VOID
-OvsUpdateIPNeighEntry(UINT32 ipAddr,
+OvsUpdateIPNeighEntry(SOCKADDR_INET ipAddr,
PMIB_IPNET_ROW2 ipNeigh,
NTSTATUS status)
{
@@ -1889,7 +1985,7 @@ OvsStartIpHelper(PVOID data)
* IPN
*/
while (!IsListEmpty(&ovsSortedIPNeighList)) {
- UINT32 ipAddr;
+ SOCKADDR_INET ipAddr;
if (context->exit) {
goto ip_helper_wait;
}
@@ -1901,7 +1997,7 @@ OvsStartIpHelper(PVOID data)
threadSleepTimeout = (PLARGE_INTEGER)&timeout;
break;
}
- ipAddr = ipn->ipAddr;
+ RtlCopyMemory(&ipAddr, &ipn->ipAddr, sizeof(ipAddr));
MIB_IPNET_ROW2 ipNeigh;
NTSTATUS status;
POVS_IPHELPER_INSTANCE instance = ipn->instance;
@@ -2107,3 +2203,55 @@ OvsCancelFwdIpHelperRequest(PNET_BUFFER_LIST nbl)
OvsFreeMemoryWithTag(req, OVS_IPHELPER_POOL_TAG);
}
}
+
+uint32_t
+OvsJhashIphHdr(const SOCKADDR_INET *iphAddr)
+{
+ UINT32 hash = 0;
+
+ if (!iphAddr) return 0;
+
+ if (iphAddr->si_family == AF_INET) {
+ hash = OvsJhashWords((UINT32*)&iphAddr->Ipv4.sin_addr.s_addr,
+ 1, OVS_HASH_BASIS);
+ } else if (iphAddr->si_family == AF_INET6) {
+ hash = OvsJhashWords((UINT32 *)&(iphAddr->Ipv6.sin6_addr.u.Byte),
+ 4, OVS_HASH_BASIS);
+ }
+
+ return hash;
+}
+
+NTSTATUS
+OvsConvertWcharToAnsiStr(WCHAR *wStr, size_t wlen,
+ CHAR* str,
+ size_t maxStrLen)
+{
+ ANSI_STRING astr;
+ UNICODE_STRING ustr;
+ NTSTATUS status;
+ size_t size;
+
+ ustr.Buffer = wStr;
+ ustr.Length = (UINT16)wlen;
+ ustr.MaximumLength = IF_MAX_STRING_SIZE;
+
+ astr.Buffer = str;
+ astr.MaximumLength = (UINT16)maxStrLen;
+ astr.Length = 0;
+
+ size = RtlUnicodeStringToAnsiSize(&ustr);
+ if (size > maxStrLen) {
+ return STATUS_BUFFER_OVERFLOW;
+ }
+
+ status = RtlUnicodeStringToAnsiString(&astr, &ustr, FALSE);
+
+ ASSERT(status == STATUS_SUCCESS);
+ if (status != STATUS_SUCCESS) {
+ return status;
+ }
+ ASSERT(astr.Length <= (UINT16)maxStrLen);
+ str[astr.Length] = 0;
+ return STATUS_SUCCESS;
+}