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; }
/*! 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); }
/*! 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; }
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; }
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); } }
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; }