nix-vector-routing: (fixes #567) Rebuild NixVector if topology changes

This commit is contained in:
Tommaso Pecorella
2022-02-17 18:40:39 +01:00
parent 72e6105195
commit a08961be42
12 changed files with 292 additions and 274 deletions

View File

@@ -84,6 +84,8 @@ attributes of <b>WifiPhy</b> can now only be used to get the corresponding value
can be now configured through the <b>ChannelSettings</b> attribute. See the wifi model documentation
for information on how to set this new attribute.</li>
<li>UE handover now works with and without enabled CA (carrier aggregation) in inter-eNB, intra-eNB, inter-frequency and intra-frequency scenarios. Previously only inter-eNB intra-frequency handover was supported and only in non-CA scenarios. </li>
<li>NixVectorRouting: <b>NixVectorRouting</b> can now better cope with topology changes. In-flight packets are not anymore causing crashes, and
the path is dynamically rebuilt by intermediate routers (this happens only to packets in-flight during the topology change).</li>
</ul>
<hr>

View File

@@ -33,7 +33,8 @@ NixVector::NixVector ()
: m_nixVector (0),
m_used (0),
m_currentVectorBitSize (0),
m_totalBitSize (0)
m_totalBitSize (0),
m_epoch (0)
{
NS_LOG_FUNCTION (this);
@@ -49,7 +50,8 @@ NixVector::NixVector (const NixVector &o)
: m_nixVector (o.m_nixVector),
m_used (o.m_used),
m_currentVectorBitSize (o.m_currentVectorBitSize),
m_totalBitSize (o.m_totalBitSize)
m_totalBitSize (o.m_totalBitSize),
m_epoch (o.m_epoch)
{
}
@@ -64,6 +66,7 @@ NixVector::operator = (const NixVector &o)
m_used = o.m_used;
m_currentVectorBitSize = o.m_currentVectorBitSize;
m_totalBitSize = o.m_totalBitSize;
m_epoch = o.m_epoch;
return *this;
}
@@ -80,7 +83,8 @@ NixVector::Copy (void) const
/* For printing the nix vector */
std::ostream & operator << (std::ostream &os, const NixVector &nix)
{
nix.DumpNixVector (os);
nix.DumpNixVector (os);
os << " (" << nix.GetRemainingBits () << " bits left)";
return os;
}
@@ -111,7 +115,6 @@ NixVector::AddNeighborIndex (uint32_t newBits, uint32_t numberOfBits)
// because we are working with a new
// entry in the vector
m_currentVectorBitSize = numberOfBits;
m_totalBitSize += numberOfBits;
}
else
{
@@ -133,7 +136,6 @@ NixVector::AddNeighborIndex (uint32_t newBits, uint32_t numberOfBits)
// because we are working with a new
// entry in the vector
m_currentVectorBitSize = (numberOfBits - (32 - m_currentVectorBitSize));
m_totalBitSize += numberOfBits;
}
}
else
@@ -152,8 +154,8 @@ NixVector::AddNeighborIndex (uint32_t newBits, uint32_t numberOfBits)
// accordingly
m_nixVector.back () = newBits;
m_currentVectorBitSize += numberOfBits;
m_totalBitSize += numberOfBits;
}
m_totalBitSize += numberOfBits;
}
uint32_t
@@ -215,8 +217,11 @@ NixVector::GetSerializedSize (void) const
{
NS_LOG_FUNCTION (this);
uint32_t totalSizeInBytes = 0;
totalSizeInBytes = sizeof (m_used) + sizeof (m_currentVectorBitSize) +
sizeof (m_totalBitSize) + (4 * m_nixVector.size ());
totalSizeInBytes = sizeof (m_used) +
sizeof (m_currentVectorBitSize) +
sizeof (m_totalBitSize) +
(sizeof (uint32_t) * m_nixVector.size ()) +
sizeof (m_epoch);
return totalSizeInBytes;
}
@@ -226,55 +231,20 @@ NixVector::Serialize (uint32_t* buffer, uint32_t maxSize) const
{
NS_LOG_FUNCTION (this << buffer << maxSize);
uint32_t* p = buffer;
uint32_t size = 0;
if (size + 4 <= maxSize)
{
size += 4;
// grab number of used bits
*p++ = m_used;
}
else
if (maxSize < GetSerializedSize ())
{
return 0;
}
if (size + 4 <= maxSize)
{
size += 4;
// grab number of current used bits
// for the front vector
*p++ = m_currentVectorBitSize;
}
else
{
return 0;
}
if (size + 4 <= maxSize)
{
size += 4;
// grab total bit size
*p++ = m_totalBitSize;
}
else
{
return 0;
}
*p++ = m_used;
*p++ = m_currentVectorBitSize;
*p++ = m_totalBitSize;
for (uint32_t j = 0; j < m_nixVector.size (); j++)
{
if (size + 4 <= maxSize)
{
size += 4;
*p++ = m_nixVector.at (j);
}
else
{
return 0;
}
*p++ = m_nixVector.at (j);
}
// Serialized successfully
*p++ = m_epoch;
return 1;
}
@@ -283,36 +253,42 @@ NixVector::Deserialize (const uint32_t* buffer, uint32_t size)
{
NS_LOG_FUNCTION (this << buffer << size);
const uint32_t* p = buffer;
uint32_t sizeCheck = size - 4;
NS_ASSERT (sizeCheck >= 4);
NS_ASSERT_MSG (size >= 16, "NixVector minimum serialized length is 16 bytes");
if (size < 16)
{
// return zero if an entire nix-vector was
// not deserialized
return 0;
}
m_used = *p++;
sizeCheck -= 4;
NS_ASSERT (sizeCheck >= 4);
m_currentVectorBitSize = *p++;
sizeCheck -= 4;
NS_ASSERT (sizeCheck >= 4);
m_totalBitSize = *p++;
sizeCheck -= 4;
// NixVector is packed in 32-bit unsigned ints.
uint32_t nixVectorLenth = m_totalBitSize / 32 + 1;
NS_ASSERT_MSG (size >= 16 + nixVectorLenth,
"NixVector serialized length should have been " << 16 + nixVectorLenth << " but buffer is shorter");
if (size < 16 + nixVectorLenth * 4)
{
// return zero if an entire nix-vector was
// not deserialized
return 0;
}
// make sure the nix-vector
// is empty
m_nixVector.clear ();
while (sizeCheck > 0)
for (uint32_t j = 0; j < nixVectorLenth; j++)
{
NS_ASSERT (sizeCheck >= 4);
uint32_t nix = *p++;
m_nixVector.push_back (nix);
sizeCheck -= 4;
}
NS_ASSERT (sizeCheck == 0);
m_epoch = *p++;
// return zero if an entire nix-vector was
// not deserialized
return (sizeCheck != 0) ? 0 : 1;
return (GetSerializedSize ());
}
void
@@ -353,8 +329,8 @@ NixVector::DumpNixVector (std::ostream &os) const
}
}
uint32_t
NixVector::GetRemainingBits (void)
uint32_t
NixVector::GetRemainingBits (void) const
{
NS_LOG_FUNCTION (this);
@@ -441,4 +417,16 @@ NixVector::PrintDec2BinNixFill (uint32_t decimalNum, uint32_t bitCount, std::ost
}
}
void
NixVector::SetEpoch (uint32_t epoch)
{
m_epoch = epoch;
}
uint32_t
NixVector::GetEpoch () const
{
return m_epoch;
}
} // namespace ns3

View File

@@ -112,7 +112,7 @@ public:
* \return number of bits remaining in the
* nix-vector (ie m_total - m_used)
*/
uint32_t GetRemainingBits (void);
uint32_t GetRemainingBits (void) const;
/**
* \return the number of bytes required for serialization
*/
@@ -150,6 +150,17 @@ public:
*/
uint32_t BitCount (uint32_t numberOfNeighbors) const;
/**
* Set the NixVector Epoch
* \param epoch the NixVector Epoch
*/
void SetEpoch (uint32_t epoch);
/**
* Get the NixVector Epoch
* \return the NixVector Epoch
*/
uint32_t GetEpoch () const;
private:
/// Typedef: the NixVector bits storage.
@@ -189,6 +200,8 @@ private:
*/
uint32_t m_totalBitSize;
uint32_t m_epoch; //!< Epoch of the Nix-vector creation
/**
* Internal for pretty printing of nix-vector (fill)
* \param decimalNum decimal divider

View File

@@ -241,7 +241,7 @@ Packet::CreateFragment (uint32_t start, uint32_t length) const
}
void
Packet::SetNixVector (Ptr<NixVector> nixVector)
Packet::SetNixVector (Ptr<NixVector> nixVector) const
{
m_nixVector = nixVector;
}

View File

@@ -687,16 +687,20 @@ public:
/**
* \brief Set the packet nix-vector.
*
* Note: This function supports a temporary solution
* \note Note: This function supports a temporary solution
* to a specific problem in this generic class, i.e.
* how to associate something specific like nix-vector
* with a packet. This design methodology
* should _not_ be followed, and is only here as an
* impetus to fix this general issue.
*
* \warning For real this function is not const, as it is the
* setter for a mutable variable member. The const qualifier
* is needed to set a private mutable variable of const objects.
*
* \param nixVector the nix vector
*/
void SetNixVector (Ptr<NixVector> nixVector);
void SetNixVector (Ptr<NixVector> nixVector) const;
/**
* \brief Get the packet nix-vector.
*
@@ -785,7 +789,7 @@ private:
PacketMetadata m_metadata; //!< the packet's metadata
/* Please see comments above about nix-vector */
Ptr<NixVector> m_nixVector; //!< the packet's Nix vector
mutable Ptr<NixVector> m_nixVector; //!< the packet's Nix vector
static uint32_t m_globalUid; //!< Global counter of packets Uid
};

View File

@@ -53,6 +53,17 @@ net-devices are added on a node and net-devices added on the channels
associated with current node's net-devices. Please check the ``nix-simple.cc``
example below to understand how nix-vectors are calculated.
**How does Nix reacts to topology changes?**
Routes in Nix are specific to a given network topology, and are cached by
the sender node. Nix monitors the following events: Interface up/down,
Route add/removal, Address add/removal to understand if the cached routes
are valid or if they have to be purged.
If the topology changes while the packet is "in flight", the associated
NixVector is invalid, and have to be rebuilt by an intermediate node.
This is possible because the NixVecor carries an "Epoch", i.e., a counter
indicating when the NixVector has been created. If the topology changes,
the Epoch is globally updated, and any outdated NixVector is rebuilt.
|ns3| supports IPv4 as well as IPv6 Nix-Vector routing.

View File

@@ -65,7 +65,7 @@
* IPv4:
* \verbatim
Time: +7s, Nix Routing
Route Path: (Node 4 to Node 7, Nix Vector: 100011)
Route path from Node 4 to Node 7, Nix Vector: 100011 (6 bits left)
10.1.1.3 (Node 4) ----> 10.1.1.4 (Node 0)
10.1.2.1 (Node 0) ----> 10.1.2.2 (Node 1)
10.1.3.4 (Node 1) ----> 10.1.3.3 (Node 7)
@@ -74,7 +74,7 @@
* IPv6:
* \verbatim
Time: +7s, Nix Routing
Route Path: (Node 4 to Node 7, Nix Vector: 100011)
Route path from Node 4 to Node 7, Nix Vector: 100011 (6 bits left)
2001:1::200:ff:fe00:5 (Node 4) ----> fe80::200:ff:fe00:6 (Node 0)
fe80::200:ff:fe00:1 (Node 0) ----> fe80::200:ff:fe00:2 (Node 1)
fe80::200:ff:fe00:a (Node 1) ----> 2001:3::200:ff:fe00:9 (Node 7)

View File

@@ -53,7 +53,6 @@
n2 (left) IP: 10.1.2.2
n2 (right) IP: 10.1.3.1, 10.2.3.1
n3 (left) IP: 10.1.3.2, 10.2.3.2
\endverbatim
*
* Cases considered:
@@ -63,76 +62,77 @@
* - At t = +3s, Path from n0 to n1 (10.2.1.2).
* - At t = +7s, Path from n0 to n3 (10.2.3.2).
*
* Logging output:
* \verbatim
Logging output:
At time +2s client sent 1024 bytes to 10.1.3.2 port 9
At time +2.01106s server received 1024 bytes from 10.1.1.1 port 49153
At time +2.01106s server sent 1024 bytes to 10.1.1.1 port 49153
At time +2.02212s client received 1024 bytes from 10.1.3.2 port 9
\endverbatim
*
* Output in nix-simple-multi-address.routes:
* \verbatim
Time: +3s, Nix Routing
Route path from Node 0 to Node 1, Nix Vector: 0 (1 bits left)
10.2.1.1 (Node 0) ----> 10.2.1.2 (Node 1)
Output in nix-simple-multi-address.routes:
Time: +3s, Nix Routing
Route Path: (Node 0 to Node 1, Nix Vector: 0)
10.2.1.1 (Node 0) ----> 10.2.1.2 (Node 1)
Node: 0, Time: +4s, Local time: +4s, Nix Routing
NixCache:
Destination NixVector
10.1.3.2 011 (3 bits left)
IpRouteCache:
Destination Gateway Source OutputDevice
10.1.3.2 10.1.1.2 10.1.1.1 1
Node: 0, Time: +4s, Local time: +4s, Nix Routing
NixCache:
Destination NixVector
10.1.3.2 011
10.2.1.2 0
Ipv4RouteCache:
Destination Gateway Source OutputDevice
10.1.3.2 10.1.1.2 10.1.1.1 1
Node: 1, Time: +4s, Local time: +4s, Nix Routing
NixCache:
IpRouteCache:
Destination Gateway Source OutputDevice
10.1.1.1 10.1.1.1 10.1.1.2 1
10.1.3.2 10.1.2.2 10.1.2.1 2
Node: 1, Time: +4s, Local time: +4s, Nix Routing
NixCache:
Ipv4RouteCache:
Destination Gateway Source OutputDevice
10.1.1.1 10.1.1.1 10.1.1.2 1
10.1.3.2 10.1.2.2 10.1.2.1 2
Node: 2, Time: +4s, Local time: +4s, Nix Routing
NixCache:
IpRouteCache:
Destination Gateway Source OutputDevice
10.1.1.1 10.1.2.1 10.1.2.2 1
10.1.3.2 10.1.3.2 10.1.3.1 2
Node: 2, Time: +4s, Local time: +4s, Nix Routing
NixCache:
Ipv4RouteCache:
Destination Gateway Source OutputDevice
10.1.1.1 10.1.2.1 10.1.2.2 1
10.1.3.2 10.1.3.2 10.1.3.1 2
Node: 3, Time: +4s, Local time: +4s, Nix Routing
NixCache:
Destination NixVector
10.1.1.1 000 (3 bits left)
IpRouteCache:
Destination Gateway Source OutputDevice
10.1.1.1 10.1.3.1 10.1.3.2 1
Node: 3, Time: +4s, Local time: +4s, Nix Routing
NixCache:
Destination NixVector
10.1.1.1 000
Ipv4RouteCache:
Destination Gateway Source OutputDevice
10.1.1.1 10.1.3.1 10.1.3.2 1
Node: 0, Time: +6s, Local time: +6s, Nix Routing
NixCache:
IpRouteCache:
Node: 0, Time: +6s, Local time: +6s, Nix Routing
NixCache:
Ipv4RouteCache:
Node: 1, Time: +6s, Local time: +6s, Nix Routing
NixCache:
IpRouteCache:
Node: 1, Time: +6s, Local time: +6s, Nix Routing
NixCache:
Ipv4RouteCache:
Node: 2, Time: +6s, Local time: +6s, Nix Routing
NixCache:
IpRouteCache:
Node: 2, Time: +6s, Local time: +6s, Nix Routing
NixCache:
Ipv4RouteCache:
Node: 3, Time: +6s, Local time: +6s, Nix Routing
NixCache:
IpRouteCache:
Node: 3, Time: +6s, Local time: +6s, Nix Routing
NixCache:
Ipv4RouteCache:
Time: +7s, Nix Routing
Route Path: (Node 0 to Node 3, Nix Vector: 011)
10.1.1.1 (Node 0) ----> 10.1.1.2 (Node 1)
10.1.2.1 (Node 1) ----> 10.1.2.2 (Node 2)
10.1.3.1 (Node 2) ----> 10.2.3.2 (Node 3)
* \endverbatim
Time: +7s, Nix Routing
Route path from Node 0 to Node 3, Nix Vector: 011 (3 bits left)
10.1.1.1 (Node 0) ----> 10.1.1.2 (Node 1)
10.1.2.1 (Node 1) ----> 10.1.2.2 (Node 2)
10.1.3.1 (Node 2) ----> 10.2.3.2 (Node 3)
\endverbatim
*/
using namespace ns3;
NS_LOG_COMPONENT_DEFINE ("NixSimpleExample");
NS_LOG_COMPONENT_DEFINE ("NixSimpleMultiAddressExample");
int
main (int argc, char *argv[])

View File

@@ -78,114 +78,104 @@
* - Source (n1) and Destination (n1)
* It goes from n1 -> n1
* .
*
* Expected IPv4 Routing Path output for above
* cases (in the output stream):
* \verbatim
Expected IPv4 Routing Path output for above
cases (in the output stream):
Time: +3s, Nix Routing
Route Path: (Node 0 to Node 3, Nix Vector: 101)
10.1.4.1 (Node 0) ----> 10.1.4.2 (Node 2)
10.1.3.1 (Node 2) ----> 10.1.3.2 (Node 3)
Time: +3s, Nix Routing
Route path from Node 0 to Node 3, Nix Vector: 101 (3 bits left)
10.1.4.1 (Node 0) ----> 10.1.4.2 (Node 2)
10.1.3.1 (Node 2) ----> 10.1.3.2 (Node 3)
Time: +5s, Nix Routing
Route Path: (Node 1 to Node 3, Nix Vector: 101)
10.1.2.1 (Node 1) ----> 10.1.2.2 (Node 2)
10.1.3.1 (Node 2) ----> 10.1.3.2 (Node 3)
Time: +5s, Nix Routing
Route path from Node 1 to Node 3, Nix Vector: 101 (3 bits left)
10.1.2.1 (Node 1) ----> 10.1.2.2 (Node 2)
10.1.3.1 (Node 2) ----> 10.1.3.2 (Node 3)
Time: +6s, Nix Routing
Route Path: (Node 2 to Node 0, Nix Vector: 10)
10.1.4.2 (Node 2) ----> 10.1.4.1 (Node 0)
Time: +6s, Nix Routing
Route path from Node 2 to Node 0, Nix Vector: 10 (2 bits left)
10.1.4.2 (Node 2) ----> 10.1.1.1 (Node 0)
Time: +7s, Nix Routing
Route Path: (Node 1 to Node 1, Nix Vector: )
10.1.1.2 (Node 1) ----> 10.1.1.2 (Node 1)
Time: +7s, Nix Routing
Route path from Node 1 to Node 1, Nix Vector:
10.1.1.2 (Node 1) ----> 10.1.1.2 (Node 1)
Node: 0, Time: +8s, Local time: +8s, Nix Routing
NixCache:
Destination NixVector
10.1.3.2 101
Ipv4RouteCache:
Destination Gateway Source OutputDevice
10.1.3.2 10.1.4.2 10.1.4.1 2
Node: 0, Time: +8s, Local time: +8s, Nix Routing
NixCache:
Destination NixVector
10.1.3.2 101 (3 bits left)
IpRouteCache:
Destination Gateway Source OutputDevice
10.1.3.2 10.1.4.2 10.1.4.1 1
Node: 1, Time: +8s, Local time: +8s, Nix Routing
NixCache:
Destination NixVector
10.1.3.2 101
Ipv4RouteCache:
Destination Gateway Source OutputDevice
10.1.3.2 10.1.2.2 10.1.2.1 2
Node: 1, Time: +8s, Local time: +8s, Nix Routing
NixCache:
IpRouteCache:
Node: 2, Time: +8s, Local time: +8s, Nix Routing
NixCache:
Destination NixVector
10.1.1.1 10
Ipv4RouteCache:
Destination Gateway Source OutputDevice
10.1.1.1 10.1.4.1 10.1.4.2 3
10.1.3.2 10.1.3.2 10.1.3.1 2
10.1.4.1 10.1.4.1 10.1.4.2 3
Node: 2, Time: +8s, Local time: +8s, Nix Routing
NixCache:
IpRouteCache:
Destination Gateway Source OutputDevice
10.1.3.2 10.1.3.2 10.1.3.1 1
10.1.4.1 10.1.4.1 10.1.4.2 2
Node: 3, Time: +8s, Local time: +8s, Nix Routing
NixCache:
Destination NixVector
10.1.4.1 010
Ipv4RouteCache:
Destination Gateway Source OutputDevice
10.1.4.1 10.1.3.1 10.1.3.2 1
Node: 3, Time: +8s, Local time: +8s, Nix Routing
NixCache:
Destination NixVector
10.1.4.1 010 (3 bits left)
IpRouteCache:
Destination Gateway Source OutputDevice
10.1.4.1 10.1.3.1 10.1.3.2 0
\endverbatim
*
* Expected IPv6 Routing Path output for above
* cases (in the output stream):
* \verbatim
Expected IPv6 Routing Path output for above
cases (in the output stream):
Time: +3s, Nix Routing
Route Path: (Node 0 to Node 3, Nix Vector: 101)
2001:4::200:ff:fe00:7 (Node 0) ----> fe80::200:ff:fe00:8 (Node 2)
fe80::200:ff:fe00:5 (Node 2) ----> 2001:3::200:ff:fe00:6 (Node 3)
Time: +3s, Nix Routing
Route path from Node 0 to Node 3, Nix Vector: 101 (3 bits left)
2001:4::200:ff:fe00:7 (Node 0) ----> fe80::200:ff:fe00:8 (Node 2)
fe80::200:ff:fe00:5 (Node 2) ----> 2001:3::200:ff:fe00:6 (Node 3)
Time: +5s, Nix Routing
Route Path: (Node 1 to Node 3, Nix Vector: 101)
2001:2::200:ff:fe00:3 (Node 1) ----> fe80::200:ff:fe00:4 (Node 2)
fe80::200:ff:fe00:5 (Node 2) ----> 2001:3::200:ff:fe00:6 (Node 3)
Time: +5s, Nix Routing
Route path from Node 1 to Node 3, Nix Vector: 101 (3 bits left)
2001:2::200:ff:fe00:3 (Node 1) ----> fe80::200:ff:fe00:4 (Node 2)
fe80::200:ff:fe00:5 (Node 2) ----> 2001:3::200:ff:fe00:6 (Node 3)
Time: +6s, Nix Routing
Route Path: (Node 2 to Node 0, Nix Vector: 10)
2001:4::200:ff:fe00:8 (Node 2) ----> 2001:1::200:ff:fe00:1 (Node 0)
Time: +6s, Nix Routing
Route path from Node 2 to Node 0, Nix Vector: 10 (2 bits left)
2001:4::200:ff:fe00:8 (Node 2) ----> 2001:1::200:ff:fe00:1 (Node 0)
Time: +7s, Nix Routing
Route Path: (Node 1 to Node 1, Nix Vector: )
2001:1::200:ff:fe00:2 (Node 1) ----> 2001:1::200:ff:fe00:2 (Node 1)
Time: +7s, Nix Routing
Route path from Node 1 to Node 1, Nix Vector:
2001:1::200:ff:fe00:2 (Node 1) ----> 2001:1::200:ff:fe00:2 (Node 1)
Node: 0, Time: +8s, Local time: +8s, Nix Routing
NixCache:
Destination NixVector
2001:3::200:ff:fe00:6 101
IpRouteCache:
Destination Gateway Source OutputDevice
2001:3::200:ff:fe00:6 fe80::200:ff:fe00:8 2001:4::200:ff:fe00:7 1
Node: 0, Time: +8s, Local time: +8s, Nix Routing
NixCache:
Destination NixVector
2001:3::200:ff:fe00:6 101 (3 bits left)
IpRouteCache:
Destination Gateway Source OutputDevice
2001:3::200:ff:fe00:6 fe80::200:ff:fe00:8 2001:4::200:ff:fe00:7 1
Node: 1, Time: +8s, Local time: +8s, Nix Routing
NixCache:
Destination NixVector
2001:3::200:ff:fe00:6 101
IpRouteCache:
Node: 1, Time: +8s, Local time: +8s, Nix Routing
NixCache:
IpRouteCache:
Node: 2, Time: +8s, Local time: +8s, Nix Routing
NixCache:
Destination NixVector
2001:1::200:ff:fe00:1 10
IpRouteCache:
Destination Gateway Source OutputDevice
2001:3::200:ff:fe00:6 fe80::200:ff:fe00:6 fe80::200:ff:fe00:5 1
2001:4::200:ff:fe00:7 fe80::200:ff:fe00:7 fe80::200:ff:fe00:8 2
Node: 2, Time: +8s, Local time: +8s, Nix Routing
NixCache:
IpRouteCache:
Destination Gateway Source OutputDevice
2001:3::200:ff:fe00:6 fe80::200:ff:fe00:6 fe80::200:ff:fe00:5 1
2001:4::200:ff:fe00:7 fe80::200:ff:fe00:7 fe80::200:ff:fe00:8 2
Node: 3, Time: +8s, Local time: +8s, Nix Routing
NixCache:
Destination NixVector
2001:4::200:ff:fe00:7 010
IpRouteCache:
Destination Gateway Source OutputDevice
2001:4::200:ff:fe00:7 fe80::200:ff:fe00:5 2001:3::200:ff:fe00:6 0
\endverbatim
Node: 3, Time: +8s, Local time: +8s, Nix Routing
NixCache:
Destination NixVector
2001:4::200:ff:fe00:7 010 (3 bits left)
IpRouteCache:
Destination Gateway Source OutputDevice
2001:4::200:ff:fe00:7 fe80::200:ff:fe00:5 2001:3::200:ff:fe00:6 0
\endverbatim
*/
using namespace ns3;
@@ -204,35 +194,21 @@ main (int argc, char *argv[])
LogComponentEnable ("UdpEchoClientApplication", LOG_LEVEL_INFO);
LogComponentEnable ("UdpEchoServerApplication", LOG_LEVEL_INFO);
NodeContainer nodes12;
nodes12.Create (2);
NodeContainer nodes23;
nodes23.Add (nodes12.Get (1));
nodes23.Create (1);
NodeContainer nodes34;
nodes34.Add (nodes23.Get (1));
nodes34.Create (1);
NodeContainer nodes13;
nodes13.Add (nodes12.Get (0));
nodes13.Add (nodes34.Get (0));
NodeContainer nodes;
nodes.Create (4);
PointToPointHelper pointToPoint;
pointToPoint.SetDeviceAttribute ("DataRate", StringValue ("5Mbps"));
pointToPoint.SetChannelAttribute ("Delay", StringValue ("2ms"));
NodeContainer allNodes = NodeContainer (nodes12, nodes23.Get (1), nodes34.Get (1));
NetDeviceContainer devices01;
NetDeviceContainer devices12;
NetDeviceContainer devices23;
NetDeviceContainer devices34;
NetDeviceContainer devices13;
devices12 = pointToPoint.Install (nodes12);
devices23 = pointToPoint.Install (nodes23);
devices34 = pointToPoint.Install (nodes34);
devices13 = pointToPoint.Install (nodes13);
NetDeviceContainer devices02;
devices01 = pointToPoint.Install (NodeContainer (nodes.Get (0), nodes.Get (1)));
devices12 = pointToPoint.Install (NodeContainer (nodes.Get (1), nodes.Get (2)));
devices23 = pointToPoint.Install (NodeContainer (nodes.Get (2), nodes.Get (3)));
devices02 = pointToPoint.Install (NodeContainer (nodes.Get (0), nodes.Get (2)));
Address udpServerAddress;
@@ -243,7 +219,7 @@ main (int argc, char *argv[])
Ipv4NixVectorHelper nixRouting;
InternetStackHelper stack;
stack.SetRoutingHelper (nixRouting); // has effect on the next Install ()
stack.Install (allNodes);
stack.Install (nodes);
Ipv4AddressHelper address1;
address1.SetBase ("10.1.1.0", "255.255.255.0");
@@ -254,19 +230,19 @@ main (int argc, char *argv[])
Ipv4AddressHelper address4;
address4.SetBase ("10.1.4.0", "255.255.255.0");
Ipv4InterfaceContainer interfaces12 = address1.Assign (devices12);
Ipv4InterfaceContainer interfaces23 = address2.Assign (devices23);
Ipv4InterfaceContainer interfaces34 = address3.Assign (devices34);
Ipv4InterfaceContainer interfaces13 = address4.Assign (devices13);
Ipv4InterfaceContainer interfaces01 = address1.Assign (devices01);
Ipv4InterfaceContainer interfaces12 = address2.Assign (devices12);
Ipv4InterfaceContainer interfaces23 = address3.Assign (devices23);
Ipv4InterfaceContainer interfaces02 = address4.Assign (devices02);
udpServerAddress = interfaces34.GetAddress (1);
udpServerAddress = interfaces23.GetAddress (1);
// Trace routing paths for different source and destinations.
Ptr<OutputStreamWrapper> routingStream = Create<OutputStreamWrapper> ("nix-simple-ipv4.routes", std::ios::out);
nixRouting.PrintRoutingPathAt (Seconds (3), nodes12.Get (0), interfaces34.GetAddress (1), routingStream);
nixRouting.PrintRoutingPathAt (Seconds (5), nodes12.Get (1), interfaces34.GetAddress (1), routingStream);
nixRouting.PrintRoutingPathAt (Seconds (6), nodes23.Get (1), interfaces12.GetAddress (0), routingStream);
nixRouting.PrintRoutingPathAt (Seconds (7), nodes12.Get (1), interfaces12.GetAddress (1), routingStream);
nixRouting.PrintRoutingPathAt (Seconds (3), nodes.Get (0), interfaces23.GetAddress (1), routingStream);
nixRouting.PrintRoutingPathAt (Seconds (5), nodes.Get (1), interfaces23.GetAddress (1), routingStream);
nixRouting.PrintRoutingPathAt (Seconds (6), nodes.Get (2), interfaces01.GetAddress (0), routingStream);
nixRouting.PrintRoutingPathAt (Seconds (7), nodes.Get (1), interfaces01.GetAddress (1), routingStream);
// Trace routing tables
nixRouting.PrintRoutingTableAllAt (Seconds (8), routingStream);
}
@@ -277,7 +253,7 @@ main (int argc, char *argv[])
Ipv6NixVectorHelper nixRouting;
InternetStackHelper stack;
stack.SetRoutingHelper (nixRouting); // has effect on the next Install ()
stack.Install (allNodes);
stack.Install (nodes);
Ipv6AddressHelper address1;
address1.SetBase (Ipv6Address ("2001:1::"), Ipv6Prefix (64));
@@ -288,26 +264,26 @@ main (int argc, char *argv[])
Ipv6AddressHelper address4;
address4.SetBase (Ipv6Address ("2001:4::"), Ipv6Prefix (64));
Ipv6InterfaceContainer interfaces12 = address1.Assign (devices12);
Ipv6InterfaceContainer interfaces23 = address2.Assign (devices23);
Ipv6InterfaceContainer interfaces34 = address3.Assign (devices34);
Ipv6InterfaceContainer interfaces13 = address4.Assign (devices13);
Ipv6InterfaceContainer interfaces01 = address1.Assign (devices01);
Ipv6InterfaceContainer interfaces12 = address2.Assign (devices12);
Ipv6InterfaceContainer interfaces23 = address3.Assign (devices23);
Ipv6InterfaceContainer interfaces02 = address4.Assign (devices02);
udpServerAddress = interfaces34.GetAddress (1, 1);
udpServerAddress = interfaces23.GetAddress (1, 1);
// Trace routing paths for different source and destinations.
Ptr<OutputStreamWrapper> routingStream = Create<OutputStreamWrapper> ("nix-simple-ipv6.routes", std::ios::out);
nixRouting.PrintRoutingPathAt (Seconds (3), nodes12.Get (0), interfaces34.GetAddress (1, 1), routingStream);
nixRouting.PrintRoutingPathAt (Seconds (5), nodes12.Get (1), interfaces34.GetAddress (1, 1), routingStream);
nixRouting.PrintRoutingPathAt (Seconds (6), nodes23.Get (1), interfaces12.GetAddress (0, 1), routingStream);
nixRouting.PrintRoutingPathAt (Seconds (7), nodes12.Get (1), interfaces12.GetAddress (1, 1), routingStream);
nixRouting.PrintRoutingPathAt (Seconds (3), nodes.Get (0), interfaces23.GetAddress (1, 1), routingStream);
nixRouting.PrintRoutingPathAt (Seconds (5), nodes.Get (1), interfaces23.GetAddress (1, 1), routingStream);
nixRouting.PrintRoutingPathAt (Seconds (6), nodes.Get (2), interfaces01.GetAddress (0, 1), routingStream);
nixRouting.PrintRoutingPathAt (Seconds (7), nodes.Get (1), interfaces01.GetAddress (1, 1), routingStream);
// Trace routing tables
nixRouting.PrintRoutingTableAllAt (Seconds (8), routingStream);
}
UdpEchoServerHelper echoServer (9);
ApplicationContainer serverApps = echoServer.Install (nodes34.Get (1));
ApplicationContainer serverApps = echoServer.Install (nodes.Get (3));
serverApps.Start (Seconds (1.0));
serverApps.Stop (Seconds (10.0));
@@ -316,7 +292,7 @@ main (int argc, char *argv[])
echoClient.SetAttribute ("Interval", TimeValue (Seconds (1.)));
echoClient.SetAttribute ("PacketSize", UintegerValue (1024));
ApplicationContainer clientApps = echoClient.Install (nodes12.Get (0));
ApplicationContainer clientApps = echoClient.Install (nodes.Get (0));
clientApps.Start (Seconds (2.0));
clientApps.Stop (Seconds (10.0));

View File

@@ -44,6 +44,9 @@ NS_OBJECT_TEMPLATE_CLASS_DEFINE (NixVectorRouting, Ipv6RoutingProtocol);
template <typename T>
bool NixVectorRouting<T>::g_isCacheDirty = false;
template <typename T>
uint32_t NixVectorRouting<T>::g_epoch = 0;
template <typename T>
typename NixVectorRouting<T>::IpAddressToNodeMap NixVectorRouting<T>::g_ipAddressToNodeMap;
@@ -183,6 +186,7 @@ NixVectorRouting<T>::GetNixVector (Ptr<Node> source, IpAddress dest, Ptr<NetDevi
NS_LOG_FUNCTION (this << source << dest << oif);
Ptr<NixVector> nixVector = Create<NixVector> ();
nixVector->SetEpoch (g_epoch);
// not in cache, must build the nix vector
// First, we have to figure out the nodes
@@ -724,9 +728,11 @@ NixVectorRouting<T>::RouteOutput (Ptr<Packet> p, const IpHeader &header, Ptr<Net
// Build the nix-vector, given this node and the
// dest IP address
nixVectorInCache = GetNixVector (m_node, destAddress, oif);
// cache it
m_nixCache.insert (typename NixMap_t::value_type (destAddress, nixVectorInCache));
if (nixVectorInCache)
{
// cache it
m_nixCache.insert (typename NixMap_t::value_type (destAddress, nixVectorInCache));
}
}
// path exists
@@ -852,6 +858,7 @@ NixVectorRouting<T>::RouteInput (Ptr<const Packet> p, const IpHeader &header, Pt
if (!lcb.IsNull ())
{
NS_LOG_LOGIC ("Local delivery to " << destAddress);
p->SetNixVector (nullptr);
lcb (p, header, iif);
return true;
}
@@ -894,6 +901,14 @@ NixVectorRouting<T>::RouteInput (Ptr<const Packet> p, const IpHeader &header, Pt
// If nixVector isn't in packet, something went wrong
NS_ASSERT (nixVector);
if (nixVector->GetEpoch () != g_epoch)
{
NS_LOG_LOGIC ("NixVector epoch mismatch (" << nixVector->GetEpoch () << " Vs " << g_epoch
<< ") - rebuilding it");
nixVector = GetNixVector (m_node, destAddress, 0);
p->SetNixVector (nixVector);
}
// Get the interface number that we go out of, by extracting
// from the nix-vector
if (m_totalNeighbors == 0)
@@ -978,9 +993,14 @@ NixVectorRouting<T>::PrintRoutingTable (Ptr<OutputStreamWrapper> stream, Time::U
{
*os << *(it->second) << std::endl;
}
else
{
*os << "-" << std::endl;
}
}
}
*os << "IpRouteCache:" << std::endl;
*os << "IpRouteCache:" << std::endl;
if (m_ipRouteCache.size () > 0)
{
*os << std::setw (30) << "Destination";
@@ -1238,8 +1258,8 @@ NixVectorRouting<T>::PrintRoutingPath (Ptr<Node> source, IpAddress dest,
*os << std::resetiosflags (std::ios::adjustfield) << std::setiosflags (std::ios::left);
*os << "Time: " << Now().As (unit)
<< ", Nix Routing" << std::endl;
*os << "Route Path: ";
*os << "(Node " << source->GetId () << " to Node " << destNode->GetId () << ", ";
*os << "Route path from ";
*os << "Node " << source->GetId () << " to Node " << destNode->GetId () << ", ";
*os << "Nix Vector: ";
// Check the Nix cache
@@ -1253,8 +1273,6 @@ NixVectorRouting<T>::PrintRoutingPath (Ptr<Node> source, IpAddress dest,
// Build the nix-vector, given the source node and the
// dest IP address
nixVectorInCache = GetNixVector (source, dest, nullptr);
// cache it
m_nixCache.insert (typename NixMap_t::value_type (dest, nixVectorInCache));
}
if (nixVectorInCache || (!nixVectorInCache && source == destNode))
@@ -1271,7 +1289,7 @@ NixVectorRouting<T>::PrintRoutingPath (Ptr<Node> source, IpAddress dest,
*os << *nixVector;
}
*os << ")" << std::endl;
*os << std::endl;
if (source == destNode)
{
@@ -1349,6 +1367,7 @@ NixVectorRouting<T>::CheckCacheStateAndFlush (void) const
if (g_isCacheDirty)
{
FlushGlobalNixRoutingCache ();
g_epoch++;
g_isCacheDirty = false;
}
}

View File

@@ -448,6 +448,11 @@ private:
*/
static bool g_isCacheDirty;
/**
* Nix Epoch, incremented each time a flush is perfomed.
*/
static uint32_t g_epoch;
/** Cache stores nix-vectors based on destination ip */
mutable NixMap_t m_nixCache;

View File

@@ -312,21 +312,21 @@ NixVectorRoutingTest::DoRun (void)
// Test the Path
const std::string p_nSrcnAnCnDstv4 = "Time: +3s, Nix Routing\n"
"Route Path: (Node 0 to Node 4, Nix Vector: 01001)\n"
"Route path from Node 0 to Node 4, Nix Vector: 01001 (5 bits left)\n"
"10.1.0.1 (Node 0) ----> 10.1.0.2 (Node 1)\n"
"10.1.4.1 (Node 1) ----> 10.1.4.2 (Node 3)\n"
"10.1.3.1 (Node 3) ----> 10.1.3.2 (Node 4)\n\n";
NS_TEST_EXPECT_MSG_EQ (stringStream1v4.str (), p_nSrcnAnCnDstv4, "Routing Path is incorrect.");
const std::string p_nSrcnAnCnDstv6 = "Time: +3s, Nix Routing\n"
"Route Path: (Node 0 to Node 4, Nix Vector: 01001)\n"
"Route path from Node 0 to Node 4, Nix Vector: 01001 (5 bits left)\n"
"2001::200:ff:fe00:1 (Node 0) ----> fe80::200:ff:fe00:2 (Node 1)\n"
"fe80::200:ff:fe00:9 (Node 1) ----> fe80::200:ff:fe00:a (Node 3)\n"
"fe80::200:ff:fe00:7 (Node 3) ----> 2001:3::200:ff:fe00:8 (Node 4)\n\n";
NS_TEST_EXPECT_MSG_EQ (stringStream1v6.str (), p_nSrcnAnCnDstv6, "Routing Path is incorrect.");
const std::string p_nSrcnAnBnCnDstv4 = "Time: +9s, Nix Routing\n"
"Route Path: (Node 0 to Node 4, Nix Vector: 0111)\n"
"Route path from Node 0 to Node 4, Nix Vector: 0111 (4 bits left)\n"
"10.1.0.1 (Node 0) ----> 10.1.0.2 (Node 1)\n"
"10.1.1.1 (Node 1) ----> 10.1.1.2 (Node 2)\n"
"10.1.2.1 (Node 2) ----> 10.1.2.2 (Node 3)\n"
@@ -334,7 +334,7 @@ NixVectorRoutingTest::DoRun (void)
NS_TEST_EXPECT_MSG_EQ (stringStream3v4.str (), p_nSrcnAnBnCnDstv4, "Routing Path is incorrect.");
const std::string p_nSrcnAnBnCnDstv6 = "Time: +9s, Nix Routing\n"
"Route Path: (Node 0 to Node 4, Nix Vector: 0111)\n"
"Route path from Node 0 to Node 4, Nix Vector: 0111 (4 bits left)\n"
"2001::200:ff:fe00:1 (Node 0) ----> fe80::200:ff:fe00:2 (Node 1)\n"
"fe80::200:ff:fe00:3 (Node 1) ----> fe80::200:ff:fe00:4 (Node 2)\n"
"fe80::200:ff:fe00:5 (Node 2) ----> fe80::200:ff:fe00:6 (Node 3)\n"