示例#1
0
void
Interface::RemoveAddresses()
{
	RecursiveLocker locker(fLock);

	while (InterfaceAddress* address = fAddresses.RemoveHead()) {
		locker.Unlock();

		if (address->LocalIsDefined()) {
			MutexLocker hashLocker(sHashLock);
			sAddressTable.Remove(address);
		}
		address->ReleaseReference();

		locker.Lock();
	}
}
示例#2
0
void
Interface::RemoveAddress(InterfaceAddress* address)
{
	net_domain* domain = address->domain;
	if (domain == NULL)
		return;

	RecursiveLocker locker(fLock);

	fAddresses.Remove(address);
	address->GetDoublyLinkedListLink()->next = NULL;

	locker.Unlock();

	if (address->LocalIsDefined()) {
		MutexLocker hashLocker(sHashLock);
		sAddressTable.Remove(address);
	}
}
示例#3
0
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;
}