ThreadError Netif::RemoveUnicastAddress(const NetifUnicastAddress &aAddress) { ThreadError error = kThreadError_None; if (mUnicastAddresses == &aAddress) { mUnicastAddresses = mUnicastAddresses->GetNext(); ExitNow(); } else if (mUnicastAddresses != NULL) { for (NetifUnicastAddress *cur = mUnicastAddresses; cur->GetNext(); cur = cur->GetNext()) { if (cur->mNext == &aAddress) { cur->mNext = aAddress.mNext; ExitNow(); } } } ExitNow(error = kThreadError_NotFound); exit: if (error != kThreadError_NotFound) { SetStateChangedFlags(OT_IP6_ADDRESS_REMOVED); } return error; }
ThreadError Netif::RemoveUnicastAddress(const NetifUnicastAddress &aAddress) { ThreadError error = kThreadError_None; if (mUnicastAddresses == &aAddress) { mUnicastAddresses = mUnicastAddresses->GetNext(); ExitNow(); } else if (mUnicastAddresses != NULL) { for (NetifUnicastAddress *cur = mUnicastAddresses; cur->GetNext(); cur = cur->GetNext()) { if (cur->mNext == &aAddress) { cur->mNext = aAddress.mNext; ExitNow(); } } } ExitNow(error = kThreadError_Error); exit: mUnicastChangedTask.Post(); return error; }
otError Netif::RemoveUnicastAddress(const NetifUnicastAddress &aAddress) { otError error = OT_ERROR_NONE; if (mUnicastAddresses == &aAddress) { mUnicastAddresses = mUnicastAddresses->GetNext(); ExitNow(); } else if (mUnicastAddresses != NULL) { for (NetifUnicastAddress *cur = mUnicastAddresses; cur->GetNext(); cur = cur->GetNext()) { if (cur->mNext == &aAddress) { cur->mNext = aAddress.mNext; ExitNow(); } } } ExitNow(error = OT_ERROR_NOT_FOUND); exit: if (error != OT_ERROR_NOT_FOUND) { GetNotifier().SetFlags(aAddress.mRloc ? OT_CHANGED_THREAD_RLOC_REMOVED : OT_CHANGED_IP6_ADDRESS_REMOVED); } return error; }
ThreadError Netif::RemoveExternalUnicastAddress(const Address &aAddress) { ThreadError error = kThreadError_None; NetifUnicastAddress *last = NULL; int8_t aAddressIndexToRemove = -1; for (NetifUnicastAddress *cur = mUnicastAddresses; cur; cur = cur->GetNext()) { if (memcmp(&cur->mAddress, &aAddress, sizeof(otIp6Address)) == 0) { aAddressIndexToRemove = GetExtUnicastAddressIndex(cur); VerifyOrExit(aAddressIndexToRemove != -1, error = kThreadError_InvalidArgs); if (last) { last->mNext = cur->mNext; } else { mUnicastAddresses = cur->GetNext(); } break; } last = cur; } if (aAddressIndexToRemove != -1) { mMaskExtUnicastAddresses &= ~(1 << aAddressIndexToRemove); SetStateChangedFlags(OT_IP6_ADDRESS_REMOVED); } else { error = kThreadError_NotFound; } exit: return error; }
otError Netif::RemoveExternalUnicastAddress(const Address &aAddress) { otError error = OT_ERROR_NONE; NetifUnicastAddress *entry; NetifUnicastAddress *last = NULL; size_t num = sizeof(mExtUnicastAddresses) / sizeof(mExtUnicastAddresses[0]); for (entry = mUnicastAddresses; entry; entry = entry->GetNext()) { if (entry->GetAddress() == aAddress) { VerifyOrExit((entry >= &mExtUnicastAddresses[0]) && (entry < &mExtUnicastAddresses[num]), error = OT_ERROR_INVALID_ARGS); if (last) { last->mNext = entry->mNext; } else { mUnicastAddresses = entry->GetNext(); } break; } last = entry; } VerifyOrExit(entry != NULL, error = OT_ERROR_NOT_FOUND); // To mark the address entry as unused/available, set the `mNext` pointer back to the entry itself. entry->mNext = entry; GetNotifier().SetFlags(OT_CHANGED_IP6_ADDRESS_REMOVED); exit: return error; }
int Netif::GetOnLinkNetif(const Address &aAddress) { int rval = -1; for (Netif *netif = sNetifListHead; netif; netif = netif->mNext) { for (NetifUnicastAddress *cur = netif->mUnicastAddresses; cur; cur = cur->GetNext()) { if (cur->GetAddress().PrefixMatch(aAddress) >= cur->mPrefixLength) { ExitNow(rval = netif->mInterfaceId); } } } exit: return rval; }
bool Netif::IsUnicastAddress(const Address &aAddress) { bool rval = false; for (Netif *netif = sNetifListHead; netif; netif = netif->mNext) { for (NetifUnicastAddress *cur = netif->mUnicastAddresses; cur; cur = cur->GetNext()) { if (cur->GetAddress() == aAddress) { ExitNow(rval = true); } } } exit: return rval; }
ThreadError Netif::AddExternalUnicastAddress(const NetifUnicastAddress &aAddress) { ThreadError error = kThreadError_None; int8_t index = 0; for (NetifUnicastAddress *cur = mUnicastAddresses; cur; cur = cur->GetNext()) { if (memcmp(&cur->mAddress, &aAddress.mAddress, sizeof(otIp6Address)) == 0) { VerifyOrExit(GetExtUnicastAddressIndex(cur) != -1, error = kThreadError_InvalidArgs); cur->mPreferredLifetime = aAddress.mPreferredLifetime; cur->mValidLifetime = aAddress.mValidLifetime; cur->mPrefixLength = aAddress.mPrefixLength; ExitNow(); } } // Make sure we haven't set all the bits in the mask already VerifyOrExit(mMaskExtUnicastAddresses != ((1 << OPENTHREAD_CONFIG_MAX_EXT_IP_ADDRS) - 1), error = kThreadError_NoBufs); // Get next available entry index while ((mMaskExtUnicastAddresses & (1 << index)) != 0) { index++; } assert(index < OPENTHREAD_CONFIG_MAX_EXT_IP_ADDRS); // Increase the count and mask the index mMaskExtUnicastAddresses |= 1 << index; // Copy the address to the next available dynamic address mExtUnicastAddresses[index] = aAddress; mExtUnicastAddresses[index].mNext = mUnicastAddresses; mUnicastAddresses = &mExtUnicastAddresses[index]; SetStateChangedFlags(OT_IP6_ADDRESS_ADDED); exit: return error; }
otError Netif::AddExternalUnicastAddress(const NetifUnicastAddress &aAddress) { otError error = OT_ERROR_NONE; NetifUnicastAddress *entry; size_t num = sizeof(mExtUnicastAddresses) / sizeof(mExtUnicastAddresses[0]); VerifyOrExit(!aAddress.GetAddress().IsLinkLocal(), error = OT_ERROR_INVALID_ARGS); for (entry = mUnicastAddresses; entry; entry = entry->GetNext()) { if (entry->GetAddress() == aAddress.GetAddress()) { VerifyOrExit((entry >= &mExtUnicastAddresses[0]) && (entry < &mExtUnicastAddresses[num]), error = OT_ERROR_INVALID_ARGS); entry->mPrefixLength = aAddress.mPrefixLength; entry->mPreferred = aAddress.mPreferred; entry->mValid = aAddress.mValid; ExitNow(); } } // Find an available entry in the `mExtUnicastAddresses` array. for (entry = &mExtUnicastAddresses[0]; num > 0; num--, entry++) { // In an unused/available entry, `mNext` points back to the entry itself. if (entry->mNext == entry) { break; } } VerifyOrExit(num > 0, error = OT_ERROR_NO_BUFS); // Copy the new address into the available entry and insert it in linked-list. *entry = aAddress; entry->mNext = mUnicastAddresses; mUnicastAddresses = entry; GetNotifier().SetFlags(OT_CHANGED_IP6_ADDRESS_ADDED); exit: return error; }
ThreadError Netif::AddUnicastAddress(NetifUnicastAddress &aAddress) { ThreadError error = kThreadError_None; for (NetifUnicastAddress *cur = mUnicastAddresses; cur; cur = cur->GetNext()) { if (cur == &aAddress) { ExitNow(error = kThreadError_Already); } } aAddress.mNext = mUnicastAddresses; mUnicastAddresses = &aAddress; SetStateChangedFlags(OT_IP6_ADDRESS_ADDED); exit: return error; }
ThreadError Netif::AddUnicastAddress(NetifUnicastAddress &aAddress) { ThreadError error = kThreadError_None; for (NetifUnicastAddress *cur = mUnicastAddresses; cur; cur = cur->GetNext()) { if (cur == &aAddress) { ExitNow(error = kThreadError_Busy); } } aAddress.mNext = mUnicastAddresses; mUnicastAddresses = &aAddress; mUnicastChangedTask.Post(); exit: return error; }
otError Netif::AddUnicastAddress(NetifUnicastAddress &aAddress) { otError error = OT_ERROR_NONE; for (NetifUnicastAddress *cur = mUnicastAddresses; cur; cur = cur->GetNext()) { if (cur == &aAddress) { ExitNow(error = OT_ERROR_ALREADY); } } aAddress.mNext = mUnicastAddresses; mUnicastAddresses = &aAddress; GetNotifier().SetFlags(aAddress.mRloc ? OT_CHANGED_THREAD_RLOC_ADDED : OT_CHANGED_IP6_ADDRESS_ADDED); exit: return error; }