nix-routing: Print Routing Path
- Add a public function `Ipv4NixVectorRouting::PrintRoutingPath` It takes source node pointer, destination IPv4 address, the OutputStreamWrapper and Time unit as input. - Add `Ipv4NixVectorHelper::PrintRoutingPathAt` which will help to schedule the printing time. Also, it exposes the function with the helper class (which is more user-friendly) - Overwrite the existing `nix-simple.cc` UDP Echo program with the PrintRoutingPath implementation. Sample Output for `src/nix-vector-routing/examples/nix-simple.cc`: ``` Time: +0s, 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: +2s, 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: (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: (Node 1 to Node 1, Nix Vector: ) 10.1.1.2 (Node 1) ----> 10.1.1.2 (Node 1) ``` Signed-off-by: Ameya Deshpande <ameyanrd@outlook.com>
This commit is contained in:
committed by
Tommaso Pecorella
parent
b8a96f327e
commit
894d786e24
@@ -23,19 +23,89 @@
|
||||
#include "ns3/ipv4-list-routing-helper.h"
|
||||
#include "ns3/ipv4-nix-vector-helper.h"
|
||||
|
||||
/*
|
||||
* Simple point to point links:
|
||||
/**
|
||||
* This program demonstrates two types of
|
||||
* trace output that are available:
|
||||
* 1) Print Routing Table for all the nodes.
|
||||
* 2) Print Routing Path, given source and destination.
|
||||
*
|
||||
* n0 -- n1 -- n2 -- n3
|
||||
*
|
||||
* n0 has UdpEchoClient
|
||||
* n3 has UdpEchoServer
|
||||
*
|
||||
* n0 IP: 10.1.1.1
|
||||
* n1 IP: 10.1.1.2, 10.1.2.1
|
||||
* n2 IP: 10.1.2.2, 10.1.3.1
|
||||
* n3 IP: 10.1.3.2
|
||||
* Simple point to point links:
|
||||
* \verbatim
|
||||
________
|
||||
/ \
|
||||
n0 -- n1 -- n2 -- n3
|
||||
|
||||
n0 IP: 10.1.1.1, 10.1.4.1
|
||||
n1 IP: 10.1.1.2, 10.1.2.1
|
||||
n2 IP: 10.1.2.2, 10.1.3.1, 10.1.4.2
|
||||
n3 IP: 10.1.3.2
|
||||
\endverbatim
|
||||
*
|
||||
* Route Path for considered cases:
|
||||
* - Source (n0) and Destination (n3)
|
||||
* It goes from n0 -> n2 -> n3
|
||||
* - Source (n1) and Destination (n3)
|
||||
* It goes from n1 -> n2 -> n3
|
||||
* - Source (n2) and Destination (n0)
|
||||
* It goes from n2 -> n0
|
||||
* - Source (n1) and Destination (n1)
|
||||
* It goes from n1 -> n1
|
||||
* .
|
||||
* \verbatim
|
||||
Expected 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: +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: +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: +7s, Nix Routing
|
||||
Route Path: (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: 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: 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: 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
|
||||
\endverbatim
|
||||
*/
|
||||
|
||||
using namespace ns3;
|
||||
@@ -47,7 +117,7 @@ main (int argc, char *argv[])
|
||||
{
|
||||
CommandLine cmd (__FILE__);
|
||||
cmd.Parse (argc, argv);
|
||||
|
||||
|
||||
LogComponentEnable ("UdpEchoClientApplication", LOG_LEVEL_INFO);
|
||||
LogComponentEnable ("UdpEchoServerApplication", LOG_LEVEL_INFO);
|
||||
|
||||
@@ -62,6 +132,10 @@ main (int argc, char *argv[])
|
||||
nodes34.Add (nodes23.Get (1));
|
||||
nodes34.Create (1);
|
||||
|
||||
NodeContainer nodes13;
|
||||
nodes13.Add (nodes12.Get (0));
|
||||
nodes13.Add (nodes34.Get (0));
|
||||
|
||||
PointToPointHelper pointToPoint;
|
||||
pointToPoint.SetDeviceAttribute ("DataRate", StringValue ("5Mbps"));
|
||||
pointToPoint.SetChannelAttribute ("Delay", StringValue ("2ms"));
|
||||
@@ -78,9 +152,11 @@ main (int argc, char *argv[])
|
||||
NetDeviceContainer devices12;
|
||||
NetDeviceContainer devices23;
|
||||
NetDeviceContainer devices34;
|
||||
NetDeviceContainer devices13;
|
||||
devices12 = pointToPoint.Install (nodes12);
|
||||
devices23 = pointToPoint.Install (nodes23);
|
||||
devices34 = pointToPoint.Install (nodes34);
|
||||
devices13 = pointToPoint.Install (nodes13);
|
||||
|
||||
Ipv4AddressHelper address1;
|
||||
address1.SetBase ("10.1.1.0", "255.255.255.0");
|
||||
@@ -88,10 +164,13 @@ main (int argc, char *argv[])
|
||||
address2.SetBase ("10.1.2.0", "255.255.255.0");
|
||||
Ipv4AddressHelper address3;
|
||||
address3.SetBase ("10.1.3.0", "255.255.255.0");
|
||||
Ipv4AddressHelper address4;
|
||||
address4.SetBase ("10.1.4.0", "255.255.255.0");
|
||||
|
||||
address1.Assign (devices12);
|
||||
address2.Assign (devices23);
|
||||
Ipv4InterfaceContainer interfaces = address3.Assign (devices34);
|
||||
Ipv4InterfaceContainer interfaces12 = address1.Assign (devices12);
|
||||
Ipv4InterfaceContainer interfaces23 = address2.Assign (devices23);
|
||||
Ipv4InterfaceContainer interfaces34 = address3.Assign (devices34);
|
||||
Ipv4InterfaceContainer interfaces13 = address4.Assign (devices13);
|
||||
|
||||
UdpEchoServerHelper echoServer (9);
|
||||
|
||||
@@ -99,7 +178,7 @@ main (int argc, char *argv[])
|
||||
serverApps.Start (Seconds (1.0));
|
||||
serverApps.Stop (Seconds (10.0));
|
||||
|
||||
UdpEchoClientHelper echoClient (interfaces.GetAddress (1), 9);
|
||||
UdpEchoClientHelper echoClient (interfaces34.GetAddress (1), 9);
|
||||
echoClient.SetAttribute ("MaxPackets", UintegerValue (1));
|
||||
echoClient.SetAttribute ("Interval", TimeValue (Seconds (1.)));
|
||||
echoClient.SetAttribute ("PacketSize", UintegerValue (1024));
|
||||
@@ -108,8 +187,13 @@ main (int argc, char *argv[])
|
||||
clientApps.Start (Seconds (2.0));
|
||||
clientApps.Stop (Seconds (10.0));
|
||||
|
||||
// Trace routing tables
|
||||
// Trace routing paths for different source and destinations.
|
||||
Ptr<OutputStreamWrapper> routingStream = Create<OutputStreamWrapper> ("nix-simple.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);
|
||||
// Trace routing tables
|
||||
nixRouting.PrintRoutingTableAllAt (Seconds (8), routingStream);
|
||||
|
||||
Simulator::Run ();
|
||||
|
||||
@@ -47,4 +47,19 @@ Ipv4NixVectorHelper::Create (Ptr<Node> node) const
|
||||
node->AggregateObject (agent);
|
||||
return agent;
|
||||
}
|
||||
|
||||
void
|
||||
Ipv4NixVectorHelper::PrintRoutingPathAt (Time printTime, Ptr<Node> source, Ipv4Address dest, Ptr<OutputStreamWrapper> stream, Time::Unit unit)
|
||||
{
|
||||
Simulator::Schedule (printTime, &Ipv4NixVectorHelper::PrintRoute, source, dest, stream, unit);
|
||||
}
|
||||
|
||||
void
|
||||
Ipv4NixVectorHelper::PrintRoute (Ptr<Node> source, Ipv4Address dest, Ptr<OutputStreamWrapper> stream, Time::Unit unit)
|
||||
{
|
||||
Ptr<Ipv4NixVectorRouting> rp = Ipv4RoutingHelper::GetRouting <Ipv4NixVectorRouting> (source->GetObject<Ipv4> ()->GetRoutingProtocol ());
|
||||
NS_ASSERT (rp);
|
||||
rp->PrintRoutingPath (source, dest, stream, unit);
|
||||
}
|
||||
|
||||
} // namespace ns3
|
||||
|
||||
@@ -66,6 +66,22 @@ public:
|
||||
*/
|
||||
virtual Ptr<Ipv4RoutingProtocol> Create (Ptr<Node> node) const;
|
||||
|
||||
/**
|
||||
* \brief prints the routing path for a source and destination at a particular time.
|
||||
* If the routing path does not exist, it prints that the path does not exist between
|
||||
* the nodes in the ostream.
|
||||
* \param printTime the time at which the routing path is supposed to be printed.
|
||||
* \param source the source node pointer to start traversing
|
||||
* \param dest the IPv4 destination address
|
||||
* \param stream the output stream object to use
|
||||
* \param unit the time unit to be used in the report
|
||||
*
|
||||
* This method calls the PrintRoutingPath() method of the
|
||||
* Ipv4NixVectorRouting for the source and destination to provide
|
||||
* the routing path at the specified time.
|
||||
*/
|
||||
void PrintRoutingPathAt (Time printTime, Ptr<Node> source, Ipv4Address dest, Ptr<OutputStreamWrapper> stream, Time::Unit unit = Time::S);
|
||||
|
||||
private:
|
||||
/**
|
||||
* \brief Assignment operator declared private and not implemented to disallow
|
||||
@@ -75,6 +91,20 @@ private:
|
||||
Ipv4NixVectorHelper &operator = (const Ipv4NixVectorHelper &);
|
||||
|
||||
ObjectFactory m_agentFactory; //!< Object factory
|
||||
|
||||
/**
|
||||
* \brief prints the routing path for the source and destination. If the routing path
|
||||
* does not exist, it prints that the path does not exist between the nodes in the ostream.
|
||||
* \param source the source node pointer to start traversing
|
||||
* \param dest the IPv4 destination address
|
||||
* \param stream the output stream object to use
|
||||
* \param unit the time unit to be used in the report
|
||||
*
|
||||
* This method calls the PrintRoutingPath() method of the
|
||||
* Ipv4NixVectorRouting for the source and destination to provide
|
||||
* the routing path.
|
||||
*/
|
||||
static void PrintRoute (Ptr<Node> source, Ipv4Address dest, Ptr<OutputStreamWrapper> stream, Time::Unit unit = Time::S);
|
||||
};
|
||||
} // namespace ns3
|
||||
|
||||
|
||||
@@ -968,6 +968,127 @@ Ipv4NixVectorRouting::BFS (uint32_t numberOfNodes, Ptr<Node> source,
|
||||
return false;
|
||||
}
|
||||
|
||||
void
|
||||
Ipv4NixVectorRouting::PrintRoutingPath (Ptr<Node> source, Ipv4Address dest,
|
||||
Ptr<OutputStreamWrapper> stream, Time::Unit unit)
|
||||
{
|
||||
NS_LOG_FUNCTION (this << source << dest);
|
||||
Ptr<NixVector> nixVectorInCache;
|
||||
Ptr<NixVector> nixVector;
|
||||
Ptr<Ipv4Route> rtentry;
|
||||
|
||||
Ptr<Node> destNode = GetNodeByIp (dest);
|
||||
|
||||
std::ostream* os = stream->GetStream ();
|
||||
// Copy the current ostream state
|
||||
std::ios oldState (nullptr);
|
||||
oldState.copyfmt (*os);
|
||||
|
||||
*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 << "Nix Vector: ";
|
||||
|
||||
nixVectorInCache = GetNixVectorInCache (dest);
|
||||
|
||||
// not in cache
|
||||
if (!nixVectorInCache)
|
||||
{
|
||||
NS_LOG_LOGIC ("Nix-vector not in cache, build: ");
|
||||
// Build the nix-vector, given the source node and the
|
||||
// dest IP address
|
||||
nixVectorInCache = GetNixVector (source, dest, nullptr);
|
||||
}
|
||||
|
||||
if (nixVectorInCache || (!nixVectorInCache && source == destNode))
|
||||
{
|
||||
Ptr<Node> curr = source;
|
||||
|
||||
if (nixVectorInCache)
|
||||
{
|
||||
// cache it
|
||||
m_nixCache.insert (NixMap_t::value_type (dest, nixVectorInCache));
|
||||
// Make a NixVector copy to work with. This is because
|
||||
// we don't want to extract the bits from nixVectorInCache
|
||||
// which is stored in the m_nixCache.
|
||||
nixVector = Create<NixVector> ();
|
||||
nixVector = nixVectorInCache->Copy ();
|
||||
|
||||
*os << *nixVector;
|
||||
}
|
||||
*os << ")" << std::endl;
|
||||
|
||||
if (source == destNode)
|
||||
{
|
||||
std::ostringstream src, dst;
|
||||
src << dest << " (Node " << destNode->GetId () << ")";
|
||||
*os << std::setw (20) << src.str ();
|
||||
dst << "----> " << dest << " (Node " << destNode->GetId () << ")";
|
||||
*os << dst.str () << std::endl;
|
||||
}
|
||||
|
||||
while (curr != destNode)
|
||||
{
|
||||
// set m_node as current node
|
||||
// and find the total neighbors
|
||||
SetNode (curr);
|
||||
m_totalNeighbors = FindTotalNeighbors ();
|
||||
// Get the number of bits required
|
||||
// to represent all the neighbors
|
||||
uint32_t numberOfBits = nixVector->BitCount (m_totalNeighbors);
|
||||
// Get the nixIndex
|
||||
uint32_t nixIndex = nixVector->ExtractNeighborIndex (numberOfBits);
|
||||
// gatewayIP is the IP of next
|
||||
// node on channel found from nixIndex
|
||||
Ipv4Address gatewayIp;
|
||||
// Get the Net Device index from the nixIndex
|
||||
uint32_t NetDeviceIndex = FindNetDeviceForNixIndex (nixIndex, gatewayIp);
|
||||
// Get the interfaceIndex with the help of NetDeviceIndex.
|
||||
// It will be used to get the IP address on interfaceIndex
|
||||
// interface of 'curr' node.
|
||||
Ptr<Ipv4> ipv4 = curr->GetObject<Ipv4> ();
|
||||
Ptr<NetDevice> outDevice = curr->GetDevice (NetDeviceIndex);
|
||||
uint32_t interfaceIndex = ipv4->GetInterfaceForDevice (outDevice);
|
||||
Ipv4Address sourceIPAddr = ipv4->GetAddress (interfaceIndex, 0).GetLocal ();
|
||||
|
||||
rtentry = GetIpv4RouteInCache (dest);
|
||||
if (!rtentry)
|
||||
{
|
||||
NS_LOG_LOGIC ("Ipv4Route not in cache, build: ");
|
||||
// start filling in the Ipv4Route info
|
||||
rtentry = Create<Ipv4Route> ();
|
||||
rtentry->SetSource (sourceIPAddr);
|
||||
|
||||
rtentry->SetGateway (gatewayIp);
|
||||
rtentry->SetDestination (dest);
|
||||
rtentry->SetOutputDevice (outDevice);
|
||||
// add rtentry to cache
|
||||
m_ipv4RouteCache.insert (Ipv4RouteMap_t::value_type (dest, rtentry));
|
||||
}
|
||||
|
||||
std::ostringstream currNode, nextNode;
|
||||
currNode << sourceIPAddr << " (Node " << curr->GetId () << ")";
|
||||
*os << std::setw (20) << currNode.str ();
|
||||
// Replace curr with the next node
|
||||
curr = GetNodeByIp (gatewayIp);
|
||||
nextNode << "----> " << gatewayIp << " (Node " << curr->GetId () << ")";
|
||||
*os << nextNode.str () << std::endl;
|
||||
}
|
||||
*os << std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
*os << ")" << std::endl;
|
||||
// No Route exists
|
||||
*os << "There does not exist a path from Node " << source->GetId ()
|
||||
<< " to Node " << destNode->GetId () << "." << std::endl;
|
||||
}
|
||||
// Restore the previous ostream state
|
||||
(*os).copyfmt (oldState);
|
||||
}
|
||||
|
||||
void
|
||||
Ipv4NixVectorRouting::CheckCacheStateAndFlush (void) const
|
||||
{
|
||||
|
||||
@@ -89,6 +89,16 @@ public:
|
||||
*/
|
||||
void FlushGlobalNixRoutingCache (void) const;
|
||||
|
||||
/**
|
||||
* @brief Print the Routing Path according to Nix Routing
|
||||
* \param source Source node
|
||||
* \param dest Destination node address
|
||||
* \param stream The ostream the Routing path is printed to
|
||||
* \param unit the time unit to be used in the report
|
||||
*/
|
||||
void PrintRoutingPath (Ptr<Node> source, Ipv4Address dest, Ptr<OutputStreamWrapper> stream, Time::Unit unit);
|
||||
|
||||
|
||||
private:
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user