diff --git a/src/core/net/dhcp6_server.cpp b/src/core/net/dhcp6_server.cpp index 1233201ef..1831c6ff8 100644 --- a/src/core/net/dhcp6_server.cpp +++ b/src/core/net/dhcp6_server.cpp @@ -162,7 +162,7 @@ ThreadError Dhcp6Server::UpdateService(void) address->mFields.m16[4] = HostSwap16(0x0000); address->mFields.m16[5] = HostSwap16(0x00ff); address->mFields.m16[6] = HostSwap16(0xfe00); - address->mFields.m8[14] = Mle::kAloc16Mask; + address->mFields.m8[14] = Ip6::Address::kAloc16Mask; address->mFields.m8[15] = lowpanContext.mContextId; mAgentsAloc[i].mPrefixLength = 128; mAgentsAloc[i].mPreferred = true; diff --git a/src/core/net/ip6.cpp b/src/core/net/ip6.cpp index 094fd78c1..ee1c9fd10 100644 --- a/src/core/net/ip6.cpp +++ b/src/core/net/ip6.cpp @@ -593,7 +593,9 @@ ThreadError Ip6::ProcessReceiveCallback(const Message &aMessage, const MessageIn { // do not pass messages sent to/from an RLOC VerifyOrExit(!messageInfo.GetSockAddr().IsRoutingLocator() && - !messageInfo.GetPeerAddr().IsRoutingLocator(), + !messageInfo.GetPeerAddr().IsRoutingLocator() && + !messageInfo.GetSockAddr().IsAnycastRoutingLocator() && + !messageInfo.GetPeerAddr().IsAnycastRoutingLocator(), error = kThreadError_NoRoute); switch (aIpProto) diff --git a/src/core/net/ip6_address.cpp b/src/core/net/ip6_address.cpp index bdfd39f34..64d719711 100644 --- a/src/core/net/ip6_address.cpp +++ b/src/core/net/ip6_address.cpp @@ -114,13 +114,14 @@ bool Address::IsRealmLocalAllMplForwarders(void) const bool Address::IsRoutingLocator(void) const { return (mFields.m16[4] == HostSwap16(0x0000) && mFields.m16[5] == HostSwap16(0x00ff) && - mFields.m16[6] == HostSwap16(0xfe00)); + mFields.m16[6] == HostSwap16(0xfe00) && mFields.m8[14] < kAloc16Mask && + (mFields.m8[14] & kRloc16ReservedBitMask) == 0); } bool Address::IsAnycastRoutingLocator(void) const { return (mFields.m16[4] == HostSwap16(0x0000) && mFields.m16[5] == HostSwap16(0x00ff) && - mFields.m16[6] == HostSwap16(0xfe00) && mFields.m8[14] == 0xfc); + mFields.m16[6] == HostSwap16(0xfe00) && mFields.m8[14] == kAloc16Mask); } bool Address::IsSubnetRouterAnycast(void) const diff --git a/src/core/net/ip6_address.hpp b/src/core/net/ip6_address.hpp index b5ffc5c61..c71bf9af5 100644 --- a/src/core/net/ip6_address.hpp +++ b/src/core/net/ip6_address.hpp @@ -56,6 +56,16 @@ OT_TOOL_PACKED_BEGIN class Address: public otIp6Address { public: + /** + * Masks + * + */ + enum + { + kAloc16Mask = 0xfc, ///< The mask for Aloc16. + kRloc16ReservedBitMask = 0x02, ///< The mask for the reserved bit of Rloc16. + }; + /** * Constants * diff --git a/src/core/thread/mle.cpp b/src/core/thread/mle.cpp index f41698c1a..a97ee3ff2 100644 --- a/src/core/thread/mle.cpp +++ b/src/core/thread/mle.cpp @@ -3202,12 +3202,14 @@ uint16_t Mle::GetNextHop(uint16_t aDestination) const bool Mle::IsRoutingLocator(const Ip6::Address &aAddress) const { - return memcmp(&mMeshLocal16, &aAddress, kRlocPrefixLength) == 0 && aAddress.mFields.m8[14] != kAloc16Mask; + return memcmp(&mMeshLocal16, &aAddress, kRlocPrefixLength) == 0 && + aAddress.mFields.m8[14] < Ip6::Address::kAloc16Mask && + (aAddress.mFields.m8[14] & Ip6::Address::kRloc16ReservedBitMask) == 0; } bool Mle::IsAnycastLocator(const Ip6::Address &aAddress) const { - return memcmp(&mMeshLocal16, &aAddress, kRlocPrefixLength) == 0 && aAddress.mFields.m8[14] == kAloc16Mask; + return memcmp(&mMeshLocal16, &aAddress, kRlocPrefixLength) == 0 && aAddress.mFields.m8[14] == Ip6::Address::kAloc16Mask; } Router *Mle::GetParent() diff --git a/src/core/thread/mle.hpp b/src/core/thread/mle.hpp index 45d2a07f7..b0274140e 100644 --- a/src/core/thread/mle.hpp +++ b/src/core/thread/mle.hpp @@ -110,7 +110,6 @@ enum DeviceState */ enum AlocAllocation { - kAloc16Mask = 0xfc, kAloc16Leader = 0xfc00, kAloc16DhcpAgentStart = 0xfc01, kAloc16DhcpAgentEnd = 0xfc0f,