/*! You need to hold the domain lock when calling this function. */ void domain_interface_went_down(net_interface* interface) { ASSERT_LOCKED_RECURSIVE(&((net_domain_private*)interface->domain)->lock); TRACE(("domain_interface_went_down(%i, %s)\n", interface->domain->family, interface->name)); invalidate_routes(interface->domain, interface); }
/*! Called when a device lost its IFF_UP status. We will invalidate all interface routes here. */ void Interface::WentDown() { TRACE("Interface %p: went down\n", this); RecursiveLocker locker(fLock); AddressList::Iterator iterator = fAddresses.GetIterator(); while (InterfaceAddress* address = iterator.Next()) { if (address->domain != NULL) invalidate_routes(address->domain, this); } }
status_t update_interface_address(InterfaceAddress* interfaceAddress, int32 option, const sockaddr* oldAddress, const sockaddr* newAddress) { TRACE("%s(address %p, option %" B_PRId32 ", oldAddress %s, newAddress " "%s)\n", __FUNCTION__, interfaceAddress, option, AddressString(interfaceAddress->domain, oldAddress).Data(), AddressString(interfaceAddress->domain, newAddress).Data()); MutexLocker locker(sHashLock); // set logical interface address sockaddr** _address = interfaceAddress->AddressFor(option); if (_address == NULL) return B_BAD_VALUE; Interface* interface = (Interface*)interfaceAddress->interface; interfaceAddress->RemoveDefaultRoutes(option); if (option == SIOCDIFADDR) { // Remove address, and release its reference (causing our caller to // delete it) locker.Unlock(); invalidate_routes(interfaceAddress); interface->RemoveAddress(interfaceAddress); interfaceAddress->ReleaseReference(); return B_OK; } if (interfaceAddress->LocalIsDefined()) sAddressTable.Remove(interfaceAddress); // Copy new address over status_t status = InterfaceAddress::Set(_address, newAddress); if (status == B_OK) { sockaddr* address = *_address; if (option == SIOCSIFADDR || option == SIOCSIFNETMASK) { // Reset netmask and broadcast addresses to defaults net_domain* domain = interfaceAddress->domain; sockaddr* defaultNetmask = NULL; const sockaddr* netmask = NULL; if (option == SIOCSIFADDR) { defaultNetmask = InterfaceAddress::Prepare( &interfaceAddress->mask, address->sa_len); } else netmask = newAddress; // Reset the broadcast address if the address family has // such sockaddr* defaultBroadcast = NULL; if ((domain->address_module->flags & NET_ADDRESS_MODULE_FLAG_BROADCAST_ADDRESS) != 0) { defaultBroadcast = InterfaceAddress::Prepare( &interfaceAddress->destination, address->sa_len); } else InterfaceAddress::Set(&interfaceAddress->destination, NULL); domain->address_module->set_to_defaults(defaultNetmask, defaultBroadcast, interfaceAddress->local, netmask); } interfaceAddress->AddDefaultRoutes(option); notify_interface_changed(interface); } if (interfaceAddress->LocalIsDefined()) sAddressTable.Insert(interfaceAddress); return status; }