Device Emulation (contd.): 'Resolve Neighbors' will now resend ARP/NDP requests for unresolved entries
This commit is contained in:
parent
6a7a17cd36
commit
72bab2737f
@ -625,6 +625,19 @@ void AbstractPort::clearDeviceNeighbors()
|
||||
|
||||
void AbstractPort::resolveDeviceNeighbors()
|
||||
{
|
||||
// For a user triggered 'Resolve Neighbors', the behaviour we want is
|
||||
// IP not in cache - send ARP/NDP request
|
||||
// IP present in cache, but unresolved - re-send ARP/NDP request
|
||||
// IP present in cache and resolved - don't sent ARP/NDP
|
||||
//
|
||||
// Device does not resend ARP/NDP requests if the IP address is
|
||||
// already present in the cache, irrespective of whether it is
|
||||
// resolved or not (this is done to avoid sending duplicate requests).
|
||||
//
|
||||
// So, to get the behaviour we want, let's clear all unresolved neighbors
|
||||
// before calling resolve
|
||||
deviceManager_->clearDeviceNeighbors(Device::kUnresolvedNeighbors);
|
||||
|
||||
// Resolve gateway for each device first ...
|
||||
deviceManager_->resolveDeviceGateways();
|
||||
|
||||
|
@ -265,10 +265,33 @@ void Device::resolveGateway()
|
||||
sendNeighborSolicit(ip6Gateway_);
|
||||
}
|
||||
|
||||
void Device::clearNeighbors()
|
||||
void Device::clearNeighbors(Device::NeighborSet set)
|
||||
{
|
||||
QMutableHashIterator<quint32, quint64> arpIter(arpTable_);
|
||||
QMutableHashIterator<UInt128, quint64> ndpIter(ndpTable_);
|
||||
|
||||
switch (set) {
|
||||
case kAllNeighbors:
|
||||
arpTable_.clear();
|
||||
ndpTable_.clear();
|
||||
break;
|
||||
|
||||
case kUnresolvedNeighbors:
|
||||
while (arpIter.hasNext()) {
|
||||
arpIter.next();
|
||||
if (arpIter.value() == 0)
|
||||
arpIter.remove();
|
||||
}
|
||||
|
||||
while (ndpIter.hasNext()) {
|
||||
ndpIter.next();
|
||||
if (ndpIter.value() == 0)
|
||||
ndpIter.remove();
|
||||
}
|
||||
break;
|
||||
default:
|
||||
Q_ASSERT(false); // Unreachable!
|
||||
}
|
||||
}
|
||||
|
||||
// Resolve the Neighbor IP address for this to-be-transmitted pktBuf
|
||||
@ -564,8 +587,12 @@ void Device::sendArpRequest(quint32 tgtIp)
|
||||
if (!tgtIp)
|
||||
return;
|
||||
|
||||
// Do we already have a ARP entry (resolved or unresolved)?
|
||||
// XXX: No NDP state machine for now
|
||||
// This function will be called once per unique stream - which
|
||||
// may all have the same dst IP; even if dst IP are different the
|
||||
// gateway for the different dst IP may all be same. However,
|
||||
// we don't want to send duplicate ARP requests, so we check
|
||||
// if the tgtIP is already in the cache (resolved or unresolved)
|
||||
// and if so, we don't resend it
|
||||
if (arpTable_.contains(tgtIp))
|
||||
return;
|
||||
|
||||
@ -945,7 +972,7 @@ void Device::sendNeighborSolicit(UInt128 tgtIp)
|
||||
return;
|
||||
|
||||
// Do we already have a NDP entry (resolved or unresolved)?
|
||||
// XXX: No ARP state machine for now
|
||||
// If so, don't resend (see note in sendArpRequest())
|
||||
if (ndpTable_.contains(tgtIp))
|
||||
return;
|
||||
|
||||
|
@ -39,6 +39,11 @@ class Device
|
||||
public:
|
||||
static const quint16 kVlanTpid = 0x8100;
|
||||
|
||||
enum NeighborSet {
|
||||
kAllNeighbors,
|
||||
kUnresolvedNeighbors
|
||||
};
|
||||
|
||||
public:
|
||||
Device(DeviceManager *deviceManager);
|
||||
|
||||
@ -61,7 +66,7 @@ public:
|
||||
|
||||
void resolveGateway();
|
||||
|
||||
void clearNeighbors();
|
||||
void clearNeighbors(Device::NeighborSet set);
|
||||
void resolveNeighbor(PacketBuffer *pktBuf);
|
||||
void getNeighbors(OstEmul::DeviceNeighborList *neighbors);
|
||||
|
||||
|
@ -258,10 +258,10 @@ void DeviceManager::resolveDeviceGateways()
|
||||
}
|
||||
}
|
||||
|
||||
void DeviceManager::clearDeviceNeighbors()
|
||||
void DeviceManager::clearDeviceNeighbors(Device::NeighborSet set)
|
||||
{
|
||||
foreach(Device *device, deviceList_)
|
||||
device->clearNeighbors();
|
||||
device->clearNeighbors(set);
|
||||
}
|
||||
|
||||
void DeviceManager::getDeviceNeighbors(
|
||||
|
@ -55,7 +55,7 @@ public:
|
||||
|
||||
void resolveDeviceGateways();
|
||||
|
||||
void clearDeviceNeighbors();
|
||||
void clearDeviceNeighbors(Device::NeighborSet set = Device::kAllNeighbors);
|
||||
void resolveDeviceNeighbor(PacketBuffer *pktBuf);
|
||||
void getDeviceNeighbors(OstProto::PortNeighborList *neighborList);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user