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; }
void Netif::RemoveAllExternalUnicastAddresses(void) { size_t num = sizeof(mExtUnicastAddresses) / sizeof(mExtUnicastAddresses[0]); for (NetifUnicastAddress *entry = &mExtUnicastAddresses[0]; num > 0; num--, entry++) { // In unused entries, the `mNext` points back to the entry itself. if (entry->mNext != entry) { RemoveExternalUnicastAddress(entry->GetAddress()); } } }
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; }
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; }