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()
|
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 ...
|
// Resolve gateway for each device first ...
|
||||||
deviceManager_->resolveDeviceGateways();
|
deviceManager_->resolveDeviceGateways();
|
||||||
|
|
||||||
|
@ -265,10 +265,33 @@ void Device::resolveGateway()
|
|||||||
sendNeighborSolicit(ip6Gateway_);
|
sendNeighborSolicit(ip6Gateway_);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Device::clearNeighbors()
|
void Device::clearNeighbors(Device::NeighborSet set)
|
||||||
{
|
{
|
||||||
arpTable_.clear();
|
QMutableHashIterator<quint32, quint64> arpIter(arpTable_);
|
||||||
ndpTable_.clear();
|
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
|
// Resolve the Neighbor IP address for this to-be-transmitted pktBuf
|
||||||
@ -564,8 +587,12 @@ void Device::sendArpRequest(quint32 tgtIp)
|
|||||||
if (!tgtIp)
|
if (!tgtIp)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Do we already have a ARP entry (resolved or unresolved)?
|
// This function will be called once per unique stream - which
|
||||||
// XXX: No NDP state machine for now
|
// 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))
|
if (arpTable_.contains(tgtIp))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -945,7 +972,7 @@ void Device::sendNeighborSolicit(UInt128 tgtIp)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
// Do we already have a NDP entry (resolved or unresolved)?
|
// 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))
|
if (ndpTable_.contains(tgtIp))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -39,6 +39,11 @@ class Device
|
|||||||
public:
|
public:
|
||||||
static const quint16 kVlanTpid = 0x8100;
|
static const quint16 kVlanTpid = 0x8100;
|
||||||
|
|
||||||
|
enum NeighborSet {
|
||||||
|
kAllNeighbors,
|
||||||
|
kUnresolvedNeighbors
|
||||||
|
};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Device(DeviceManager *deviceManager);
|
Device(DeviceManager *deviceManager);
|
||||||
|
|
||||||
@ -61,7 +66,7 @@ public:
|
|||||||
|
|
||||||
void resolveGateway();
|
void resolveGateway();
|
||||||
|
|
||||||
void clearNeighbors();
|
void clearNeighbors(Device::NeighborSet set);
|
||||||
void resolveNeighbor(PacketBuffer *pktBuf);
|
void resolveNeighbor(PacketBuffer *pktBuf);
|
||||||
void getNeighbors(OstEmul::DeviceNeighborList *neighbors);
|
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_)
|
foreach(Device *device, deviceList_)
|
||||||
device->clearNeighbors();
|
device->clearNeighbors(set);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DeviceManager::getDeviceNeighbors(
|
void DeviceManager::getDeviceNeighbors(
|
||||||
|
@ -55,7 +55,7 @@ public:
|
|||||||
|
|
||||||
void resolveDeviceGateways();
|
void resolveDeviceGateways();
|
||||||
|
|
||||||
void clearDeviceNeighbors();
|
void clearDeviceNeighbors(Device::NeighborSet set = Device::kAllNeighbors);
|
||||||
void resolveDeviceNeighbor(PacketBuffer *pktBuf);
|
void resolveDeviceNeighbor(PacketBuffer *pktBuf);
|
||||||
void getDeviceNeighbors(OstProto::PortNeighborList *neighborList);
|
void getDeviceNeighbors(OstProto::PortNeighborList *neighborList);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user