Beispiel #1
0
/*!	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);
}
Beispiel #2
0
/*!	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);
	}
}
Beispiel #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;
}