* On change_address(), arp_remove_local_enty() must not switch to the address
that caused the change (but that has not actually been changed yet). * Also, it will now reset the INADDR_ANY local address in case there is no other address configured. This should help with automatic configuring after deletion of an interface address (though it doesn't seem to work yet for some other reason, at least in VMware). git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@38110 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -436,65 +436,6 @@ arp_update_entry(in_addr_t protocolAddress, sockaddr_dl *hardwareAddress,
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
arp_remove_local_entry(arp_protocol* protocol, const sockaddr* local,
|
||||
bool updateLocalAddress)
|
||||
{
|
||||
in_addr_t inetAddress;
|
||||
|
||||
if (local == NULL) {
|
||||
// interface has not yet been set
|
||||
inetAddress = INADDR_ANY;
|
||||
} else
|
||||
inetAddress = ((sockaddr_in*)local)->sin_addr.s_addr;
|
||||
|
||||
TRACE(("%s(): address %s\n", __FUNCTION__, inet_to_string(inetAddress)));
|
||||
|
||||
MutexLocker locker(sCacheLock);
|
||||
|
||||
arp_entry* entry = arp_entry::Lookup(inetAddress);
|
||||
if (entry != NULL) {
|
||||
hash_remove(sCache, entry);
|
||||
entry->flags |= ARP_FLAG_REMOVED;
|
||||
}
|
||||
|
||||
if (updateLocalAddress && protocol->local_address == inetAddress) {
|
||||
// find new local sender address
|
||||
protocol->local_address = 0;
|
||||
|
||||
net_interface_address* address = NULL;
|
||||
while (sDatalinkModule->get_next_interface_address(protocol->interface,
|
||||
&address)) {
|
||||
if (address->local == NULL || address->local->sa_family != AF_INET)
|
||||
continue;
|
||||
|
||||
protocol->local_address
|
||||
= ((sockaddr_in*)address->local)->sin_addr.s_addr;
|
||||
}
|
||||
}
|
||||
|
||||
locker.Unlock();
|
||||
delete entry;
|
||||
}
|
||||
|
||||
|
||||
/*! Removes all entries belonging to the local interface of the \a procotol
|
||||
given.
|
||||
*/
|
||||
static void
|
||||
arp_remove_local(arp_protocol* protocol)
|
||||
{
|
||||
net_interface_address* address = NULL;
|
||||
while (sDatalinkModule->get_next_interface_address(protocol->interface,
|
||||
&address)) {
|
||||
if (address->local == NULL || address->local->sa_family != AF_INET)
|
||||
continue;
|
||||
|
||||
arp_remove_local_entry(protocol, address->local, false);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static status_t
|
||||
arp_set_local_entry(arp_protocol* protocol, const sockaddr* local)
|
||||
{
|
||||
@@ -537,6 +478,71 @@ arp_set_local_entry(arp_protocol* protocol, const sockaddr* local)
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
arp_remove_local_entry(arp_protocol* protocol, const sockaddr* local,
|
||||
net_interface_address* updateLocalAddress = NULL)
|
||||
{
|
||||
in_addr_t inetAddress;
|
||||
|
||||
if (local == NULL) {
|
||||
// interface has not yet been set
|
||||
inetAddress = INADDR_ANY;
|
||||
} else
|
||||
inetAddress = ((sockaddr_in*)local)->sin_addr.s_addr;
|
||||
|
||||
TRACE(("%s(): address %s\n", __FUNCTION__, inet_to_string(inetAddress)));
|
||||
|
||||
MutexLocker locker(sCacheLock);
|
||||
|
||||
arp_entry* entry = arp_entry::Lookup(inetAddress);
|
||||
if (entry != NULL) {
|
||||
hash_remove(sCache, entry);
|
||||
entry->flags |= ARP_FLAG_REMOVED;
|
||||
}
|
||||
|
||||
if (updateLocalAddress != NULL && protocol->local_address == inetAddress) {
|
||||
// find new local sender address
|
||||
protocol->local_address = 0;
|
||||
|
||||
net_interface_address* address = NULL;
|
||||
while (sDatalinkModule->get_next_interface_address(protocol->interface,
|
||||
&address)) {
|
||||
if (address == updateLocalAddress || address->local == NULL
|
||||
|| address->local->sa_family != AF_INET)
|
||||
continue;
|
||||
|
||||
protocol->local_address
|
||||
= ((sockaddr_in*)address->local)->sin_addr.s_addr;
|
||||
}
|
||||
}
|
||||
|
||||
locker.Unlock();
|
||||
delete entry;
|
||||
|
||||
if (protocol->local_address == 0 && updateLocalAddress) {
|
||||
// Try to keep the interface operational
|
||||
arp_set_local_entry(protocol, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*! Removes all entries belonging to the local interface of the \a procotol
|
||||
given.
|
||||
*/
|
||||
static void
|
||||
arp_remove_local(arp_protocol* protocol)
|
||||
{
|
||||
net_interface_address* address = NULL;
|
||||
while (sDatalinkModule->get_next_interface_address(protocol->interface,
|
||||
&address)) {
|
||||
if (address->local == NULL || address->local->sa_family != AF_INET)
|
||||
continue;
|
||||
|
||||
arp_remove_local_entry(protocol, address->local);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*! Creates permanent local entries for all addresses of the interface belonging
|
||||
to this protocol.
|
||||
Returns an error if no entry could be added.
|
||||
@@ -1130,7 +1136,7 @@ arp_change_address(net_datalink_protocol* _protocol,
|
||||
|
||||
if (option != SIOCAIFADDR
|
||||
&& (oldAddress == NULL || oldAddress->sa_family == AF_INET))
|
||||
arp_remove_local_entry(protocol, oldAddress, true);
|
||||
arp_remove_local_entry(protocol, oldAddress, address);
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user