* Interface::_ChangeAddress() got the address check for equality wrong,
effectively rejecting any try to set an address. * It now copies the new address as well in order to make sure that its sa_len field is set correctly. * Improved debug output. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@37937 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -9,6 +9,7 @@
|
||||
|
||||
|
||||
#include <net/if.h>
|
||||
#include <net/if_dl.h>
|
||||
#include <net/if_media.h>
|
||||
#include <net/route.h>
|
||||
#include <new>
|
||||
@@ -477,10 +478,19 @@ datalink_is_local_link_address(net_domain* domain, bool unconfiguredOnly,
|
||||
if (domain == NULL || address == NULL || address->sa_family != AF_LINK)
|
||||
return false;
|
||||
|
||||
#ifdef TRACE_DATALINK
|
||||
uint8* data = LLADDR((sockaddr_dl*)address);
|
||||
TRACE("%s(domain %p, unconfiguredOnly %d, address %02x:%02x:%02x:%02x:%02x"
|
||||
":%02x)\n", __FUNCTION__, domain, unconfiguredOnly, data[0], data[1],
|
||||
data[2], data[3], data[4], data[5]);
|
||||
#endif
|
||||
|
||||
InterfaceAddress* interfaceAddress = get_interface_address_for_link(domain,
|
||||
address, unconfiguredOnly);
|
||||
if (interfaceAddress == NULL)
|
||||
if (interfaceAddress == NULL) {
|
||||
TRACE(" no\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (_interfaceAddress != NULL)
|
||||
*_interfaceAddress = interfaceAddress;
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
#include <KernelExport.h>
|
||||
|
||||
#include <net_device.h>
|
||||
#include <NetUtilities.h>
|
||||
|
||||
#include "device_interfaces.h"
|
||||
#include "domains.h"
|
||||
@@ -408,7 +409,10 @@ Interface::Interface(const char* interfaceName,
|
||||
TRACE("Interface %p: new \"%s\", device interface %p\n", this,
|
||||
interfaceName, deviceInterface);
|
||||
|
||||
strlcpy(name, interfaceName, IF_NAMESIZE);
|
||||
int written = strlcpy(name, interfaceName, IF_NAMESIZE);
|
||||
memset(name + written, 0, IF_NAMESIZE - written);
|
||||
// Clear remaining space
|
||||
|
||||
device = deviceInterface->device;
|
||||
|
||||
index = ++sInterfaceIndex;
|
||||
@@ -961,18 +965,27 @@ Interface::_FirstForFamily(int family)
|
||||
|
||||
status_t
|
||||
Interface::_ChangeAddress(RecursiveLocker& locker, InterfaceAddress* address,
|
||||
int32 option, const sockaddr* originalAddress, const sockaddr* newAddress)
|
||||
int32 option, const sockaddr* originalAddress,
|
||||
const sockaddr* requestedAddress)
|
||||
{
|
||||
// Copy old address over
|
||||
// Copy old address
|
||||
sockaddr_storage oldAddress;
|
||||
if (address->domain->address_module->set_to((sockaddr*)&oldAddress,
|
||||
originalAddress) != B_OK)
|
||||
oldAddress.ss_family = AF_UNSPEC;
|
||||
|
||||
// Copy new address (this also makes sure that sockaddr::sa_len is set
|
||||
// correctly)
|
||||
sockaddr_storage newAddress;
|
||||
if (address->domain->address_module->set_to((sockaddr*)&newAddress,
|
||||
requestedAddress) != B_OK)
|
||||
newAddress.ss_family = AF_UNSPEC;
|
||||
|
||||
// Test if anything changed for real
|
||||
if (!address->domain->address_module->equal_addresses(originalAddress,
|
||||
newAddress)) {
|
||||
if (address->domain->address_module->equal_addresses(
|
||||
(sockaddr*)&oldAddress, (sockaddr*)&newAddress)) {
|
||||
// Nothing to do
|
||||
TRACE(" option %" B_PRId32 " addresses are equal!\n", option);
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
@@ -984,8 +997,7 @@ Interface::_ChangeAddress(RecursiveLocker& locker, InterfaceAddress* address,
|
||||
status_t status = datalink->first_protocol->module->change_address(
|
||||
datalink->first_protocol, address, option,
|
||||
oldAddress.ss_family != AF_UNSPEC ? (sockaddr*)&oldAddress : NULL,
|
||||
newAddress != NULL && newAddress->sa_family != AF_UNSPEC
|
||||
? newAddress : NULL);
|
||||
newAddress.ss_family != AF_UNSPEC ? (sockaddr*)&newAddress : NULL);
|
||||
|
||||
locker.Lock();
|
||||
address->ReleaseReference();
|
||||
@@ -1144,6 +1156,11 @@ 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
|
||||
@@ -1358,6 +1375,7 @@ get_interface_address_for_link(net_domain* domain, const sockaddr* address,
|
||||
if (linkAddress.sdl_alen == interface->device->address.length
|
||||
&& memcmp(LLADDR(&linkAddress), interface->device->address.data,
|
||||
linkAddress.sdl_alen) == 0) {
|
||||
TRACE(" %s matches\n", interface->name);
|
||||
// link address matches
|
||||
if (unconfiguredOnly)
|
||||
return interface->FirstUnconfiguredForFamily(domain->family);
|
||||
|
||||
Reference in New Issue
Block a user