* Renamed net_device_interface::rx_lock to receive_lock.

* Cleanup, improved comments, removed useless ones.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@29232 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Axel Dörfler
2009-02-16 11:13:28 +00:00
parent 86a0cf15e4
commit 3c13a5f5b3
4 changed files with 364 additions and 405 deletions
+98 -107
View File
@@ -1,5 +1,5 @@
/*
* Copyright 2006-2008, Haiku, Inc. All Rights Reserved.
* Copyright 2006-2009, Haiku, Inc. All Rights Reserved.
* Distributed under the terms of the MIT License.
*
* Authors:
@@ -31,28 +31,28 @@
struct datalink_protocol : net_protocol {
struct net_domain_private *domain;
struct net_domain_private* domain;
};
struct interface_protocol : net_datalink_protocol {
struct net_device_module_info *device_module;
struct net_device *device;
struct net_device_module_info* device_module;
struct net_device* device;
};
static status_t
device_reader_thread(void *_interface)
device_reader_thread(void* _interface)
{
net_device_interface *interface = (net_device_interface *)_interface;
net_device *device = interface->device;
net_device_interface* interface = (net_device_interface*)_interface;
net_device* device = interface->device;
status_t status = B_OK;
RecursiveLocker locker(interface->rx_lock);
RecursiveLocker locker(interface->receive_lock);
while (device->flags & IFF_UP) {
while ((device->flags & IFF_UP) != 0) {
locker.Unlock();
net_buffer *buffer;
net_buffer* buffer;
status = device->module->receive_data(device, &buffer);
locker.Lock();
@@ -61,8 +61,7 @@ device_reader_thread(void *_interface)
// feed device monitors
DeviceMonitorList::Iterator iterator =
interface->monitor_funcs.GetIterator();
while (iterator.HasNext()) {
net_device_monitor *monitor = iterator.Next();
while (net_device_monitor* monitor = iterator.Next()) {
monitor->receive(monitor, buffer);
}
@@ -76,26 +75,17 @@ device_reader_thread(void *_interface)
fifo_enqueue_buffer(&interface->receive_queue, buffer);
} else {
// In case of error, give the other threads some
// time to run since this is a near real time thread.
//
// TODO: can this value be lower? 1000 works fine in
// my system. 10ms seems a bit too much and adds
// as latency.
// time to run since this is a high priority time thread.
snooze(10000);
}
// if the interface went down IFF_UP was removed
// and the receive_data() above should have been
// interrupted. One check should be enough, specially
// considering the snooze above.
}
return status;
}
static struct sockaddr **
interface_address(net_interface *interface, int32 option)
static struct sockaddr**
interface_address(net_interface* interface, int32 option)
{
switch (option) {
case SIOCSIFADDR:
@@ -118,8 +108,8 @@ interface_address(net_interface *interface, int32 option)
}
void
remove_default_routes(net_interface_private *interface, int32 option)
static void
remove_default_routes(net_interface_private* interface, int32 option)
{
net_route route;
route.destination = interface->address;
@@ -141,8 +131,8 @@ remove_default_routes(net_interface_private *interface, int32 option)
}
void
add_default_routes(net_interface_private *interface, int32 option)
static void
add_default_routes(net_interface_private* interface, int32 option)
{
net_route route;
route.destination = interface->address;
@@ -164,16 +154,16 @@ add_default_routes(net_interface_private *interface, int32 option)
}
sockaddr *
reallocate_address(sockaddr **_address, uint32 size)
static sockaddr*
reallocate_address(sockaddr** _address, uint32 size)
{
sockaddr *address = *_address;
sockaddr* address = *_address;
size = max_c(size, sizeof(struct sockaddr));
if (address != NULL && address->sa_len >= size)
return address;
address = (sockaddr *)malloc(size);
address = (sockaddr*)malloc(size);
if (address == NULL)
return NULL;
@@ -185,8 +175,8 @@ reallocate_address(sockaddr **_address, uint32 size)
static status_t
datalink_control_interface(net_domain_private *domain, int32 option,
void *value, size_t *_length, size_t expected, bool getByName)
datalink_control_interface(net_domain_private* domain, int32 option,
void* value, size_t* _length, size_t expected, bool getByName)
{
if (*_length < expected)
return B_BAD_VALUE;
@@ -198,14 +188,14 @@ datalink_control_interface(net_domain_private *domain, int32 option,
return B_BAD_ADDRESS;
MutexLocker _(domain->lock);
net_interface *interface = NULL;
net_interface* interface = NULL;
if (getByName)
interface = find_interface(domain, request.ifr_name);
else
interface = find_interface(domain, request.ifr_index);
status_t status = (interface == NULL) ? ENODEV : B_OK;
status_t status = interface == NULL ? ENODEV : B_OK;
switch (option) {
case SIOCGIFINDEX:
@@ -234,10 +224,10 @@ datalink_control_interface(net_domain_private *domain, int32 option,
status_t
datalink_control(net_domain *_domain, int32 option, void *value,
size_t *_length)
datalink_control(net_domain* _domain, int32 option, void* value,
size_t* _length)
{
net_domain_private *domain = (net_domain_private *)_domain;
net_domain_private* domain = (net_domain_private*)_domain;
if (domain == NULL || domain->family == AF_LINK) {
// the AF_LINK family is already handled completely in the link protocol
return B_BAD_VALUE;
@@ -288,7 +278,7 @@ datalink_control(net_domain *_domain, int32 option, void *value,
return B_BAD_ADDRESS;
status_t result = list_domain_interfaces(config.ifc_buf,
(size_t *)&config.ifc_len);
(size_t*)&config.ifc_len);
if (result != B_OK)
return result;
@@ -324,7 +314,7 @@ datalink_control(net_domain *_domain, int32 option, void *value,
MutexLocker _(domain->lock);
net_interface *interface = find_interface(domain,
net_interface* interface = find_interface(domain,
request.ifr_name);
if (interface == NULL)
return B_BAD_VALUE;
@@ -339,10 +329,10 @@ datalink_control(net_domain *_domain, int32 option, void *value,
status_t
datalink_send_data(struct net_route *route, net_buffer *buffer)
datalink_send_data(struct net_route* route, net_buffer* buffer)
{
net_interface_private *interface =
(net_interface_private *)route->interface;
net_interface_private* interface =
(net_interface_private*)route->interface;
//dprintf("send buffer (%ld bytes) to interface %s (route flags %lx)\n",
// buffer->size, interface->name, route->flags);
@@ -373,19 +363,19 @@ datalink_send_data(struct net_route *route, net_buffer *buffer)
status_t
datalink_send_datagram(net_protocol *protocol, net_domain *domain,
net_buffer *buffer)
datalink_send_datagram(net_protocol* protocol, net_domain* domain,
net_buffer* buffer)
{
if (protocol == NULL && domain == NULL)
return B_BAD_VALUE;
net_protocol_module_info *module = protocol ? protocol->module
net_protocol_module_info* module = protocol ? protocol->module
: domain->module;
if (domain == NULL)
domain = protocol->module->get_domain(protocol);
net_route *route = NULL;
net_route* route = NULL;
status_t status;
if (protocol != NULL && protocol->socket->bound_to_device > 0) {
status = get_device_route(domain, protocol->socket->bound_to_device,
@@ -408,21 +398,21 @@ datalink_send_datagram(net_protocol *protocol, net_domain *domain,
\param _matchedType will be set to either zero or MSG_BCAST if non-NULL.
*/
bool
datalink_is_local_address(net_domain *_domain, const struct sockaddr *address,
net_interface **_interface, uint32 *_matchedType)
datalink_is_local_address(net_domain* _domain, const struct sockaddr* address,
net_interface** _interface, uint32* _matchedType)
{
net_domain_private *domain = (net_domain_private *)_domain;
net_domain_private* domain = (net_domain_private*)_domain;
if (domain == NULL || address == NULL)
return false;
MutexLocker locker(domain->lock);
net_interface *interface = NULL;
net_interface *fallback = NULL;
net_interface* interface = NULL;
net_interface* fallback = NULL;
uint32 matchedType = 0;
while (true) {
interface = (net_interface *)list_get_next_item(
interface = (net_interface*)list_get_next_item(
&domain->interfaces, interface);
if (interface == NULL)
break;
@@ -460,20 +450,20 @@ datalink_is_local_address(net_domain *_domain, const struct sockaddr *address,
}
net_interface *
datalink_get_interface_with_address(net_domain *_domain,
const sockaddr *address)
net_interface*
datalink_get_interface_with_address(net_domain* _domain,
const sockaddr* address)
{
net_domain_private *domain = (net_domain_private *)_domain;
net_domain_private* domain = (net_domain_private*)_domain;
if (domain == NULL)
return NULL;
MutexLocker _(domain->lock);
net_interface *interface = NULL;
net_interface* interface = NULL;
while (true) {
interface = (net_interface *)list_get_next_item(
interface = (net_interface*)list_get_next_item(
&domain->interfaces, interface);
if (interface == NULL)
break;
@@ -490,8 +480,8 @@ datalink_get_interface_with_address(net_domain *_domain,
}
net_interface *
datalink_get_interface(net_domain *domain, uint32 index)
net_interface*
datalink_get_interface(net_domain* domain, uint32 index)
{
if (index == 0)
return datalink_get_interface_with_address(domain, NULL);
@@ -518,12 +508,12 @@ datalink_std_ops(int32 op, ...)
status_t
interface_protocol_init(struct net_interface *_interface,
net_datalink_protocol **_protocol)
interface_protocol_init(struct net_interface* _interface,
net_datalink_protocol** _protocol)
{
net_interface_private *interface = (net_interface_private *)_interface;
net_interface_private* interface = (net_interface_private*)_interface;
interface_protocol *protocol = new (std::nothrow) interface_protocol;
interface_protocol* protocol = new (std::nothrow) interface_protocol;
if (protocol == NULL)
return B_NO_MEMORY;
@@ -536,7 +526,7 @@ interface_protocol_init(struct net_interface *_interface,
status_t
interface_protocol_uninit(net_datalink_protocol *protocol)
interface_protocol_uninit(net_datalink_protocol* protocol)
{
delete protocol;
return B_OK;
@@ -544,12 +534,12 @@ interface_protocol_uninit(net_datalink_protocol *protocol)
status_t
interface_protocol_send_data(net_datalink_protocol *_protocol,
net_buffer *buffer)
interface_protocol_send_data(net_datalink_protocol* _protocol,
net_buffer* buffer)
{
interface_protocol *protocol = (interface_protocol *)_protocol;
net_interface_private *interface
= (net_interface_private *)protocol->interface;
interface_protocol* protocol = (interface_protocol*)_protocol;
net_interface_private* interface
= (net_interface_private*)protocol->interface;
// TODO: Need to think about this locking. We can't obtain the
// RX Lock here (nor would it make sense) as the ARP
@@ -560,7 +550,7 @@ interface_protocol_send_data(net_datalink_protocol *_protocol,
DeviceMonitorList::Iterator iterator =
interface->device_interface->monitor_funcs.GetIterator();
while (iterator.HasNext()) {
net_device_monitor *monitor = iterator.Next();
net_device_monitor* monitor = iterator.Next();
monitor->receive(monitor, buffer);
}
@@ -569,12 +559,12 @@ interface_protocol_send_data(net_datalink_protocol *_protocol,
status_t
interface_protocol_up(net_datalink_protocol *_protocol)
interface_protocol_up(net_datalink_protocol* _protocol)
{
interface_protocol *protocol = (interface_protocol *)_protocol;
net_device_interface *deviceInterface =
((net_interface_private *)protocol->interface)->device_interface;
net_device *device = protocol->device;
interface_protocol* protocol = (interface_protocol*)_protocol;
net_device_interface* deviceInterface =
((net_interface_private*)protocol->interface)->device_interface;
net_device* device = protocol->device;
// This function is called with the RX lock held.
@@ -610,11 +600,11 @@ interface_protocol_up(net_datalink_protocol *_protocol)
void
interface_protocol_down(net_datalink_protocol *_protocol)
interface_protocol_down(net_datalink_protocol* _protocol)
{
interface_protocol *protocol = (interface_protocol *)_protocol;
net_device_interface *deviceInterface =
((net_interface_private *)protocol->interface)->device_interface;
interface_protocol* protocol = (interface_protocol*)_protocol;
net_device_interface* deviceInterface =
((net_interface_private*)protocol->interface)->device_interface;
// This function is called with the RX lock held.
if (deviceInterface->up_count == 0)
@@ -632,11 +622,12 @@ interface_protocol_down(net_datalink_protocol *_protocol)
status_t
interface_protocol_control(net_datalink_protocol *_protocol,
int32 option, void *argument, size_t length)
interface_protocol_control(net_datalink_protocol* _protocol, int32 option,
void* argument, size_t length)
{
interface_protocol *protocol = (interface_protocol *)_protocol;
net_interface_private *interface = (net_interface_private *)protocol->interface;
interface_protocol* protocol = (interface_protocol*)_protocol;
net_interface_private* interface
= (net_interface_private*)protocol->interface;
switch (option) {
case SIOCSIFADDR:
@@ -649,12 +640,12 @@ interface_protocol_control(net_datalink_protocol *_protocol,
if (user_memcpy(&request, argument, sizeof(struct ifreq)) < B_OK)
return B_BAD_ADDRESS;
sockaddr **_address = interface_address(interface, option);
sockaddr** _address = interface_address(interface, option);
if (_address == NULL)
return B_BAD_VALUE;
// allocate new address if needed
sockaddr *address = reallocate_address(_address,
sockaddr* address = reallocate_address(_address,
request.ifr_addr.sa_len);
// copy new address over
@@ -664,15 +655,15 @@ interface_protocol_control(net_datalink_protocol *_protocol,
if (option == SIOCSIFADDR || option == SIOCSIFNETMASK) {
// reset netmask and broadcast addresses to defaults
sockaddr *netmask = NULL;
sockaddr *oldNetmask = NULL;
sockaddr* netmask = NULL;
sockaddr* oldNetmask = NULL;
if (option == SIOCSIFADDR) {
netmask = reallocate_address(&interface->mask,
request.ifr_addr.sa_len);
} else
oldNetmask = address;
sockaddr *broadcast = reallocate_address(
sockaddr* broadcast = reallocate_address(
&interface->destination, request.ifr_addr.sa_len);
interface->domain->address_module->set_to_defaults(
@@ -691,13 +682,13 @@ interface_protocol_control(net_datalink_protocol *_protocol,
case SIOCGIFDSTADDR:
{
// get logical interface address
sockaddr **_address = interface_address(interface, option);
sockaddr** _address = interface_address(interface, option);
if (_address == NULL)
return B_BAD_VALUE;
struct ifreq request;
sockaddr *address = *_address;
sockaddr* address = *_address;
if (address != NULL)
memcpy(&request.ifr_addr, address, address->sa_len);
else {
@@ -706,7 +697,7 @@ interface_protocol_control(net_datalink_protocol *_protocol,
}
// copy address over
return user_memcpy(&((struct ifreq *)argument)->ifr_addr,
return user_memcpy(&((struct ifreq*)argument)->ifr_addr,
&request.ifr_addr, request.ifr_addr.sa_len);
}
@@ -716,7 +707,7 @@ interface_protocol_control(net_datalink_protocol *_protocol,
struct ifreq request;
request.ifr_flags = interface->flags | interface->device->flags;
return user_memcpy(&((struct ifreq *)argument)->ifr_flags,
return user_memcpy(&((struct ifreq*)argument)->ifr_flags,
&request.ifr_flags, sizeof(request.ifr_flags));
}
@@ -730,14 +721,14 @@ interface_protocol_control(net_datalink_protocol *_protocol,
request.ifr_parameter.sub_type = 0;
// TODO: for now, we ignore the sub type...
return user_memcpy(&((struct ifreq *)argument)->ifr_parameter,
return user_memcpy(&((struct ifreq*)argument)->ifr_parameter,
&request.ifr_parameter, sizeof(request.ifr_parameter));
}
case SIOCGIFSTATS:
{
// get stats
return user_memcpy(&((struct ifreq *)argument)->ifr_stats,
return user_memcpy(&((struct ifreq*)argument)->ifr_stats,
&interface->device_interface->device->stats,
sizeof(struct ifreq_stats));
}
@@ -748,7 +739,7 @@ interface_protocol_control(net_datalink_protocol *_protocol,
struct ifreq request;
request.ifr_type = interface->type;
return user_memcpy(&((struct ifreq *)argument)->ifr_type,
return user_memcpy(&((struct ifreq*)argument)->ifr_type,
&request.ifr_type, sizeof(request.ifr_type));
}
@@ -758,7 +749,7 @@ interface_protocol_control(net_datalink_protocol *_protocol,
struct ifreq request;
request.ifr_mtu = interface->mtu;
return user_memcpy(&((struct ifreq *)argument)->ifr_mtu,
return user_memcpy(&((struct ifreq*)argument)->ifr_mtu,
&request.ifr_mtu, sizeof(request.ifr_mtu));
}
case SIOCSIFMTU:
@@ -793,7 +784,7 @@ interface_protocol_control(net_datalink_protocol *_protocol,
struct ifreq request;
request.ifr_media = interface->device->media;
return user_memcpy(&((struct ifreq *)argument)->ifr_media,
return user_memcpy(&((struct ifreq*)argument)->ifr_media,
&request.ifr_media, sizeof(request.ifr_media));
}
@@ -803,7 +794,7 @@ interface_protocol_control(net_datalink_protocol *_protocol,
struct ifreq request;
request.ifr_metric = interface->metric;
return user_memcpy(&((struct ifreq *)argument)->ifr_metric,
return user_memcpy(&((struct ifreq*)argument)->ifr_metric,
&request.ifr_metric, sizeof(request.ifr_metric));
}
case SIOCSIFMETRIC:
@@ -829,20 +820,20 @@ interface_protocol_control(net_datalink_protocol *_protocol,
static status_t
interface_protocol_join_multicast(net_datalink_protocol *_protocol,
const sockaddr *address)
interface_protocol_join_multicast(net_datalink_protocol* _protocol,
const sockaddr* address)
{
interface_protocol *protocol = (interface_protocol *)_protocol;
interface_protocol* protocol = (interface_protocol*)_protocol;
return protocol->device_module->add_multicast(protocol->device, address);
}
static status_t
interface_protocol_leave_multicast(net_datalink_protocol *_protocol,
const sockaddr *address)
interface_protocol_leave_multicast(net_datalink_protocol* _protocol,
const sockaddr* address)
{
interface_protocol *protocol = (interface_protocol *)_protocol;
interface_protocol* protocol = (interface_protocol*)_protocol;
return protocol->device_module->remove_multicast(protocol->device,
address);
+86 -95
View File
@@ -1,5 +1,5 @@
/*
* Copyright 2006-2008, Haiku, Inc. All Rights Reserved.
* Copyright 2006-2009, Haiku, Inc. All Rights Reserved.
* Distributed under the terms of the MIT License.
*
* Authors:
@@ -40,12 +40,12 @@ static list sDomains;
Scans the domain list for the specified family.
You need to hold the sDomainLock when calling this function.
*/
static net_domain_private *
static net_domain_private*
lookup_domain(int family)
{
net_domain_private *domain = NULL;
net_domain_private* domain = NULL;
while (true) {
domain = (net_domain_private *)list_get_next_item(&sDomains, domain);
domain = (net_domain_private*)list_get_next_item(&sDomains, domain);
if (domain == NULL)
break;
@@ -63,7 +63,7 @@ lookup_domain(int family)
/*!
Gets the domain of the specified family.
*/
net_domain *
net_domain*
get_domain(int family)
{
MutexLocker locker(sDomainLock);
@@ -76,17 +76,17 @@ count_domain_interfaces()
{
MutexLocker locker(sDomainLock);
net_domain_private *domain = NULL;
net_domain_private* domain = NULL;
uint32 count = 0;
while (true) {
domain = (net_domain_private *)list_get_next_item(&sDomains, domain);
domain = (net_domain_private*)list_get_next_item(&sDomains, domain);
if (domain == NULL)
break;
net_interface *interface = NULL;
net_interface* interface = NULL;
while (true) {
interface = (net_interface *)list_get_next_item(&domain->interfaces,
interface = (net_interface*)list_get_next_item(&domain->interfaces,
interface);
if (interface == NULL)
break;
@@ -105,23 +105,23 @@ count_domain_interfaces()
returned.
*/
status_t
list_domain_interfaces(void *_buffer, size_t *bufferSize)
list_domain_interfaces(void* _buffer, size_t* bufferSize)
{
MutexLocker locker(sDomainLock);
UserBuffer buffer(_buffer, *bufferSize);
net_domain_private *domain = NULL;
net_domain_private* domain = NULL;
while (true) {
domain = (net_domain_private *)list_get_next_item(&sDomains, domain);
domain = (net_domain_private*)list_get_next_item(&sDomains, domain);
if (domain == NULL)
break;
MutexLocker locker(domain->lock);
net_interface *interface = NULL;
net_interface* interface = NULL;
while (true) {
interface = (net_interface *)list_get_next_item(&domain->interfaces,
interface = (net_interface*)list_get_next_item(&domain->interfaces,
interface);
if (interface == NULL)
break;
@@ -149,23 +149,23 @@ list_domain_interfaces(void *_buffer, size_t *bufferSize)
status_t
add_interface_to_domain(net_domain *_domain,
add_interface_to_domain(net_domain* _domain,
struct ifreq& request)
{
net_domain_private *domain = (net_domain_private *)_domain;
net_domain_private* domain = (net_domain_private*)_domain;
const char *deviceName = request.ifr_parameter.device[0]
const char* deviceName = request.ifr_parameter.device[0]
? request.ifr_parameter.device : request.ifr_name;
const char *baseName = request.ifr_parameter.base_name[0]
const char* baseName = request.ifr_parameter.base_name[0]
? request.ifr_parameter.base_name : request.ifr_name;
net_device_interface *deviceInterface = get_device_interface(deviceName);
net_device_interface* deviceInterface = get_device_interface(deviceName);
if (deviceInterface == NULL)
return ENODEV;
MutexLocker locker(domain->lock);
net_interface_private *interface = NULL;
net_interface_private* interface = NULL;
status_t status;
if (find_interface(domain, request.ifr_name) == NULL) {
@@ -200,140 +200,129 @@ add_interface_to_domain(net_domain *_domain,
You need to hold the domain's lock when calling this function.
*/
status_t
remove_interface_from_domain(net_interface *interface)
remove_interface_from_domain(net_interface* interface)
{
net_domain_private *domain = (net_domain_private *)interface->domain;
net_domain_private* domain = (net_domain_private*)interface->domain;
list_remove_item(&domain->interfaces, interface);
notify_interface_removed(interface);
delete_interface((net_interface_private *)interface);
delete_interface((net_interface_private*)interface);
return B_OK;
}
status_t
domain_interface_control(net_domain_private *domain, int32 option,
ifreq *request)
domain_interface_control(net_domain_private* domain, int32 option,
ifreq* request)
{
const char *name = request->ifr_name;
const char* name = request->ifr_name;
status_t status = B_OK;
net_device_interface *device = get_device_interface(name, false);
net_device_interface* device = get_device_interface(name, false);
if (device == NULL)
return ENODEV;
else {
// The locking protocol dictates that if both the RX lock
// and domain locks are required, we MUST obtain the RX
// lock before the domain lock. This order MUST NOT ever
// be reversed under the penalty of deadlock.
RecursiveLocker _1(device->rx_lock);
MutexLocker _2(domain->lock);
net_interface *interface = find_interface(domain, name);
if (interface != NULL) {
switch (option) {
case SIOCDIFADDR:
remove_interface_from_domain(interface);
break;
// The locking protocol dictates that if both the receive lock
// and domain locks are required, we MUST obtain the receive
// lock before the domain lock.
RecursiveLocker _1(device->receive_lock);
MutexLocker _2(domain->lock);
case SIOCSIFFLAGS:
{
uint32 requestFlags = request->ifr_flags;
request->ifr_flags &= ~(IFF_UP | IFF_LINK | IFF_BROADCAST);
net_interface* interface = find_interface(domain, name);
if (interface != NULL) {
switch (option) {
case SIOCDIFADDR:
remove_interface_from_domain(interface);
break;
if ((requestFlags & IFF_UP) != (interface->flags & IFF_UP)) {
if (requestFlags & IFF_UP) {
status = interface->first_info->interface_up(
interface->first_protocol);
if (status == B_OK)
interface->flags |= IFF_UP;
} else {
interface_set_down(interface);
}
case SIOCSIFFLAGS:
{
uint32 requestFlags = request->ifr_flags;
request->ifr_flags &= ~(IFF_UP | IFF_LINK | IFF_BROADCAST);
if ((requestFlags & IFF_UP) != (interface->flags & IFF_UP)) {
if (requestFlags & IFF_UP) {
status = interface->first_info->interface_up(
interface->first_protocol);
if (status == B_OK)
interface->flags |= IFF_UP;
} else {
interface_set_down(interface);
}
if (status == B_OK) {
// TODO: why shouldn't we able to delete IFF_BROADCAST?
interface->flags &= IFF_UP | IFF_LINK | IFF_BROADCAST;
interface->flags |= request->ifr_flags;
}
break;
}
if (status == B_OK) {
// TODO: why shouldn't we able to delete IFF_BROADCAST?
interface->flags &= IFF_UP | IFF_LINK | IFF_BROADCAST;
interface->flags |= request->ifr_flags;
}
break;
}
}
}
// If the SIOCDIFADDR call above removed the last interface
// associated with the device interface, this put_() will
// effectively remove the interface
// If the SIOCDIFADDR call above removed the last interface associated with
// the device interface, this will effectively remove the interface
put_device_interface(device);
return status;
}
/*! You need to hold the domain lock when calling this function. */
void
domain_interface_went_down(net_interface *interface)
domain_interface_went_down(net_interface* interface)
{
// the domain should be locked here. always check
// all callers to be sure. We get here via
// interface_set_down().
ASSERT_LOCKED_MUTEX(&((net_domain_private*)interface->domain)->lock);
dprintf("domain_interface_went_down(%i, %s)\n",
interface->domain->family, interface->name);
TRACE(("domain_interface_went_down(%i, %s)\n",
interface->domain->family, interface->name));
// domain might have been locked by:
// - domain_removed_device_interface() <--- here
// remove_interface_from_domain()
// delete_interface()
// interface_set_down()
// - datalink_control() <--- here
// interface_set_down()
invalidate_routes(interface->domain, interface);
}
void
domain_removed_device_interface(net_device_interface *interface)
domain_removed_device_interface(net_device_interface* deviceInterface)
{
MutexLocker locker(sDomainLock);
net_domain_private *domain = NULL;
net_domain_private* domain = NULL;
while (true) {
domain = (net_domain_private *)list_get_next_item(&sDomains, domain);
domain = (net_domain_private*)list_get_next_item(&sDomains, domain);
if (domain == NULL)
break;
MutexLocker locker(domain->lock);
net_interface_private *priv = find_interface(domain,
interface->device->name);
if (priv == NULL)
net_interface_private* interface = find_interface(domain,
deviceInterface->device->name);
if (interface == NULL)
continue;
remove_interface_from_domain(priv);
remove_interface_from_domain(interface);
}
}
status_t
register_domain(int family, const char *name,
struct net_protocol_module_info *module,
struct net_address_module_info *addressModule,
net_domain **_domain)
register_domain(int family, const char* name,
struct net_protocol_module_info* module,
struct net_address_module_info* addressModule,
net_domain** _domain)
{
TRACE(("register_domain(%d, %s)\n", family, name));
MutexLocker locker(sDomainLock);
struct net_domain_private *domain = lookup_domain(family);
struct net_domain_private* domain = lookup_domain(family);
if (domain != NULL)
return B_NAME_IN_USE;
domain = new (std::nothrow) net_domain_private;
domain = new(std::nothrow) net_domain_private;
if (domain == NULL)
return B_NO_MEMORY;
mutex_init_etc(&domain->lock, name, MUTEX_FLAG_CLONE_NAME);
mutex_init(&domain->lock, name);
domain->family = family;
domain->name = name;
@@ -350,18 +339,20 @@ register_domain(int family, const char *name,
status_t
unregister_domain(net_domain *_domain)
unregister_domain(net_domain* _domain)
{
TRACE(("unregister_domain(%p, %d, %s)\n", _domain, _domain->family, _domain->name));
TRACE(("unregister_domain(%p, %d, %s)\n", _domain, _domain->family,
_domain->name));
net_domain_private *domain = (net_domain_private *)_domain;
net_domain_private* domain = (net_domain_private*)_domain;
MutexLocker locker(sDomainLock);
list_remove_item(&sDomains, domain);
net_interface_private *interface = NULL;
net_interface_private* interface = NULL;
while (true) {
interface = (net_interface_private *)list_remove_head_item(&domain->interfaces);
interface = (net_interface_private*)list_remove_head_item(
&domain->interfaces);
if (interface == NULL)
break;
+143 -166
View File
@@ -1,5 +1,5 @@
/*
* Copyright 2006-2007, Haiku, Inc. All Rights Reserved.
* Copyright 2006-2009, Haiku, Inc. All Rights Reserved.
* Distributed under the terms of the MIT License.
*
* Authors:
@@ -41,11 +41,11 @@ static uint32 sDeviceIndex;
static status_t
device_consumer_thread(void *_interface)
device_consumer_thread(void* _interface)
{
net_device_interface *interface = (net_device_interface *)_interface;
net_device *device = interface->device;
net_buffer *buffer;
net_device_interface* interface = (net_device_interface*)_interface;
net_device* device = interface->device;
net_buffer* buffer;
while (true) {
ssize_t status = fifo_dequeue_buffer(&interface->receive_queue, 0,
@@ -56,19 +56,16 @@ device_consumer_thread(void *_interface)
break;
if (buffer->interface != NULL) {
// if the interface is already specified this buffer was
// if the interface is already specified, this buffer was
// delivered locally.
net_domain *domain = buffer->interface->domain;
if (domain->module->receive_data(buffer) == B_OK)
if (buffer->interface->domain->module->receive_data(buffer) == B_OK)
buffer = NULL;
} else {
// find handler for this packet
DeviceHandlerList::Iterator it2 =
DeviceHandlerList::Iterator iterator =
interface->receive_funcs.GetIterator();
while (buffer && it2.HasNext()) {
net_device_handler *handler = it2.Next();
while (buffer && iterator.HasNext()) {
net_device_handler* handler = iterator.Next();
// if the handler returns B_OK, it consumed the buffer
if (handler->type == buffer->type
@@ -77,7 +74,7 @@ device_consumer_thread(void *_interface)
}
}
if (buffer)
if (buffer != NULL)
gNetBufferModule.free(buffer);
}
@@ -85,14 +82,12 @@ device_consumer_thread(void *_interface)
}
static net_device_interface *
find_device_interface(const char *name)
static net_device_interface*
find_device_interface(const char* name)
{
DeviceInterfaceList::Iterator iterator = sInterfaces.GetIterator();
while (iterator.HasNext()) {
net_device_interface *interface = iterator.Next();
while (net_device_interface* interface = iterator.Next()) {
if (!strcmp(interface->device->name, name))
return interface;
}
@@ -101,30 +96,33 @@ find_device_interface(const char *name)
}
/*! The domain's device receive handler - this will inject the net_buffers into
the protocol layer (the domain's registered receive handler).
*/
static status_t
domain_receive_adapter(void *cookie, net_device *device, net_buffer *buffer)
domain_receive_adapter(void* cookie, net_device* device, net_buffer* buffer)
{
net_domain_private *domain = (net_domain_private *)cookie;
net_domain_private* domain = (net_domain_private*)cookie;
buffer->interface = find_interface(domain, device->index);
return domain->module->receive_data(buffer);
}
static net_device_interface *
allocate_device_interface(net_device *device, net_device_module_info *module)
static net_device_interface*
allocate_device_interface(net_device* device, net_device_module_info* module)
{
net_device_interface *interface = new (std::nothrow) net_device_interface;
net_device_interface* interface = new(std::nothrow) net_device_interface;
if (interface == NULL)
goto error_0;
return NULL;
recursive_lock_init(&interface->rx_lock, "rx lock");
recursive_lock_init(&interface->receive_lock, "interface receive lock");
char name[128];
snprintf(name, sizeof(name), "%s receive queue", device->name);
if (init_fifo(&interface->receive_queue, name, 16 * 1024 * 1024) < B_OK)
goto error_2;
goto error1;
interface->device = device;
interface->up_count = 0;
@@ -138,7 +136,7 @@ allocate_device_interface(net_device *device, net_device_module_info *module)
interface->consumer_thread = spawn_kernel_thread(device_consumer_thread,
name, B_DISPLAY_PRIORITY, interface);
if (interface->consumer_thread < B_OK)
goto error_3;
goto error2;
resume_thread(interface->consumer_thread);
// TODO: proper interface index allocation
@@ -148,20 +146,18 @@ allocate_device_interface(net_device *device, net_device_module_info *module)
sInterfaces.Add(interface);
return interface;
error_3:
error2:
uninit_fifo(&interface->receive_queue);
error_2:
recursive_lock_destroy(&interface->rx_lock);
error1:
recursive_lock_destroy(&interface->receive_lock);
delete interface;
error_0:
return NULL;
}
net_device_interface *
grab_device_interface(net_device_interface *interface)
static net_device_interface*
acquire_device_interface(net_device_interface* interface)
{
if (interface == NULL || atomic_add(&interface->ref_count, 1) == 0)
return NULL;
@@ -171,14 +167,12 @@ grab_device_interface(net_device_interface *interface)
static void
notify_device_monitors(net_device_interface *interface, int32 event)
notify_device_monitors(net_device_interface* interface, int32 event)
{
DeviceMonitorList::Iterator iterator = interface->monitor_funcs.GetIterator();
while (iterator.HasNext()) {
// when we call Next() the next item in the list is obtained
// so it's safe for the "current" item to remove itself.
net_device_monitor *monitor = iterator.Next();
DeviceMonitorList::Iterator iterator
= interface->monitor_funcs.GetIterator();
while (net_device_monitor* monitor = iterator.Next()) {
// it's safe for the "current" item to remove itself.
monitor->event(monitor, event);
}
}
@@ -187,17 +181,16 @@ notify_device_monitors(net_device_interface *interface, int32 event)
// #pragma mark - interfaces
/*!
Searches for a specific interface in a domain by name.
/*! Searches for a specific interface in a domain by name.
You need to have the domain's lock hold when calling this function.
*/
struct net_interface_private *
find_interface(struct net_domain *domain, const char *name)
struct net_interface_private*
find_interface(struct net_domain* domain, const char* name)
{
net_interface_private *interface = NULL;
net_interface_private* interface = NULL;
while (true) {
interface = (net_interface_private *)list_get_next_item(
interface = (net_interface_private*)list_get_next_item(
&domain->interfaces, interface);
if (interface == NULL)
break;
@@ -210,17 +203,16 @@ find_interface(struct net_domain *domain, const char *name)
}
/*!
Searches for a specific interface in a domain by index.
/*! Searches for a specific interface in a domain by index.
You need to have the domain's lock hold when calling this function.
*/
struct net_interface_private *
find_interface(struct net_domain *domain, uint32 index)
struct net_interface_private*
find_interface(struct net_domain* domain, uint32 index)
{
net_interface_private *interface = NULL;
net_interface_private* interface = NULL;
while (true) {
interface = (net_interface_private *)list_get_next_item(
interface = (net_interface_private*)list_get_next_item(
&domain->interfaces, interface);
if (interface == NULL)
break;
@@ -234,11 +226,10 @@ find_interface(struct net_domain *domain, uint32 index)
status_t
create_interface(net_domain *domain, const char *name, const char *baseName,
net_device_interface *deviceInterface, net_interface_private **_interface)
create_interface(net_domain* domain, const char* name, const char* baseName,
net_device_interface* deviceInterface, net_interface_private** _interface)
{
net_interface_private *interface =
new (std::nothrow) net_interface_private;
net_interface_private* interface = new(std::nothrow) net_interface_private;
if (interface == NULL)
return B_NO_MEMORY;
@@ -256,7 +247,7 @@ create_interface(net_domain *domain, const char *name, const char *baseName,
interface->type = 0;
interface->mtu = deviceInterface->device->mtu;
interface->metric = 0;
interface->device_interface = grab_device_interface(deviceInterface);
interface->device_interface = acquire_device_interface(deviceInterface);
// setup direct route for bound devices
interface->direct_route.destination = NULL;
@@ -276,7 +267,7 @@ create_interface(net_domain *domain, const char *name, const char *baseName,
// Grab a reference to the networking stack, to make sure it won't be
// unloaded as long as an interface exists
module_info *module;
module_info* module;
get_module(gNetStackInterfaceModule.info.name, &module);
*_interface = interface;
@@ -285,7 +276,7 @@ create_interface(net_domain *domain, const char *name, const char *baseName,
void
interface_set_down(net_interface *interface)
interface_set_down(net_interface* interface)
{
if ((interface->flags & IFF_UP) == 0)
return;
@@ -296,7 +287,7 @@ interface_set_down(net_interface *interface)
void
delete_interface(net_interface_private *interface)
delete_interface(net_interface_private* interface)
{
// deleting an interface is fairly complex as we need
// to clear all references to it throughout the stack
@@ -332,23 +323,23 @@ delete_interface(net_interface_private *interface)
void
put_interface(struct net_interface_private *interface)
put_interface(struct net_interface_private* interface)
{
// TODO: reference counting
// TODO: better locking scheme
mutex_unlock(&((net_domain_private *)interface->domain)->lock);
mutex_unlock(&((net_domain_private*)interface->domain)->lock);
}
struct net_interface_private *
get_interface(net_domain *_domain, const char *name)
struct net_interface_private*
get_interface(net_domain* _domain, const char* name)
{
net_domain_private *domain = (net_domain_private *)_domain;
net_domain_private* domain = (net_domain_private*)_domain;
mutex_lock(&domain->lock);
net_interface_private *interface = NULL;
net_interface_private* interface = NULL;
while (true) {
interface = (net_interface_private *)list_get_next_item(
interface = (net_interface_private*)list_get_next_item(
&domain->interfaces, interface);
if (interface == NULL)
break;
@@ -366,9 +357,9 @@ get_interface(net_domain *_domain, const char *name)
void
get_device_interface_address(net_device_interface *interface, sockaddr *_address)
get_device_interface_address(net_device_interface* interface, sockaddr* _address)
{
sockaddr_dl &address = *(sockaddr_dl *)_address;
sockaddr_dl &address = *(sockaddr_dl*)_address;
address.sdl_family = AF_LINK;
address.sdl_index = interface->device->index;
@@ -402,28 +393,24 @@ count_device_interfaces()
}
/*!
Dumps a list of all interfaces into the supplied userland buffer.
/*! Dumps a list of all interfaces into the supplied userland buffer.
If the interfaces don't fit into the buffer, an error (\c ENOBUFS) is
returned.
*/
status_t
list_device_interfaces(void *_buffer, size_t *bufferSize)
list_device_interfaces(void* _buffer, size_t* bufferSize)
{
MutexLocker locker(sInterfaceLock);
DeviceInterfaceList::Iterator iterator = sInterfaces.GetIterator();
UserBuffer buffer(_buffer, *bufferSize);
while (iterator.HasNext()) {
net_device_interface *interface = iterator.Next();
while (net_device_interface* interface = iterator.Next()) {
ifreq request;
strlcpy(request.ifr_name, interface->device->name, IF_NAMESIZE);
get_device_interface_address(interface, &request.ifr_addr);
if (buffer.Copy(&request, IF_NAMESIZE
+ request.ifr_addr.sa_len) == NULL)
if (buffer.Copy(&request, IF_NAMESIZE + request.ifr_addr.sa_len) == NULL)
return buffer.Status();
}
@@ -432,12 +419,11 @@ list_device_interfaces(void *_buffer, size_t *bufferSize)
}
/*!
Releases the reference for the interface. When all references are
/*! Releases the reference for the interface. When all references are
released, the interface is removed.
*/
void
put_device_interface(struct net_device_interface *interface)
put_device_interface(struct net_device_interface* interface)
{
if (atomic_add(&interface->ref_count, -1) != 1)
return;
@@ -451,28 +437,27 @@ put_device_interface(struct net_device_interface *interface)
status_t status;
wait_for_thread(interface->consumer_thread, &status);
net_device *device = interface->device;
net_device* device = interface->device;
const char* moduleName = device->module->info.name;
device->module->uninit_device(device);
put_module(moduleName);
recursive_lock_destroy(&interface->rx_lock);
recursive_lock_destroy(&interface->receive_lock);
delete interface;
}
/*!
Finds an interface by the specified index and grabs a reference to it.
/*! Finds an interface by the specified index and acquires a reference to it.
*/
struct net_device_interface *
struct net_device_interface*
get_device_interface(uint32 index)
{
MutexLocker locker(sInterfaceLock);
// TODO: maintain an array of all device interfaces instead
DeviceInterfaceList::Iterator iterator = sInterfaces.GetIterator();
while (iterator.HasNext()) {
net_device_interface *interface = iterator.Next();
while (net_device_interface* interface = iterator.Next()) {
if (interface->device->index == index) {
if (atomic_add(&interface->ref_count, 1) != 0)
return interface;
@@ -483,16 +468,15 @@ get_device_interface(uint32 index)
}
/*!
Finds an interface by the specified name and grabs a reference to it.
/*! Finds an interface by the specified name and grabs a reference to it.
If the interface does not yet exist, a new one is created.
*/
struct net_device_interface *
get_device_interface(const char *name, bool create)
struct net_device_interface*
get_device_interface(const char* name, bool create)
{
MutexLocker locker(sInterfaceLock);
net_device_interface *interface = find_device_interface(name);
net_device_interface* interface = find_device_interface(name);
if (interface != NULL) {
if (atomic_add(&interface->ref_count, 1) != 0)
return interface;
@@ -503,7 +487,7 @@ get_device_interface(const char *name, bool create)
if (!create)
return NULL;
void *cookie = open_module_list("network/devices");
void* cookie = open_module_list("network/devices");
if (cookie == NULL)
return NULL;
@@ -515,14 +499,15 @@ get_device_interface(const char *name, bool create)
TRACE(("get_device_interface: ask \"%s\" for %s\n", moduleName, name));
net_device_module_info *module;
if (get_module(moduleName, (module_info **)&module) == B_OK) {
net_device *device;
net_device_module_info* module;
if (get_module(moduleName, (module_info**)&module) == B_OK) {
net_device* device;
status_t status = module->init_device(name, &device);
if (status == B_OK) {
interface = allocate_device_interface(device, module);
if (interface)
if (interface != NULL)
return interface;
module->uninit_device(device);
}
put_module(moduleName);
@@ -534,9 +519,9 @@ get_device_interface(const char *name, bool create)
void
down_device_interface(net_device_interface *interface)
down_device_interface(net_device_interface* interface)
{
// RX lock must be held when calling down_device_interface.
// Receive lock must be held when calling down_device_interface.
// Known callers are `interface_protocol_down' which gets
// here via one of the following paths:
//
@@ -549,7 +534,7 @@ down_device_interface(net_device_interface *interface)
// delete_interface()
// interface_set_down()
net_device *device = interface->device;
net_device* device = interface->device;
device->flags &= ~IFF_UP;
device->module->down(device);
@@ -557,42 +542,36 @@ down_device_interface(net_device_interface *interface)
notify_device_monitors(interface, B_DEVICE_GOING_DOWN);
if (device->module->receive_data != NULL) {
thread_id reader_thread = interface->reader_thread;
// TODO when setting the interface down,
// should we clear the receive queue?
thread_id readerThread = interface->reader_thread;
// one of the callers must hold a reference to the net_device_interface
// usually it is one of the net_interfaces.
recursive_lock_unlock(&interface->rx_lock);
recursive_lock_unlock(&interface->receive_lock);
// make sure the reader thread is gone before shutting down the interface
status_t status;
wait_for_thread(reader_thread, &status);
wait_for_thread(readerThread, &status);
recursive_lock_lock(&interface->rx_lock);
recursive_lock_lock(&interface->receive_lock);
}
}
// #pragma mark - devices
// #pragma mark - devices stack API
/*!
Unregisters a previously registered deframer function.
This function is part of the net_manager_module_info API.
*/
/*! Unregisters a previously registered deframer function. */
status_t
unregister_device_deframer(net_device *device)
unregister_device_deframer(net_device* device)
{
MutexLocker locker(sInterfaceLock);
// find device interface for this device
net_device_interface *interface = find_device_interface(device->name);
net_device_interface* interface = find_device_interface(device->name);
if (interface == NULL)
return ENODEV;
RecursiveLocker _(interface->rx_lock);
RecursiveLocker _(interface->receive_lock);
if (--interface->deframe_ref_count == 0)
interface->deframe_func = NULL;
@@ -601,29 +580,27 @@ unregister_device_deframer(net_device *device)
}
/*!
Registers the deframer function for the specified \a device.
/*! Registers the deframer function for the specified \a device.
Note, however, that right now, you can only register one single
deframer function per device.
If the need arises, we might want to lift that limitation at a
later time (which would require a slight API change, though).
This function is part of the net_manager_module_info API.
*/
status_t
register_device_deframer(net_device *device, net_deframe_func deframeFunc)
register_device_deframer(net_device* device, net_deframe_func deframeFunc)
{
MutexLocker locker(sInterfaceLock);
// find device interface for this device
net_device_interface *interface = find_device_interface(device->name);
net_device_interface* interface = find_device_interface(device->name);
if (interface == NULL)
return ENODEV;
RecursiveLocker _(interface->rx_lock);
RecursiveLocker _(interface->receive_lock);
if (interface->deframe_func != NULL && interface->deframe_func != deframeFunc)
if (interface->deframe_func != NULL
&& interface->deframe_func != deframeFunc)
return B_ERROR;
interface->deframe_func = deframeFunc;
@@ -632,44 +609,46 @@ register_device_deframer(net_device *device, net_deframe_func deframeFunc)
}
/*! Registers a domain to receive net_buffers from the specified \a device. */
status_t
register_domain_device_handler(struct net_device *device, int32 type,
struct net_domain *_domain)
register_domain_device_handler(struct net_device* device, int32 type,
struct net_domain* _domain)
{
net_domain_private *domain = (net_domain_private *)_domain;
net_domain_private* domain = (net_domain_private*)_domain;
if (domain->module == NULL || domain->module->receive_data == NULL)
return B_BAD_VALUE;
return register_device_handler(device, type, &domain_receive_adapter, domain);
return register_device_handler(device, type, &domain_receive_adapter,
domain);
}
/*! Registers a receiving function callback for the specified \a device. */
status_t
register_device_handler(struct net_device *device, int32 type,
net_receive_func receiveFunc, void *cookie)
register_device_handler(struct net_device* device, int32 type,
net_receive_func receiveFunc, void* cookie)
{
MutexLocker locker(sInterfaceLock);
// find device interface for this device
net_device_interface *interface = find_device_interface(device->name);
net_device_interface* interface = find_device_interface(device->name);
if (interface == NULL)
return ENODEV;
RecursiveLocker _(interface->rx_lock);
RecursiveLocker _(interface->receive_lock);
// see if such a handler already for this device
DeviceHandlerList::Iterator iterator = interface->receive_funcs.GetIterator();
while (iterator.HasNext()) {
net_device_handler *handler = iterator.Next();
DeviceHandlerList::Iterator iterator
= interface->receive_funcs.GetIterator();
while (net_device_handler* handler = iterator.Next()) {
if (handler->type == type)
return B_ERROR;
}
// Add new handler
net_device_handler *handler = new (std::nothrow) net_device_handler;
net_device_handler* handler = new(std::nothrow) net_device_handler;
if (handler == NULL)
return B_NO_MEMORY;
@@ -681,24 +660,24 @@ register_device_handler(struct net_device *device, int32 type,
}
/*! Unregisters a previously registered device handler. */
status_t
unregister_device_handler(struct net_device *device, int32 type)
unregister_device_handler(struct net_device* device, int32 type)
{
MutexLocker locker(sInterfaceLock);
// find device interface for this device
net_device_interface *interface = find_device_interface(device->name);
net_device_interface* interface = find_device_interface(device->name);
if (interface == NULL)
return ENODEV;
RecursiveLocker _(interface->rx_lock);
RecursiveLocker _(interface->receive_lock);
// search for the handler
DeviceHandlerList::Iterator iterator = interface->receive_funcs.GetIterator();
while (iterator.HasNext()) {
net_device_handler *handler = iterator.Next();
DeviceHandlerList::Iterator iterator
= interface->receive_funcs.GetIterator();
while (net_device_handler* handler = iterator.Next()) {
if (handler->type == type) {
// found it
iterator.Remove();
@@ -711,8 +690,9 @@ unregister_device_handler(struct net_device *device, int32 type)
}
/*! Registers a device monitor for the specified device. */
status_t
register_device_monitor(net_device *device, net_device_monitor *monitor)
register_device_monitor(net_device* device, net_device_monitor* monitor)
{
if (monitor->receive == NULL || monitor->event == NULL)
return B_BAD_VALUE;
@@ -720,27 +700,28 @@ register_device_monitor(net_device *device, net_device_monitor *monitor)
MutexLocker locker(sInterfaceLock);
// find device interface for this device
net_device_interface *interface = find_device_interface(device->name);
net_device_interface* interface = find_device_interface(device->name);
if (interface == NULL)
return ENODEV;
RecursiveLocker _(interface->rx_lock);
RecursiveLocker _(interface->receive_lock);
interface->monitor_funcs.Add(monitor);
return B_OK;
}
/*! Unregisters a previously registered device monitor. */
status_t
unregister_device_monitor(net_device *device, net_device_monitor *monitor)
unregister_device_monitor(net_device* device, net_device_monitor* monitor)
{
MutexLocker locker(sInterfaceLock);
// find device interface for this device
net_device_interface *interface = find_device_interface(device->name);
net_device_interface* interface = find_device_interface(device->name);
if (interface == NULL)
return ENODEV;
RecursiveLocker _(interface->rx_lock);
RecursiveLocker _(interface->receive_lock);
// search for the monitor
@@ -756,32 +737,29 @@ unregister_device_monitor(net_device *device, net_device_monitor *monitor)
}
/*!
This function is called by device modules in case their link
/*! This function is called by device modules in case their link
state changed, ie. if an ethernet cable was plugged in or
removed.
*/
status_t
device_link_changed(net_device *device)
device_link_changed(net_device* device)
{
notify_link_changed(device);
return B_OK;
}
/*!
This function is called by device modules once their device got
/*! This function is called by device modules once their device got
physically removed, ie. a USB networking card is unplugged.
It is part of the net_manager_module_info API.
*/
status_t
device_removed(net_device *device)
device_removed(net_device* device)
{
MutexLocker locker(sInterfaceLock);
// hold a reference to the device interface being removed
// so our put_() will (eventually) do the final cleanup
net_device_interface *interface = get_device_interface(device->name, false);
net_device_interface* interface = get_device_interface(device->name, false);
if (interface == NULL)
return ENODEV;
@@ -789,7 +767,7 @@ device_removed(net_device *device)
// This is very complex, refer to delete_interface() for
// further details.
RecursiveLocker _(interface->rx_lock);
RecursiveLocker _(interface->receive_lock);
// this will possibly call:
// remove_interface_from_domain() [domain gets locked]
@@ -804,7 +782,7 @@ device_removed(net_device *device)
interface->monitor_funcs.RemoveAll();
// All of the readers should be gone as well since we are out of
// interfaces and `put_domain_datalink_protocols' is called for
// interfaces and put_domain_datalink_protocols() is called for
// each delete_interface().
put_device_interface(interface);
@@ -814,10 +792,9 @@ device_removed(net_device *device)
status_t
device_enqueue_buffer(net_device *device, net_buffer *buffer)
device_enqueue_buffer(net_device* device, net_buffer* buffer)
{
net_device_interface *interface = get_device_interface(device->index);
net_device_interface* interface = get_device_interface(device->index);
if (interface == NULL)
return ENODEV;
+37 -37
View File
@@ -1,5 +1,5 @@
/*
* Copyright 2006-2007, Haiku, Inc. All Rights Reserved.
* Copyright 2006-2009, Haiku, Inc. All Rights Reserved.
* Distributed under the terms of the MIT License.
*
* Authors:
@@ -18,7 +18,7 @@
struct net_device_handler : public DoublyLinkedListLinkImpl<net_device_handler> {
net_receive_func func;
int32 type;
void *cookie;
void* cookie;
};
typedef DoublyLinkedList<net_device_handler> DeviceHandlerList;
@@ -27,7 +27,7 @@ typedef DoublyLinkedList<net_device_monitor,
DoublyLinkedListCLink<net_device_monitor> > DeviceMonitorList;
struct net_device_interface : DoublyLinkedListLinkImpl<net_device_interface> {
struct net_device *device;
struct net_device* device;
thread_id reader_thread;
uint32 up_count;
// a device can be brought up by more than one interface
@@ -39,7 +39,7 @@ struct net_device_interface : DoublyLinkedListLinkImpl<net_device_interface> {
DeviceMonitorList monitor_funcs;
DeviceHandlerList receive_funcs;
recursive_lock rx_lock;
recursive_lock receive_lock;
thread_id consumer_thread;
net_fifo receive_queue;
@@ -49,7 +49,7 @@ typedef DoublyLinkedList<net_device_interface> DeviceInterfaceList;
struct net_interface_private : net_interface {
char base_name[IF_NAMESIZE];
net_device_interface *device_interface;
net_device_interface* device_interface;
net_route_private direct_route;
};
@@ -58,44 +58,44 @@ status_t init_interfaces();
status_t uninit_interfaces();
// interfaces
struct net_interface_private *find_interface(struct net_domain *domain,
const char *name);
struct net_interface_private *find_interface(struct net_domain *domain,
struct net_interface_private* find_interface(struct net_domain* domain,
const char* name);
struct net_interface_private* find_interface(struct net_domain* domain,
uint32 index);
void put_interface(struct net_interface_private *interface);
struct net_interface_private *get_interface(net_domain *domain,
const char *name);
status_t create_interface(net_domain *domain, const char *name,
const char *baseName, net_device_interface *deviceInterface,
struct net_interface_private **_interface);
void delete_interface(net_interface_private *interface);
void interface_set_down(net_interface *);
void put_interface(struct net_interface_private* interface);
struct net_interface_private* get_interface(net_domain* domain,
const char* name);
status_t create_interface(net_domain* domain, const char* name,
const char* baseName, net_device_interface* deviceInterface,
struct net_interface_private** _interface);
void delete_interface(net_interface_private* interface);
void interface_set_down(net_interface* interface);
// device interfaces
void get_device_interface_address(net_device_interface *interface,
sockaddr *address);
void get_device_interface_address(net_device_interface* interface,
sockaddr* address);
uint32 count_device_interfaces();
status_t list_device_interfaces(void *buffer, size_t *_bufferSize);
void put_device_interface(struct net_device_interface *interface);
struct net_device_interface *get_device_interface(uint32 index);
struct net_device_interface *get_device_interface(const char *name,
status_t list_device_interfaces(void* buffer, size_t* _bufferSize);
void put_device_interface(struct net_device_interface* interface);
struct net_device_interface* get_device_interface(uint32 index);
struct net_device_interface* get_device_interface(const char* name,
bool create = true);
void down_device_interface(net_device_interface *interface);
void down_device_interface(net_device_interface* interface);
// devices
status_t unregister_device_deframer(net_device *device);
status_t register_device_deframer(net_device *device, net_deframe_func deframeFunc);
status_t register_domain_device_handler(struct net_device *device, int32 type,
struct net_domain *domain);
status_t register_device_handler(struct net_device *device, int32 type,
net_receive_func receiveFunc, void *cookie);
status_t unregister_device_handler(struct net_device *device, int32 type);
status_t register_device_monitor(struct net_device *device,
struct net_device_monitor *monitor);
status_t unregister_device_monitor(struct net_device *device,
struct net_device_monitor *monitor);
status_t device_link_changed(net_device *device);
status_t device_removed(net_device *device);
status_t device_enqueue_buffer(net_device *device, net_buffer *buffer);
status_t unregister_device_deframer(net_device* device);
status_t register_device_deframer(net_device* device, net_deframe_func deframeFunc);
status_t register_domain_device_handler(struct net_device* device, int32 type,
struct net_domain* domain);
status_t register_device_handler(struct net_device* device, int32 type,
net_receive_func receiveFunc, void* cookie);
status_t unregister_device_handler(struct net_device* device, int32 type);
status_t register_device_monitor(struct net_device* device,
struct net_device_monitor* monitor);
status_t unregister_device_monitor(struct net_device* device,
struct net_device_monitor* monitor);
status_t device_link_changed(net_device* device);
status_t device_removed(net_device* device);
status_t device_enqueue_buffer(net_device* device, net_buffer* buffer);
#endif // INTERFACES_H