diff --git a/src/add-ons/kernel/network/devices/ethernet/ethernet.cpp b/src/add-ons/kernel/network/devices/ethernet/ethernet.cpp index 6889739442..3c213b2677 100644 --- a/src/add-ons/kernel/network/devices/ethernet/ethernet.cpp +++ b/src/add-ons/kernel/network/devices/ethernet/ethernet.cpp @@ -67,6 +67,11 @@ update_link_state(ethernet_device *device, bool notify = true) device->link_quality = state.quality; device->link_speed = state.speed; + if (device->media & IFM_ACTIVE) + device->flags |= IFF_LINK; + else + device->flags &= ~IFF_LINK; + dprintf("%s: media change, media 0x%0x quality %u speed %u\n", device->name, (unsigned int)device->media, (unsigned int)device->link_quality, @@ -132,7 +137,7 @@ ethernet_init(const char *name, net_device **_device) memset(device, 0, sizeof(ethernet_device)); strcpy(device->name, name); - device->flags = IFF_BROADCAST; + device->flags = IFF_BROADCAST | IFF_LINK; device->type = IFT_ETHER; device->mtu = 1500; device->media = IFM_ACTIVE | IFM_ETHER; diff --git a/src/add-ons/kernel/network/devices/loopback/loopback.cpp b/src/add-ons/kernel/network/devices/loopback/loopback.cpp index 53e79d71ba..aec82415ca 100644 --- a/src/add-ons/kernel/network/devices/loopback/loopback.cpp +++ b/src/add-ons/kernel/network/devices/loopback/loopback.cpp @@ -15,6 +15,7 @@ #include #include +#include #include #include #include @@ -85,9 +86,10 @@ loopback_init(const char *name, net_device **_device) memset(device, 0, sizeof(loopback_device)); strcpy(device->name, name); - device->flags = IFF_LOOPBACK; + device->flags = IFF_LOOPBACK | IFF_LINK; device->type = IFT_LOOP; device->mtu = 16384; + device->media = IFM_ACTIVE; *_device = device; return B_OK; diff --git a/src/add-ons/kernel/network/stack/datalink.cpp b/src/add-ons/kernel/network/stack/datalink.cpp index 851967b35e..760bdc7b4f 100644 --- a/src/add-ons/kernel/network/stack/datalink.cpp +++ b/src/add-ons/kernel/network/stack/datalink.cpp @@ -619,7 +619,7 @@ interface_protocol_control(net_datalink_protocol *_protocol, { // get flags struct ifreq request; - request.ifr_flags = interface->flags; + request.ifr_flags = interface->flags | interface->device->flags; return user_memcpy(&((struct ifreq *)argument)->ifr_flags, &request.ifr_flags, sizeof(request.ifr_flags)); diff --git a/src/add-ons/kernel/network/stack/domains.cpp b/src/add-ons/kernel/network/stack/domains.cpp index 946e4772d7..bc1c019142 100644 --- a/src/add-ons/kernel/network/stack/domains.cpp +++ b/src/add-ons/kernel/network/stack/domains.cpp @@ -219,30 +219,30 @@ domain_interface_control(net_domain_private *domain, int32 option, net_interface *interface = find_interface(domain, name); if (interface != NULL) { switch (option) { - case SIOCDIFADDR: - remove_interface_from_domain(interface); - break; + case SIOCDIFADDR: + remove_interface_from_domain(interface); + break; - case SIOCSIFFLAGS: - if (((uint32)request->ifr_flags & IFF_UP) - != (interface->flags & IFF_UP)) { - if (interface->flags & IFF_UP) { - interface_set_down(interface); - } else { - status = interface->first_info->interface_up( - interface->first_protocol); - if (status == B_OK) { - interface->flags |= IFF_UP; - // TODO this doesn't belong here - if (interface->device->media & IFM_ACTIVE) - interface->flags |= IFF_LINK; + 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) - interface->flags |= request->ifr_flags & ~(IFF_UP | IFF_LINK); - break; + if (status == B_OK) + interface->flags |= request->ifr_flags; + break; + } } } } @@ -256,38 +256,6 @@ domain_interface_control(net_domain_private *domain, int32 option, } -void -domain_interfaces_link_changed(net_device *device) -{ - // TODO: notify listeners about this! - - BenaphoreLocker locker(sDomainLock); - - net_domain_private *domain = NULL; - while (true) { - domain = (net_domain_private *)list_get_next_item(&sDomains, domain); - if (domain == NULL) - break; - - BenaphoreLocker locker(domain->lock); - - net_interface *interface = NULL; - while (true) { - interface = (net_interface *)list_get_next_item(&domain->interfaces, - interface); - if (interface == NULL) - break; - - if (interface->device == device) { - // update IFF_LINK flag - interface->flags = (interface->flags & ~IFF_LINK) - | (device->media & IFM_ACTIVE ? IFF_LINK : 0); - } - } - } -} - - void domain_interface_went_down(net_interface *interface) { diff --git a/src/add-ons/kernel/network/stack/domains.h b/src/add-ons/kernel/network/stack/domains.h index 83252f5d0f..89b72f9b47 100644 --- a/src/add-ons/kernel/network/stack/domains.h +++ b/src/add-ons/kernel/network/stack/domains.h @@ -36,7 +36,6 @@ uint32 count_domain_interfaces(); status_t list_domain_interfaces(void *buffer, size_t *_bufferSize); status_t add_interface_to_domain(net_domain *domain, struct ifreq& request); status_t remove_interface_from_domain(net_interface *interface); -void domain_interfaces_link_changed(net_device *device); void domain_interface_went_down(net_interface *); void domain_removed_device_interface(net_device_interface *); status_t domain_interface_control(net_domain_private *domain, int32 option, diff --git a/src/add-ons/kernel/network/stack/interfaces.cpp b/src/add-ons/kernel/network/stack/interfaces.cpp index 37e3f62459..32ce044f79 100644 --- a/src/add-ons/kernel/network/stack/interfaces.cpp +++ b/src/add-ons/kernel/network/stack/interfaces.cpp @@ -141,7 +141,7 @@ create_interface(net_domain *domain, const char *name, const char *baseName, interface->mask = NULL; interface->index = ++sInterfaceIndex; - interface->flags = deviceInterface->device->flags & ~IFF_UP; + interface->flags = 0; interface->type = 0; interface->mtu = deviceInterface->device->mtu; interface->metric = 0; @@ -169,8 +169,7 @@ interface_set_down(net_interface *interface) if ((interface->flags & IFF_UP) == 0) return; - // TODO: IFF_LINK should belong in device only - interface->flags &= ~(IFF_UP | IFF_LINK); + interface->flags &= ~IFF_UP; interface->first_info->interface_down(interface->first_protocol); } @@ -658,7 +657,6 @@ unregister_device_monitor(struct net_device *device, status_t device_link_changed(net_device *device) { - domain_interfaces_link_changed(device); return B_OK; }