Ejemplo n.º 1
0
static struct net_route*
get_route_internal(struct net_domain_private* domain,
	const struct sockaddr* address)
{
	ASSERT_LOCKED_RECURSIVE(&domain->lock);
	net_route_private* route = NULL;

	if (address->sa_family == AF_LINK) {
		// special address to find an interface directly
		RouteList::Iterator iterator = domain->routes.GetIterator();
		const sockaddr_dl* link = (const sockaddr_dl*)address;

		while (iterator.HasNext()) {
			route = iterator.Next();

			net_device* device = route->interface_address->interface->device;

			if ((link->sdl_nlen > 0
					&& !strncmp(device->name, (const char*)link->sdl_data,
							IF_NAMESIZE))
				|| (link->sdl_nlen == 0 && link->sdl_alen > 0
					&& !memcmp(LLADDR(link), device->address.data,
							device->address.length)))
				break;
		}
	} else
		route = find_route(domain, address);

	if (route != NULL && atomic_add(&route->ref_count, 1) == 0) {
		// route has been deleted already
		route = NULL;
	}

	return route;
}
Ejemplo n.º 2
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);
}
Ejemplo n.º 3
0
/*!	Searches for a specific interface by name.
	You need to have the interface list's lock hold when calling this function.
*/
static struct Interface*
find_interface(const char* name)
{
	ASSERT_LOCKED_RECURSIVE(&sLock);

	InterfaceList::Iterator iterator = sInterfaces.GetIterator();
	while (Interface* interface = iterator.Next()) {
		if (!strcmp(interface->name, name))
			return interface;
	}

	return NULL;
}
Ejemplo n.º 4
0
InterfaceAddress*
Interface::_FirstForFamily(int family)
{
	ASSERT_LOCKED_RECURSIVE(&fLock);

	AddressList::Iterator iterator = fAddresses.GetIterator();
	while (InterfaceAddress* address = iterator.Next()) {
		if (address->domain != NULL && address->domain->family == family)
			return address;
	}

	return NULL;
}
Ejemplo n.º 5
0
static void
update_route_infos(struct net_domain_private* domain)
{
	ASSERT_LOCKED_RECURSIVE(&domain->lock);
	RouteInfoList::Iterator iterator = domain->route_infos.GetIterator();

	while (iterator.HasNext()) {
		net_route_info* info = iterator.Next();

		put_route_internal(domain, info->route);
		info->route = get_route_internal(domain, &info->address);
	}
}
Ejemplo n.º 6
0
static void
put_route_internal(struct net_domain_private* domain, net_route* _route)
{
	ASSERT_LOCKED_RECURSIVE(&domain->lock);

	net_route_private* route = (net_route_private*)_route;
	if (route == NULL || atomic_add(&route->ref_count, -1) != 1)
		return;

	// delete route - it must already have been removed at this point
	if (route->interface_address != NULL)
		((InterfaceAddress*)route->interface_address)->ReleaseReference();

	delete route;
}