Added IPv6 support to the IpHelper module. Signed-off-by: Sorin Vinturis <svintu...@cloudbasesolutions.com> --- datapath-windows/ovsext/Actions.c | 32 +-- datapath-windows/ovsext/DpInternal.h | 12 +- datapath-windows/ovsext/Flow.c | 37 ++-- datapath-windows/ovsext/Gre.c | 15 +- datapath-windows/ovsext/IpHelper.c | 382 ++++++++++++++++++----------------- datapath-windows/ovsext/IpHelper.h | 12 +- datapath-windows/ovsext/Stt.c | 16 +- datapath-windows/ovsext/User.c | 6 +- datapath-windows/ovsext/Util.h | 33 +++ datapath-windows/ovsext/Vxlan.c | 21 +- 10 files changed, 323 insertions(+), 243 deletions(-)
diff --git a/datapath-windows/ovsext/Actions.c b/datapath-windows/ovsext/Actions.c index 4edf7d0..909a84a 100644 --- a/datapath-windows/ovsext/Actions.c +++ b/datapath-windows/ovsext/Actions.c @@ -317,12 +317,13 @@ OvsDetectTunnelPkt(OvsForwardingContext *ovsFwdCtx, if (!vport || (vport->ovsType != OVS_VPORT_TYPE_NETDEV && !OvsIsBridgeInternalVport(vport))) { - ovsFwdCtx->tunKey.dst = 0; + RtlZeroMemory(&ovsFwdCtx->tunKey.dst, + sizeof(ovsFwdCtx->tunKey.dst)); } } /* Tunnel the packet only if tunnel context is set. */ - if (ovsFwdCtx->tunKey.dst != 0) { + if (!IsNullIpAddr(&ovsFwdCtx->tunKey.dst)) { switch(dstVport->ovsType) { case OVS_VPORT_TYPE_GRE: ovsActionStats.txGre++; @@ -498,7 +499,8 @@ static __inline VOID OvsClearTunTxCtx(OvsForwardingContext *ovsFwdCtx) { ovsFwdCtx->tunnelTxNic = NULL; - ovsFwdCtx->tunKey.dst = 0; + RtlZeroMemory(&ovsFwdCtx->tunKey.dst, + sizeof(ovsFwdCtx->tunKey.dst)); } @@ -512,7 +514,8 @@ static __inline VOID OvsClearTunRxCtx(OvsForwardingContext *ovsFwdCtx) { ovsFwdCtx->tunnelRxNic = NULL; - ovsFwdCtx->tunKey.dst = 0; + RtlZeroMemory(&ovsFwdCtx->tunKey.dst, + sizeof(ovsFwdCtx->tunKey.dst)); } @@ -574,6 +577,7 @@ OvsDoFlowLookupOutput(OvsForwardingContext *ovsFwdCtx) OvsFlow *flow = NULL; UINT64 hash = 0; NDIS_STATUS status = NDIS_STATUS_SUCCESS; + BOOLEAN isNullDst = IsNullIpAddr(&ovsFwdCtx->tunKey.dst); POVS_VPORT_ENTRY vport = OvsFindVportByPortNo(ovsFwdCtx->switchContext, ovsFwdCtx->srcVportNo); if (vport == NULL || vport->ovsState != OVS_STATE_CONNECTED) { @@ -585,11 +589,11 @@ OvsDoFlowLookupOutput(OvsForwardingContext *ovsFwdCtx) ASSERT(vport->nicState == NdisSwitchNicStateConnected); /* Assert that in the Rx direction, key is always setup. */ - ASSERT(ovsFwdCtx->tunnelRxNic == NULL || ovsFwdCtx->tunKey.dst != 0); + ASSERT(ovsFwdCtx->tunnelRxNic == NULL || !isNullDst); status = OvsExtractFlow(ovsFwdCtx->curNbl, ovsFwdCtx->srcVportNo, &key, &ovsFwdCtx->layers, - ovsFwdCtx->tunKey.dst != 0 ? &ovsFwdCtx->tunKey : NULL); + isNullDst ? NULL : &ovsFwdCtx->tunKey); if (status != NDIS_STATUS_SUCCESS) { OvsCompleteNBLForwardingCtx(ovsFwdCtx, L"OVS-Flow extract failed"); @@ -902,11 +906,11 @@ OvsOutputForwardingCtx(OvsForwardingContext *ovsFwdCtx) if (ovsFwdCtx->tunnelTxNic != NULL) { status = OvsTunnelPortTx(ovsFwdCtx); ASSERT(ovsFwdCtx->tunnelTxNic == NULL); - ASSERT(ovsFwdCtx->tunKey.dst == 0); + ASSERT(IsNullIpAddr(&ovsFwdCtx->tunKey.dst)); } else if (ovsFwdCtx->tunnelRxNic != NULL) { status = OvsTunnelPortRx(ovsFwdCtx); ASSERT(ovsFwdCtx->tunnelRxNic == NULL); - ASSERT(ovsFwdCtx->tunKey.dst == 0); + ASSERT(IsNullIpAddr(&ovsFwdCtx->tunKey.dst)); } ASSERT(ovsFwdCtx->curNbl == NULL); @@ -1245,10 +1249,10 @@ OvsTunnelAttrToIPv4TunnelKey(PNL_ATTR attr, PNL_ATTR a; INT rem; - tunKey->attr[0] = 0; - tunKey->attr[1] = 0; - tunKey->attr[2] = 0; ASSERT(NlAttrType(attr) == OVS_KEY_ATTR_TUNNEL); + for (UINT32 i = 0; i < sizeof(*tunKey) / sizeof(UINT64); i++) { + tunKey->attr[i] = 0; + } NL_ATTR_FOR_EACH_UNSAFE (a, rem, NlAttrData(attr), NlAttrGetSize(attr)) { @@ -1258,10 +1262,12 @@ OvsTunnelAttrToIPv4TunnelKey(PNL_ATTR attr, tunKey->flags |= OVS_TNL_F_KEY; break; case OVS_TUNNEL_KEY_ATTR_IPV4_SRC: - tunKey->src = NlAttrGetBe32(a); + tunKey->src.Ipv4.sin_addr.s_addr = NlAttrGetBe32(a); + tunKey->src.si_family = AF_INET; break; case OVS_TUNNEL_KEY_ATTR_IPV4_DST: - tunKey->dst = NlAttrGetBe32(a); + tunKey->dst.Ipv4.sin_addr.s_addr = NlAttrGetBe32(a); + tunKey->dst.si_family = AF_INET; break; case OVS_TUNNEL_KEY_ATTR_TOS: tunKey->tos = NlAttrGetU8(a); diff --git a/datapath-windows/ovsext/DpInternal.h b/datapath-windows/ovsext/DpInternal.h index 07bc180..526efe6 100644 --- a/datapath-windows/ovsext/DpInternal.h +++ b/datapath-windows/ovsext/DpInternal.h @@ -128,12 +128,12 @@ typedef struct L2Key { } L2Key; /* Size of 24 byte. */ /* Number of packet attributes required to store OVS tunnel key. */ -#define NUM_PKT_ATTR_REQUIRED 3 +#define NUM_PKT_ATTR_REQUIRED 9 typedef union OvsIPv4TunnelKey { struct { - ovs_be32 dst; - ovs_be32 src; + SOCKADDR_INET dst; + SOCKADDR_INET src; ovs_be64 tunnelId; uint16_t flags; uint8_t tos; @@ -147,7 +147,7 @@ typedef union OvsIPv4TunnelKey { }; }; uint64_t attr[NUM_PKT_ATTR_REQUIRED]; -} OvsIPv4TunnelKey; /* Size of 24 byte. */ +} OvsIPv4TunnelKey; /* Size of 72 byte. */ typedef struct MplsKey { ovs_be32 lse; /* MPLS topmost label stack entry. */ @@ -155,7 +155,7 @@ typedef struct MplsKey { } MplsKey; /* Size of 8 bytes. */ typedef __declspec(align(8)) struct OvsFlowKey { - OvsIPv4TunnelKey tunKey; /* 24 bytes */ + OvsIPv4TunnelKey tunKey; /* 72 bytes */ L2Key l2; /* 24 bytes */ union { /* These headers are mutually exclusive. */ @@ -254,7 +254,7 @@ typedef struct OvsFlowPut { PNL_ATTR actions; } OvsFlowPut; -#define OVS_MIN_PACKET_SIZE 60 +#define OVS_MIN_PACKET_SIZE 108 typedef struct _OVS_PACKET_INFO { uint32_t totalLen; uint32_t userDataLen; diff --git a/datapath-windows/ovsext/Flow.c b/datapath-windows/ovsext/Flow.c index c2e0227..c40da8a 100644 --- a/datapath-windows/ovsext/Flow.c +++ b/datapath-windows/ovsext/Flow.c @@ -964,7 +964,7 @@ MapFlowKeyToNlKey(PNL_BUFFER nlBuf, goto done; } - if (flowKey->tunKey.dst) { + if (!IsNullIpAddr(&flowKey->tunKey.dst)) { rc = MapFlowTunKeyToNlKey(nlBuf, &(flowKey->tunKey), tunKeyType); if (rc != STATUS_SUCCESS) { @@ -1006,13 +1006,13 @@ MapFlowTunKeyToNlKey(PNL_BUFFER nlBuf, } if (!NlMsgPutTailU32(nlBuf, OVS_TUNNEL_KEY_ATTR_IPV4_DST, - tunKey->dst)) { + tunKey->dst.Ipv4.sin_addr.s_addr)) { rc = STATUS_UNSUCCESSFUL; goto done; } if (!NlMsgPutTailU32(nlBuf, OVS_TUNNEL_KEY_ATTR_IPV4_SRC, - tunKey->src)) { + tunKey->src.Ipv4.sin_addr.s_addr)) { rc = STATUS_UNSUCCESSFUL; goto done; } @@ -1653,13 +1653,15 @@ MapTunAttrToFlowPut(PNL_ATTR *keyAttrs, } if (tunAttrs[OVS_TUNNEL_KEY_ATTR_IPV4_DST]) { - destKey->tunKey.dst = NlAttrGetU32 - (tunAttrs[OVS_TUNNEL_KEY_ATTR_IPV4_DST]); + destKey->tunKey.dst.si_family = AF_INET; + destKey->tunKey.dst.Ipv4.sin_addr.s_addr = + NlAttrGetU32(tunAttrs[OVS_TUNNEL_KEY_ATTR_IPV4_DST]); } if (tunAttrs[OVS_TUNNEL_KEY_ATTR_IPV4_SRC]) { - destKey->tunKey.src = NlAttrGetU32 - (tunAttrs[OVS_TUNNEL_KEY_ATTR_IPV4_SRC]); + destKey->tunKey.src.si_family = AF_INET; + destKey->tunKey.src.Ipv4.sin_addr.s_addr = + NlAttrGetU32(tunAttrs[OVS_TUNNEL_KEY_ATTR_IPV4_SRC]); } if (tunAttrs[OVS_TUNNEL_KEY_ATTR_DONT_FRAGMENT]) { @@ -1683,9 +1685,9 @@ MapTunAttrToFlowPut(PNL_ATTR *keyAttrs, destKey->tunKey.pad = 0; destKey->l2.offset = 0; } else { - destKey->tunKey.attr[0] = 0; - destKey->tunKey.attr[1] = 0; - destKey->tunKey.attr[2] = 0; + for (UINT32 i = 0; i < sizeof(destKey->tunKey) / sizeof(UINT64); i++) { + destKey->tunKey.attr[i] = 0; + } destKey->l2.offset = sizeof destKey->tunKey; } } @@ -1887,11 +1889,12 @@ OvsExtractFlow(const NET_BUFFER_LIST *packet, layers->value = 0; if (tunKey) { - ASSERT(tunKey->dst != 0); + ASSERT(!IsNullIpAddr(&tunKey->dst)); RtlMoveMemory(&flow->tunKey, tunKey, sizeof flow->tunKey); flow->l2.offset = 0; } else { - flow->tunKey.dst = 0; + RtlZeroMemory(&flow->tunKey.dst, + sizeof(flow->tunKey.dst)); flow->l2.offset = OVS_WIN_TUNNEL_KEY_SIZE; } @@ -2220,9 +2223,10 @@ OvsLookupFlow(OVS_DATAPATH *datapath, UINT16 offset = key->l2.offset; UINT16 size = key->l2.keyLen; UINT8 *start; + BOOLEAN isNullDst = IsNullIpAddr(&key->tunKey.dst); - ASSERT(key->tunKey.dst || offset == sizeof (OvsIPv4TunnelKey)); - ASSERT(!key->tunKey.dst || offset == 0); + ASSERT(!isNullDst || offset == sizeof(OvsIPv4TunnelKey)); + ASSERT(isNullDst || offset == 0); start = (UINT8 *)key + offset; @@ -2277,9 +2281,10 @@ OvsHashFlow(const OvsFlowKey *key) UINT16 offset = key->l2.offset; UINT16 size = key->l2.keyLen; UINT8 *start; + BOOLEAN isNullDst = IsNullIpAddr(&key->tunKey.dst); - ASSERT(key->tunKey.dst || offset == sizeof (OvsIPv4TunnelKey)); - ASSERT(!key->tunKey.dst || offset == 0); + ASSERT(!isNullDst || offset == sizeof(OvsIPv4TunnelKey)); + ASSERT(isNullDst || offset == 0); start = (UINT8 *)key + offset; return OvsJhashBytes(start, size, 0); } diff --git a/datapath-windows/ovsext/Gre.c b/datapath-windows/ovsext/Gre.c index cb41593..1cc4e69 100644 --- a/datapath-windows/ovsext/Gre.c +++ b/datapath-windows/ovsext/Gre.c @@ -236,10 +236,11 @@ OvsDoEncapGre(POVS_VPORT_ENTRY vport, IP_DF_NBO : 0; ipHdr->ttl = tunKey->ttl ? tunKey->ttl : 64; ipHdr->protocol = IPPROTO_GRE; - ASSERT(tunKey->dst == fwdInfo->dstIpAddr); - ASSERT(tunKey->src == fwdInfo->srcIpAddr || tunKey->src == 0); - ipHdr->saddr = fwdInfo->srcIpAddr; - ipHdr->daddr = fwdInfo->dstIpAddr; + ASSERT(IsEqualIpAddr(&tunKey->dst, &fwdInfo->dstIpAddr)); + ASSERT(IsEqualIpAddr(&tunKey->src, &fwdInfo->srcIpAddr) || + IsNullIpAddr(&tunKey->src)); + ipHdr->saddr = fwdInfo->srcIpAddr.Ipv4.sin_addr.s_addr; + ipHdr->daddr = fwdInfo->dstIpAddr.Ipv4.sin_addr.s_addr; ipHdr->check = 0; ipHdr->check = IPChecksum((UINT8 *)ipHdr, sizeof *ipHdr, 0); @@ -336,8 +337,10 @@ OvsDecapGre(POVS_SWITCH_CONTEXT switchContext, headRoom += sizeof *ethHdr; ipHdr = (IPHdr *)((PCHAR)ethHdr + sizeof *ethHdr); - tunKey->src = ipHdr->saddr; - tunKey->dst = ipHdr->daddr; + tunKey->src.Ipv4.sin_addr.s_addr = ipHdr->saddr; + tunKey->src.Ipv4.sin_family = AF_INET; + tunKey->dst.Ipv4.sin_addr.s_addr = ipHdr->daddr; + tunKey->dst.Ipv4.sin_family = AF_INET; tunKey->tos = ipHdr->tos; tunKey->ttl = ipHdr->ttl; tunKey->pad = 0; diff --git a/datapath-windows/ovsext/IpHelper.c b/datapath-windows/ovsext/IpHelper.c index d747e8c..b919084 100644 --- a/datapath-windows/ovsext/IpHelper.c +++ b/datapath-windows/ovsext/IpHelper.c @@ -46,7 +46,7 @@ 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; +static SOCKADDR_INET ovsInternalIP; /* @@ -81,11 +81,53 @@ 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 OvsCleanupIpHelperRequestList(VOID); static VOID OvsCleanupFwdTable(VOID); static VOID OvsAddToSortedNeighList(POVS_IPNEIGH_ENTRY ipn); +static __inline VOID +OvsDumpIpAddrMsg(CHAR *msg, + const SOCKADDR_INET *ipAddress) +{ + if (ipAddress->si_family == AF_INET) { + UINT32 ipv4Addr = ipAddress->Ipv4.sin_addr.s_addr; + OVS_LOG_INFO("%s: %d.%d.%d.%d", msg, + ipv4Addr & 0xff, (ipv4Addr >> 8) & 0xff, + (ipv4Addr >> 16) & 0xff, (ipv4Addr >> 24) & 0xff); + } else { + const UCHAR* ipv6Addr = ipAddress->Ipv6.sin6_addr.u.Byte; + OVS_LOG_INFO("%s: %02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x" + ":%02x%02x:%02x%02x", msg, + ipv6Addr[0], ipv6Addr[1], ipv6Addr[2], ipv6Addr[3], + ipv6Addr[4], ipv6Addr[5], ipv6Addr[6], ipv6Addr[7], + ipv6Addr[8], ipv6Addr[9], ipv6Addr[10], ipv6Addr[11], + ipv6Addr[12], ipv6Addr[13], ipv6Addr[14], ipv6Addr[15]); + } +} + +static __inline VOID +OvsDumpIpAddrMsgStatus(CHAR *msg, + const SOCKADDR_INET *ipAddress, + NTSTATUS status) +{ + if (ipAddress->si_family == AF_INET) { + UINT32 ipv4Addr = ipAddress->Ipv4.sin_addr.s_addr; + OVS_LOG_INFO("%s: %d.%d.%d.%d, status: %x", msg, + ipv4Addr & 0xff, (ipv4Addr >> 8) & 0xff, + (ipv4Addr >> 16) & 0xff, (ipv4Addr >> 24) & 0xff, status); + } else { + const UCHAR* ipv6Addr = ipAddress->Ipv6.sin6_addr.u.Byte; + OVS_LOG_INFO("%s: %02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x" + ":%02x%02x:%02x%02x, status: %x", msg, + ipv6Addr[0], ipv6Addr[1], ipv6Addr[2], ipv6Addr[3], + ipv6Addr[4], ipv6Addr[5], ipv6Addr[6], ipv6Addr[7], + ipv6Addr[8], ipv6Addr[9], ipv6Addr[10], ipv6Addr[11], + ipv6Addr[12], ipv6Addr[13], ipv6Addr[14], ipv6Addr[15], + status); + } +} + static VOID OvsDumpIfRow(PMIB_IF_ROW2 ifRow) { @@ -206,20 +248,13 @@ OvsGetIPInterfaceEntry(NET_LUID luid, 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); + OvsDumpIpAddrMsg("Unicast Address: ", &ipRow->Address); } @@ -264,21 +299,9 @@ OvsGetIPEntry(NET_LUID interfaceLuid, static VOID OvsDumpIPPath(PMIB_IPPATH_ROW ipPath) { - UINT32 ipAddr = ipPath->Source.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 = ipPath->Destination.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 = ipPath->CurrentNextHop.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("Source: ", &ipPath->Source); + OvsDumpIpAddrMsg("Destination: ", &ipPath->Destination); + OvsDumpIpAddrMsg("NextHop: ", &ipPath->CurrentNextHop); } @@ -286,14 +309,11 @@ NTSTATUS OvsGetIPPathEntry(PMIB_IPPATH_ROW ipPath) { NTSTATUS status; - UINT32 ipAddr = ipPath->Destination.Ipv4.sin_addr.s_addr; status = GetIpPathEntry(ipPath); - if (status != STATUS_SUCCESS) { - OVS_LOG_INFO("Fail to get IP path to %d.%d.%d.%d, status:%x", - ipAddr & 0xff, (ipAddr >> 8) & 0xff, - (ipAddr >> 16) & 0xff, (ipAddr >> 24) & 0xff, status); + OvsDumpIpAddrMsgStatus("Fail to get IP path to: ", + &ipPath->Destination, status); return status; } OvsDumpIPPath(ipPath); @@ -306,21 +326,9 @@ 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); } @@ -341,10 +349,8 @@ OvsGetRoute(NET_LUID interfaceLuid, 0, route, sourceAddress); 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); + OvsDumpIpAddrMsgStatus("Fail to get route to: ", + destinationAddress, status); return status; } @@ -355,11 +361,8 @@ OvsGetRoute(NET_LUID interfaceLuid, static VOID OvsDumpIPNeigh(PMIB_IPNET_ROW2 ipNeigh) { - UINT32 ipAddr = ipNeigh->Address.Ipv4.sin_addr.s_addr; + OvsDumpIpAddrMsg("Neigh: ", &ipNeigh->Address); - OVS_LOG_INFO("Neigh: %d.%d.%d.%d", - 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], @@ -380,10 +383,8 @@ 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); + OvsDumpIpAddrMsgStatus("Fail to get ARP entry: ", + &ipNeigh->Address, status); return status; } if (ipNeigh->State == NlnsReachable || @@ -404,10 +405,8 @@ 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 resolve ARP entry: ", + &ipNeigh->Address, status); return status; } @@ -421,7 +420,7 @@ OvsResolveIPNeighEntry(PMIB_IPNET_ROW2 ipNeigh) NTSTATUS -OvsGetOrResolveIPNeigh(UINT32 ipAddr, +OvsGetOrResolveIPNeigh(SOCKADDR_INET ipAddr, PMIB_IPNET_ROW2 ipNeigh) { NTSTATUS status; @@ -431,8 +430,7 @@ OvsGetOrResolveIPNeigh(UINT32 ipAddr, RtlZeroMemory(ipNeigh, sizeof (*ipNeigh)); ipNeigh->InterfaceLuid.Value = ovsInternalRow.InterfaceLuid.Value; ipNeigh->InterfaceIndex = ovsInternalRow.InterfaceIndex; - ipNeigh->Address.si_family = AF_INET; - ipNeigh->Address.Ipv4.sin_addr.s_addr = ipAddr; + ipNeigh->Address = ipAddr; status = OvsGetIPNeighEntry(ipNeigh); @@ -440,8 +438,7 @@ OvsGetOrResolveIPNeigh(UINT32 ipAddr, RtlZeroMemory(ipNeigh, sizeof (*ipNeigh)); ipNeigh->InterfaceLuid.Value = ovsInternalRow.InterfaceLuid.Value; ipNeigh->InterfaceIndex = ovsInternalRow.InterfaceIndex; - ipNeigh->Address.si_family = AF_INET; - ipNeigh->Address.Ipv4.sin_addr.s_addr = ipAddr; + ipNeigh->Address = ipAddr; status = OvsResolveIPNeighEntry(ipNeigh); } return status; @@ -514,33 +511,46 @@ OvsChangeCallbackIpRoute(PVOID context, 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); - break; - - case MibParameterNotification: case MibDeleteInstance: + case MibParameterNotification: 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"); + + if (ipRoute->NextHop.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 == MibAddInstance) ? "added" : + (notificationType == MibDeleteInstance) ? "deleted" : + "modified"); + } else { + UCHAR* ipAddr = + ipRoute->DestinationPrefix.Prefix.Ipv6.sin6_addr.u.Byte; + UCHAR* nextHop = + ipRoute->NextHop.Ipv6.sin6_addr.u.Byte; + OVS_LOG_INFO( + "IPRoute: To %02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x\ + through %02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x %s.", + ipAddr[0], ipAddr[1], ipAddr[2], ipAddr[3], ipAddr[4], + ipAddr[5], ipAddr[6], ipAddr[7], ipAddr[8], ipAddr[9], + ipAddr[10], ipAddr[11], ipAddr[12], ipAddr[13], ipAddr[14], + ipAddr[15], nextHop[0], nextHop[1], nextHop[2], nextHop[3], + nextHop[4], nextHop[5], nextHop[6], nextHop[7], nextHop[8], + nextHop[9], nextHop[10], nextHop[11], nextHop[12], nextHop[13], + nextHop[14], nextHop[15], + (notificationType == MibAddInstance) ? "added" : + (notificationType == MibDeleteInstance) ? "deleted" : + "modified"); + } + + if (notificationType == MibAddInstance) { + break; + } if (ipRoute->InterfaceLuid.Info.NetLuidIndex == ovsInternalRow.InterfaceLuid.Info.NetLuidIndex && @@ -573,33 +583,25 @@ OvsChangeCallbackUnicastIpAddress(PVOID context, PMIB_UNICASTIPADDRESS_ROW unicastRow, MIB_NOTIFICATION_TYPE notificationType) { - UINT32 ipAddr; - UNREFERENCED_PARAMETER(context); switch (notificationType) { case MibParameterNotification: case MibAddInstance: 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; + ovsInternalIP = unicastRow->Address; } - 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"); + OvsDumpIpAddrMsg(notificationType == MibAddInstance ? + "IP Address added:" : "IP Address modified:", + &unicastRow->Address); break; case MibDeleteInstance: 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 == @@ -608,10 +610,11 @@ OvsChangeCallbackUnicastIpAddress(PVOID context, LOCK_STATE_EX lockState; NdisAcquireRWLockWrite(ovsTableLock, &lockState, 0); - OvsRemoveAllFwdEntriesWithSrc(ipAddr); + OvsRemoveAllFwdEntriesWithSrc(unicastRow->Address); NdisReleaseRWLock(ovsTableLock, &lockState); } + OvsDumpIpAddrMsg("IP Address removed:", &unicastRow->Address); break; case MibInitialNotification: @@ -646,28 +649,28 @@ OvsRegisterChangeNotification() NTSTATUS status; - status = NotifyIpInterfaceChange(AF_INET, OvsChangeCallbackIpInterface, + status = NotifyIpInterfaceChange(AF_UNSPEC, OvsChangeCallbackIpInterface, NULL, TRUE, &ipInterfaceNotificationHandle); if (status != STATUS_SUCCESS) { OVS_LOG_ERROR("Fail to register Notify IP interface change, status:%x.", - status); + status); return status; } - status = NotifyRouteChange2(AF_INET, OvsChangeCallbackIpRoute, NULL, + status = NotifyRouteChange2(AF_UNSPEC, OvsChangeCallbackIpRoute, NULL, TRUE, &ipRouteNotificationHandle); if (status != STATUS_SUCCESS) { - OVS_LOG_ERROR("Fail to regiter ip route change, status: %x.", - status); + OVS_LOG_ERROR("Fail to register ip route change, status: %x.", + status); goto register_cleanup; } - status = NotifyUnicastIpAddressChange(AF_INET, + status = NotifyUnicastIpAddressChange(AF_UNSPEC, OvsChangeCallbackUnicastIpAddress, NULL, TRUE, &unicastIPNotificationHandle); if (status != STATUS_SUCCESS) { - OVS_LOG_ERROR("Fail to regiter unicast ip change, status: %x.", status); + OVS_LOG_ERROR("Fail to register unicast ip change, status: %x.", status); } register_cleanup: if (status != STATUS_SUCCESS) { @@ -678,16 +681,54 @@ register_cleanup: } +static UINT32 +OvsHashIPPrefix(PIP_ADDRESS_PREFIX prefix) +{ + UINT32 hash; + + 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 { // 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 UINT32 +OvsHashIPAddr(SOCKADDR_INET *ipAddr) +{ + UINT32 hash; + + if (ipAddr->si_family == AF_INET) { + hash = OvsJhashWords((UINT32*)&ipAddr->Ipv4.sin_addr.s_addr, + 1, OVS_HASH_BASIS); + } else { // ipAddr->si_family == AF_INET6 + hash = OvsJhashWords((UINT32*)ipAddr->Ipv6.sin6_addr.u.Byte, + 4, OVS_HASH_BASIS); + } + + return hash; +} + + static POVS_IPNEIGH_ENTRY -OvsLookupIPNeighEntry(UINT32 ipAddr) +OvsLookupIPNeighEntry(SOCKADDR_INET ipAddr) { PLIST_ENTRY link; POVS_IPNEIGH_ENTRY entry; - UINT32 hash = OvsJhashWords(&ipAddr, 1, OVS_HASH_BASIS); + UINT32 hash = OvsHashIPAddr(&ipAddr); LIST_FORALL(&ovsNeighHashTable[hash & OVS_NEIGH_HASH_TABLE_MASK], link) { entry = CONTAINING_RECORD(link, OVS_IPNEIGH_ENTRY, link); - if (entry->ipAddr == ipAddr) { + if (IsEqualIpAddr(&entry->ipAddr, &ipAddr)) { return entry; } } @@ -695,15 +736,6 @@ OvsLookupIPNeighEntry(UINT32 ipAddr) } -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); -} - - static POVS_IPFORWARD_ENTRY OvsLookupIPForwardEntry(PIP_ADDRESS_PREFIX prefix) { @@ -711,19 +743,12 @@ OvsLookupIPForwardEntry(PIP_ADDRESS_PREFIX prefix) PLIST_ENTRY link; POVS_IPFORWARD_ENTRY ipfEntry; 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) { 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) { + IsEqualIpAddr(&ipfEntry->prefix.Prefix, &prefix->Prefix)) { return ipfEntry; } } @@ -732,15 +757,15 @@ OvsLookupIPForwardEntry(PIP_ADDRESS_PREFIX prefix) static POVS_FWD_ENTRY -OvsLookupIPFwdEntry(UINT32 dstIp) +OvsLookupIPFwdEntry(SOCKADDR_INET dstAddr) { PLIST_ENTRY link; POVS_FWD_ENTRY entry; - UINT32 hash = OvsJhashWords(&dstIp, 1, OVS_HASH_BASIS); + UINT32 hash = OvsHashIPAddr(&dstAddr); LIST_FORALL(&ovsFwdHashTable[hash & OVS_FWD_HASH_TABLE_MASK], link) { entry = CONTAINING_RECORD(link, OVS_FWD_ENTRY, link); - if (entry->info.dstIpAddr == dstIp) { + if (IsEqualIpAddr(&entry->info.dstIpAddr, &dstAddr)) { return entry; } } @@ -749,7 +774,7 @@ OvsLookupIPFwdEntry(UINT32 dstIp) NTSTATUS -OvsLookupIPFwdInfo(UINT32 dstIp, +OvsLookupIPFwdInfo(SOCKADDR_INET dstAddr, POVS_FWD_INFO info) { POVS_FWD_ENTRY entry; @@ -757,11 +782,11 @@ OvsLookupIPFwdInfo(UINT32 dstIp, NTSTATUS status = STATUS_NOT_FOUND; NdisAcquireRWLockRead(ovsTableLock, &lockState, 0); - entry = OvsLookupIPFwdEntry(dstIp); + entry = OvsLookupIPFwdEntry(dstAddr); if (entry) { - info->value[0] = entry->info.value[0]; - info->value[1] = entry->info.value[1]; - info->value[2] = entry->info.value[2]; + for (UINT32 i = 0; i < sizeof(*info) / sizeof(UINT64); i++) { + info->value[i] = entry->info.value[i]; + } status = STATUS_SUCCESS; } NdisReleaseRWLock(ovsTableLock, &lockState); @@ -772,19 +797,19 @@ OvsLookupIPFwdInfo(UINT32 dstIp, static POVS_IPNEIGH_ENTRY OvsCreateIPNeighEntry(PMIB_IPNET_ROW2 ipNeigh) { - POVS_IPNEIGH_ENTRY entry; UINT64 timeVal; ASSERT(ipNeigh != NULL); - entry = (POVS_IPNEIGH_ENTRY)OvsAllocateMemoryWithTag( - sizeof(OVS_IPNEIGH_ENTRY), OVS_IPHELPER_POOL_TAG); + entry = (POVS_IPNEIGH_ENTRY) + OvsAllocateMemoryWithTag(sizeof(OVS_IPNEIGH_ENTRY), + OVS_IPHELPER_POOL_TAG); if (entry == NULL) { return NULL; } RtlZeroMemory(entry, sizeof (OVS_IPNEIGH_ENTRY)); - entry->ipAddr = ipNeigh->Address.Ipv4.sin_addr.s_addr; + entry->ipAddr = ipNeigh->Address; KeQuerySystemTime((LARGE_INTEGER *)&timeVal); entry->timeout = timeVal + OVS_IPNEIGH_TIMEOUT; RtlCopyMemory(entry->macAddr, ipNeigh->PhysicalAddress, @@ -798,13 +823,12 @@ OvsCreateIPNeighEntry(PMIB_IPNET_ROW2 ipNeigh) static POVS_IPFORWARD_ENTRY OvsCreateIPForwardEntry(PMIB_IPFORWARD_ROW2 ipRoute) { - POVS_IPFORWARD_ENTRY entry; ASSERT(ipRoute); - - entry = (POVS_IPFORWARD_ENTRY)OvsAllocateMemoryWithTag( - sizeof(OVS_IPFORWARD_ENTRY), OVS_IPHELPER_POOL_TAG); + entry = (POVS_IPFORWARD_ENTRY) + OvsAllocateMemoryWithTag(sizeof(OVS_IPFORWARD_ENTRY), + OVS_IPHELPER_POOL_TAG); if (entry == NULL) { return NULL; } @@ -812,7 +836,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; + entry->nextHop = ipRoute->NextHop; InitializeListHead(&entry->fwdList); return entry; @@ -824,14 +848,16 @@ OvsCreateFwdEntry(POVS_FWD_INFO fwdInfo) { POVS_FWD_ENTRY entry; - entry = (POVS_FWD_ENTRY)OvsAllocateMemoryWithTag( - sizeof(OVS_FWD_ENTRY), OVS_IPHELPER_POOL_TAG); + entry = (POVS_FWD_ENTRY) + OvsAllocateMemoryWithTag(sizeof(OVS_FWD_ENTRY), + OVS_IPHELPER_POOL_TAG); if (entry == NULL) { return NULL; } RtlZeroMemory(entry, sizeof (OVS_FWD_ENTRY)); RtlCopyMemory(&entry->info, fwdInfo, sizeof (OVS_FWD_INFO)); + return entry; } @@ -944,7 +970,8 @@ OvsAddIPFwdCache(POVS_FWD_ENTRY fwdEntry, NdisAcquireSpinLock(&ovsIpHelperLock); OvsAddToSortedNeighList(ipn); NdisReleaseSpinLock(&ovsIpHelperLock); - hash = OvsJhashWords(&ipn->ipAddr, 1, OVS_HASH_BASIS); + + hash = OvsHashIPAddr(&ipn->ipAddr); InsertHeadList(&ovsNeighHashTable[hash & OVS_NEIGH_HASH_TABLE_MASK], &ipn->link); } @@ -962,7 +989,7 @@ OvsAddIPFwdCache(POVS_FWD_ENTRY fwdEntry, ipn->refCount++; fwdEntry->ipn = ipn; - hash = OvsJhashWords(&fwdEntry->info.dstIpAddr, 1, OVS_HASH_BASIS); + hash = OvsHashIPAddr(&fwdEntry->info.dstIpAddr); InsertHeadList(&ovsFwdHashTable[hash & OVS_FWD_HASH_TABLE_MASK], &fwdEntry->link); ovsNumFwdEntries++; @@ -970,7 +997,7 @@ OvsAddIPFwdCache(POVS_FWD_ENTRY fwdEntry, static VOID -OvsRemoveAllFwdEntriesWithSrc(UINT32 ipAddr) +OvsRemoveAllFwdEntriesWithSrc(SOCKADDR_INET ipAddr) { UINT32 i; POVS_FWD_ENTRY fwdEntry; @@ -979,7 +1006,7 @@ OvsRemoveAllFwdEntriesWithSrc(UINT32 ipAddr) for (i = 0; i < OVS_FWD_HASH_TABLE_SIZE; i++) { LIST_FORALL_SAFE(&ovsFwdHashTable[i], link, next) { fwdEntry = CONTAINING_RECORD(link, OVS_FWD_ENTRY, link); - if (fwdEntry->info.srcIpAddr == ipAddr) { + if (IsEqualIpAddr(&fwdEntry->info.srcIpAddr, &ipAddr)) { OvsRemoveFwdEntry(fwdEntry); } } @@ -1109,7 +1136,7 @@ OvsHandleInternalAdapterUp(POVS_IP_HELPER_REQUEST request) status = OvsGetIfEntry(&ovsInternalNetCfgId, &ovsInternalRow); if (status != STATUS_SUCCESS) { - OVS_LOG_ERROR("Fali to get IF entry for internal port with GUID" + OVS_LOG_ERROR("Fail to get IF entry for internal port with GUID" " %08x-%04x-%04x-%04x-%02x%02x%02x%02x%02x%02x", netCfgInstanceId->Data1, netCfgInstanceId->Data2, @@ -1137,7 +1164,7 @@ OvsHandleInternalAdapterUp(POVS_IP_HELPER_REQUEST request) status = OvsGetIPEntry(ovsInternalRow.InterfaceLuid, &ipEntry); if (status != STATUS_SUCCESS) { - OVS_LOG_INFO("Fali to get IP entry for internal port with GUID" + OVS_LOG_INFO("Fail to get IP entry for internal port with GUID" " %08x-%04x-%04x-%04x-%02x%02x%02x%02x%02x%02x", netCfgInstanceId->Data1, netCfgInstanceId->Data2, @@ -1208,13 +1235,12 @@ OvsFwdIPHelperRequest(PNET_BUFFER_LIST nbl, static VOID OvsHandleFwdRequest(POVS_IP_HELPER_REQUEST request) { - SOCKADDR_INET dst, src; - NTSTATUS status; + NTSTATUS status = STATUS_SUCCESS; MIB_IPFORWARD_ROW2 ipRoute; MIB_IPNET_ROW2 ipNeigh; OVS_FWD_INFO fwdInfo; - UINT32 ipAddr; - UINT32 srcAddr; + SOCKADDR_INET srcAddr; + SOCKADDR_INET ipAddr; POVS_FWD_ENTRY fwdEntry = NULL; POVS_IPFORWARD_ENTRY ipf = NULL; POVS_IPNEIGH_ENTRY ipn = NULL; @@ -1230,33 +1256,31 @@ OvsHandleFwdRequest(POVS_IP_HELPER_REQUEST request) } /* find IPRoute */ - RtlZeroMemory(&dst, sizeof(dst)); - RtlZeroMemory(&src, sizeof(src)); + RtlZeroMemory(&srcAddr, sizeof(srcAddr)); RtlZeroMemory(&ipRoute, sizeof (MIB_IPFORWARD_ROW2)); - dst.si_family = AF_INET; - dst.Ipv4.sin_addr.s_addr = request->fwdReq.tunnelKey.dst; + RtlZeroMemory(&ipNeigh, sizeof (ipNeigh)); - status = OvsGetRoute(ovsInternalRow.InterfaceLuid, &dst, &ipRoute, &src); + status = OvsGetRoute(ovsInternalRow.InterfaceLuid, + &request->fwdReq.tunnelKey.dst, + &ipRoute, &srcAddr); if (status != STATUS_SUCCESS) { goto fwd_handle_nbl; } - srcAddr = src.Ipv4.sin_addr.s_addr; + ipNeigh.InterfaceLuid.Value = ovsInternalRow.InterfaceLuid.Value; /* find IPNeigh */ - ipAddr = ipRoute.NextHop.Ipv4.sin_addr.s_addr; - if (ipAddr != 0) { + ipAddr = ipRoute.NextHop; + if (!IsNullIpAddr(&ipAddr)) { NdisAcquireRWLockWrite(ovsTableLock, &lockState, 0); ipn = OvsLookupIPNeighEntry(ipAddr); if (ipn) { goto fwd_request_done; } NdisReleaseRWLock(ovsTableLock, &lockState); - } - RtlZeroMemory(&ipNeigh, sizeof (ipNeigh)); - ipNeigh.InterfaceLuid.Value = ovsInternalRow.InterfaceLuid.Value; - if (ipAddr == 0) { + } else { ipAddr = request->fwdReq.tunnelKey.dst; } + status = OvsGetOrResolveIPNeigh(ipAddr, &ipNeigh); if (status != STATUS_SUCCESS) { goto fwd_handle_nbl; @@ -1339,10 +1363,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); + OvsDumpIpAddrMsg("Fail to handle IP helper request for dst: ", + &request->fwdReq.tunnelKey.dst); } if (request->fwdReq.cb) { request->fwdReq.cb(request->fwdReq.nbl, @@ -1358,7 +1380,7 @@ fwd_handle_nbl: static VOID -OvsUpdateIPNeighEntry(UINT32 ipAddr, +OvsUpdateIPNeighEntry(SOCKADDR_INET ipAddr, PMIB_IPNET_ROW2 ipNeigh, NTSTATUS status) { @@ -1425,7 +1447,7 @@ OvsUpdateIPNeighEntry(UINT32 ipAddr, static VOID -OvsHandleIPNeighTimeout(UINT32 ipAddr) +OvsHandleIPNeighTimeout(SOCKADDR_INET ipAddr) { MIB_IPNET_ROW2 ipNeigh; NTSTATUS status; @@ -1488,7 +1510,7 @@ OvsStartIpHelper(PVOID data) * IPN */ while (!IsListEmpty(&ovsSortedIPNeighList)) { - UINT32 ipAddr; + SOCKADDR_INET ipAddr; if (context->exit) { goto ip_helper_wait; } @@ -1551,7 +1573,7 @@ OvsInitIpHelper(NDIS_HANDLE ndisFilterHandle) RtlZeroMemory(&ovsInternalRow, sizeof(MIB_IF_ROW2)); RtlZeroMemory(&ovsInternalIPRow, sizeof (MIB_IPINTERFACE_ROW)); - ovsInternalIP = 0; + RtlZeroMemory(&ovsInternalIP, sizeof(SOCKADDR_INET)); ovsInternalAdapterUp = FALSE; diff --git a/datapath-windows/ovsext/IpHelper.h b/datapath-windows/ovsext/IpHelper.h index 8562f86..5a685c3 100644 --- a/datapath-windows/ovsext/IpHelper.h +++ b/datapath-windows/ovsext/IpHelper.h @@ -35,7 +35,7 @@ typedef struct _OVS_IPNEIGH_ENTRY { UINT8 macAddr[ETH_ADDR_LEN]; UINT16 refCount; - UINT32 ipAddr; + SOCKADDR_INET ipAddr; UINT32 pad; UINT64 timeout; LIST_ENTRY link; @@ -45,7 +45,7 @@ typedef struct _OVS_IPNEIGH_ENTRY { typedef struct _OVS_IPFORWARD_ENTRY { IP_ADDRESS_PREFIX prefix; - UINT32 nextHop; + SOCKADDR_INET nextHop; UINT16 refCount; LIST_ENTRY link; LIST_ENTRY fwdList; @@ -53,13 +53,13 @@ typedef struct _OVS_IPFORWARD_ENTRY { typedef union _OVS_FWD_INFO { struct { - UINT32 dstIpAddr; - UINT32 srcIpAddr; + SOCKADDR_INET dstIpAddr; + SOCKADDR_INET srcIpAddr; UINT8 dstMacAddr[ETH_ADDR_LEN]; UINT8 srcMacAddr[ETH_ADDR_LEN]; UINT32 srcPortNo; }; - UINT64 value[3]; + UINT64 value[9]; } OVS_FWD_INFO, *POVS_FWD_INFO; typedef struct _OVS_FWD_ENTRY { @@ -122,7 +122,7 @@ NTSTATUS OvsFwdIPHelperRequest(PNET_BUFFER_LIST nbl, UINT32 inPort, OvsIPHelperCallback cb, PVOID cbData1, PVOID cbData2); -NTSTATUS OvsLookupIPFwdInfo(UINT32 dstIp, POVS_FWD_INFO info); +NTSTATUS OvsLookupIPFwdInfo(SOCKADDR_INET dstIp, POVS_FWD_INFO info); VOID OvsCancelFwdIpHelperRequest(PNET_BUFFER_LIST nbl); #endif /* __IP_HELPER_H_ */ diff --git a/datapath-windows/ovsext/Stt.c b/datapath-windows/ovsext/Stt.c index dd7bf92..a7290d5 100644 --- a/datapath-windows/ovsext/Stt.c +++ b/datapath-windows/ovsext/Stt.c @@ -270,8 +270,8 @@ OvsDoEncapStt(POVS_VPORT_ENTRY vport, outerIpHdr->ttl = tunKey->ttl? tunKey->ttl : 64; outerIpHdr->protocol = IPPROTO_TCP; outerIpHdr->check = 0; - outerIpHdr->saddr = fwdInfo->srcIpAddr; - outerIpHdr->daddr = tunKey->dst; + outerIpHdr->saddr = fwdInfo->srcIpAddr.Ipv4.sin_addr.s_addr; + outerIpHdr->daddr = tunKey->dst.Ipv4.sin_addr.s_addr; /* L4 header */ RtlZeroMemory(outerTcpHdr, sizeof *outerTcpHdr); @@ -288,8 +288,10 @@ OvsDoEncapStt(POVS_VPORT_ENTRY vport, /* Calculate pseudo header chksum */ tcpChksumLen = sizeof(TCPHdr) + STT_HDR_LEN + innerFrameLen; ASSERT(tcpChksumLen < 65535); - outerTcpHdr->check = IPPseudoChecksum(&fwdInfo->srcIpAddr,(uint32 *) &tunKey->dst, - IPPROTO_TCP, (uint16) tcpChksumLen); + outerTcpHdr->check = + IPPseudoChecksum((UINT32*)&fwdInfo->srcIpAddr.Ipv4.sin_addr.s_addr, + (UINT32*)&tunKey->dst.Ipv4.sin_addr.s_addr, + IPPROTO_TCP, (uint16) tcpChksumLen); sttHdr->version = 0; /* Set STT Header */ @@ -817,8 +819,10 @@ OvsDecapStt(POVS_SWITCH_CONTEXT switchContext, ASSERT(sttHdr); /* Initialize the tunnel key */ - tunKey->dst = ipHdr->daddr; - tunKey->src = ipHdr->saddr; + tunKey->dst.Ipv4.sin_addr.s_addr = ipHdr->daddr; + tunKey->dst.si_family = AF_INET; + tunKey->src.Ipv4.sin_addr.s_addr = ipHdr->saddr; + tunKey->src.si_family = AF_INET; tunKey->tunnelId = sttHdr->key; tunKey->flags = OVS_TNL_F_KEY; tunKey->tos = ipHdr->tos; diff --git a/datapath-windows/ovsext/User.c b/datapath-windows/ovsext/User.c index 92a71e1..110a6cc 100644 --- a/datapath-windows/ovsext/User.c +++ b/datapath-windows/ovsext/User.c @@ -456,8 +456,10 @@ OvsExecuteDpIoctl(OvsPacketExecute *execute) MapTunAttrToFlowPut(execute->keyAttrs, tunnelAttrs, &tempTunKey); } - ndisStatus = OvsExtractFlow(pNbl, execute->inPort, &key, &layers, - tempTunKey.tunKey.dst == 0 ? NULL : &tempTunKey.tunKey); + ndisStatus = + OvsExtractFlow(pNbl, execute->inPort, &key, &layers, + IsNullIpAddr(&tempTunKey.tunKey.dst) ? + NULL : &tempTunKey.tunKey); if (ndisStatus == NDIS_STATUS_SUCCESS) { NdisAcquireRWLockRead(gOvsSwitchContext->dispatchLock, &lockState, 0); diff --git a/datapath-windows/ovsext/Util.h b/datapath-windows/ovsext/Util.h index 4bcde3b..3bf457d 100644 --- a/datapath-windows/ovsext/Util.h +++ b/datapath-windows/ovsext/Util.h @@ -113,4 +113,37 @@ OvsPerCpuDataInit(); VOID OvsPerCpuDataCleanup(); +__inline +BOOLEAN +IsNullIpAddr(const SOCKADDR_INET *ipAddr) +{ + UCHAR zeros[16] = { 0 }; + + if (((ipAddr->si_family == AF_INET || ipAddr->si_family == AF_UNSPEC) && + ipAddr->Ipv4.sin_addr.s_addr == 0) || + (ipAddr->si_family == AF_INET6 && + RtlEqualMemory(&ipAddr->Ipv6.sin6_addr.u.Byte, + &zeros, + sizeof(ipAddr->Ipv6.sin6_addr)))) { + return TRUE; + } + return FALSE; +} + +__inline +BOOLEAN +IsEqualIpAddr(const SOCKADDR_INET *src, + const SOCKADDR_INET *dst) +{ + if ((src->si_family == AF_INET && dst->si_family == AF_INET && + src->Ipv4.sin_addr.s_addr == dst->Ipv4.sin_addr.s_addr) || + (src->si_family == AF_INET6 && dst->si_family == AF_INET6 && + RtlEqualMemory(&src->Ipv6.sin6_addr, + &dst->Ipv6.sin6_addr, + sizeof(src->Ipv6.sin6_addr)))) { + return TRUE; + } + return FALSE; +} + #endif /* __UTIL_H_ */ diff --git a/datapath-windows/ovsext/Vxlan.c b/datapath-windows/ovsext/Vxlan.c index 20214cb..63e3680 100644 --- a/datapath-windows/ovsext/Vxlan.c +++ b/datapath-windows/ovsext/Vxlan.c @@ -282,10 +282,11 @@ OvsDoEncapVxlan(POVS_VPORT_ENTRY vport, IP_DF_NBO : 0; ipHdr->ttl = tunKey->ttl ? tunKey->ttl : VXLAN_DEFAULT_TTL; ipHdr->protocol = IPPROTO_UDP; - ASSERT(tunKey->dst == fwdInfo->dstIpAddr); - ASSERT(tunKey->src == fwdInfo->srcIpAddr || tunKey->src == 0); - ipHdr->saddr = fwdInfo->srcIpAddr; - ipHdr->daddr = fwdInfo->dstIpAddr; + ASSERT(IsEqualIpAddr(&tunKey->dst, &fwdInfo->dstIpAddr)); + ASSERT(IsEqualIpAddr(&tunKey->src, &fwdInfo->srcIpAddr) || + IsNullIpAddr(&tunKey->src)); + ipHdr->saddr = fwdInfo->srcIpAddr.Ipv4.sin_addr.s_addr; + ipHdr->daddr = fwdInfo->dstIpAddr.Ipv4.sin_addr.s_addr; ipHdr->check = 0; ipHdr->check = IPChecksum((UINT8 *)ipHdr, sizeof *ipHdr, 0); @@ -451,8 +452,10 @@ OvsDecapVxlan(POVS_SWITCH_CONTEXT switchContext, ethHdr = (EthHdr *)bufferStart; /* XXX: Handle IP options. */ ipHdr = (IPHdr *)((PCHAR)ethHdr + sizeof *ethHdr); - tunKey->src = ipHdr->saddr; - tunKey->dst = ipHdr->daddr; + tunKey->src.Ipv4.sin_addr.s_addr = ipHdr->saddr; + tunKey->src.Ipv4.sin_family = AF_INET; + tunKey->dst.Ipv4.sin_addr.s_addr = ipHdr->daddr; + tunKey->dst.Ipv4.sin_family = AF_INET; tunKey->tos = ipHdr->tos; tunKey->ttl = ipHdr->ttl; tunKey->pad = 0; @@ -530,8 +533,10 @@ OvsSlowPathDecapVxlan(const PNET_BUFFER_LIST packet, &VxlanHeaderBuffer); if (VxlanHeader) { - tunnelKey->src = nh->saddr; - tunnelKey->dst = nh->daddr; + tunnelKey->src.Ipv4.sin_addr.s_addr = nh->saddr; + tunnelKey->src.si_family = AF_INET; + tunnelKey->dst.Ipv4.sin_addr.s_addr = nh->daddr; + tunnelKey->dst.si_family = AF_INET; tunnelKey->ttl = nh->ttl; tunnelKey->tos = nh->tos; if (VxlanHeader->instanceID) { -- 1.9.0.msysgit.0 _______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev