25 #include "ns3/abort.h" 26 #include "ns3/names.h" 27 #include "ns3/ipv4-list-routing.h" 28 #include "ns3/loopback-net-device.h" 46 .SetGroupName (
"NixVectorRouting")
53 : m_totalNeighbors (0)
107 rp->FlushNixCache ();
108 rp->FlushIpv4RouteCache ();
150 if (source == destNode)
159 std::vector< Ptr<Node> > parentVector;
222 for (uint32_t i = 0; i < numberOfDevices; i++)
248 if (parentVector.at (dest) == 0)
253 Ptr<Node> parentNode = parentVector.at (dest);
255 uint32_t numberOfDevices = parentNode->
GetNDevices ();
257 uint32_t totalNeighbors = 0;
261 for (uint32_t i = 0; i < numberOfDevices; i++)
267 if (localNetDevice->IsBridge ())
290 Ptr<Node> remoteNode = (*iter)->GetNode ();
292 if (remoteNode->
GetId () == dest)
294 destId = totalNeighbors + offset;
299 totalNeighbors += netDeviceContainer.
GetN ();
302 << nixVector->
BitCount (totalNeighbors) <<
" bits, for node " << parentNode->
GetId ());
307 BuildNixVector (parentVector, source, (parentVector.at (dest))->GetId (), nixVector);
316 for (std::size_t i = 0; i <
channel->GetNDevices (); i++)
319 if (remoteDevice != netDevice)
326 NS_LOG_LOGIC (
"Looking through bridge ports of bridge net device " << bd);
327 for (uint32_t j = 0; j < bd->GetNBridgePorts (); ++j)
330 if (ndBridged == remoteDevice)
332 NS_LOG_LOGIC (
"That bridge port is me, don't walk backward");
345 netDeviceContainer.
Add (
channel->GetDevice (i));
365 for (uint32_t deviceId = 0; deviceId < numberOfDevices; deviceId++)
370 if ( !DynamicCast<LoopbackNetDevice>(device) )
372 int32_t interfaceIndex = (ipv4)->GetInterfaceForDevice (node->
GetDevice (deviceId));
373 if (interfaceIndex != -1)
375 uint32_t numberOfAddresses = ipv4->GetNAddresses (interfaceIndex);
376 for (uint32_t addressIndex = 0; addressIndex < numberOfAddresses; addressIndex++)
382 "Duplicate IPv4 address (" << addr <<
") found during NIX Vector map construction for node " << node->
GetId ());
384 NS_LOG_LOGIC (
"Adding IPv4 address " << addr <<
" for node " << node->
GetId () <<
" to NIX Vector IPv4 address to node map");
411 NS_LOG_ERROR (
"Couldn't find dest node given the IP" << dest);
416 destNode = iter ->
second;
426 uint32_t totalNeighbors = 0;
430 for (uint32_t i = 0; i < numberOfDevices; i++)
447 totalNeighbors += netDeviceContainer.
GetN ();
450 return totalNeighbors;
467 for (uint32_t i = 0; i < nDevices; ++i)
472 if (ndTest->IsBridge ())
474 NS_LOG_LOGIC (
"device " << i <<
" is a bridge net device");
476 NS_ABORT_MSG_UNLESS (bnd,
"Ipv4NixVectorRouting::NetDeviceIsBridged (): GetObject for <BridgeNetDevice> failed");
478 for (uint32_t j = 0; j < bnd->GetNBridgePorts (); ++j)
480 NS_LOG_LOGIC (
"Examine bridge port " << j <<
" " << bnd->GetBridgePort (j));
481 if (bnd->GetBridgePort (j) == nd)
483 NS_LOG_LOGIC (
"Net device " << nd <<
" is bridged by " << bnd);
489 NS_LOG_LOGIC (
"Net device " << nd <<
" is not bridged");
498 uint32_t totalNeighbors = 0;
502 for (uint32_t i = 0; i < numberOfDevices; i++)
520 if (nodeIndex < (totalNeighbors + netDeviceContainer.
GetN ()))
524 Ptr<NetDevice> gatewayDevice = netDeviceContainer.
Get (nodeIndex-totalNeighbors);
525 Ptr<Node> gatewayNode = gatewayDevice->GetNode ();
528 uint32_t interfaceIndex = (ipv4)->GetInterfaceForDevice (gatewayDevice);
533 totalNeighbors += netDeviceContainer.
GetN ();
554 if (!nixVectorInCache)
566 if (nixVectorInCache)
568 NS_LOG_LOGIC (
"Nix-vector contents: " << *nixVectorInCache);
572 nixVectorForPacket = nixVectorInCache->
Copy ();
605 int32_t interfaceIndex = 0;
613 interfaceIndex = (
m_ipv4)->GetInterfaceForDevice (oif);
616 NS_ASSERT_MSG (interfaceIndex != -1,
"Interface index not found for device");
621 rtentry = Create<Ipv4Route> ();
648 NS_LOG_LOGIC (
"Adding Nix-vector to packet: " << *nixVectorForPacket);
673 uint32_t iif =
m_ipv4->GetInterfaceForDevice (idev);
681 lcb (p, header, iif);
723 rtentry = Create<Ipv4Route> ();
735 " bits from Nix-vector: " << nixVector <<
" : " << *nixVector);
741 ucb (rtentry, p, header);
754 std::ios oldState (
nullptr);
755 oldState.copyfmt (*os);
757 *os << std::resetiosflags (std::ios::adjustfield) << std::setiosflags (std::ios::left);
759 *os <<
"Node: " <<
m_ipv4->GetObject<
Node> ()->GetId ()
760 <<
", Time: " <<
Now().
As (unit)
761 <<
", Local time: " <<
m_ipv4->GetObject<
Node> ()->GetLocalTime ().As (unit)
762 <<
", Nix Routing" << std::endl;
764 *os <<
"NixCache:" << std::endl;
767 *os <<
"Destination NixVector" << std::endl;
770 std::ostringstream dest;
772 *os << std::setw (16) << dest.str ();
773 *os << *(it->second) << std::endl;
776 *os <<
"Ipv4RouteCache:" << std::endl;
779 *os <<
"Destination Gateway Source OutputDevice" << std::endl;
782 std::ostringstream dest, gw, src;
783 dest << it->second->GetDestination ();
784 *os << std::setw (16) << dest.str ();
785 gw << it->second->GetGateway ();
786 *os << std::setw (16) << gw.str ();
787 src << it->second->GetSource ();
788 *os << std::setw (16) << src.str ();
796 *os << it->second->GetOutputDevice ()->GetIfIndex ();
803 (*os).copyfmt (oldState);
836 std::queue< Ptr<Node> > greyNodeList;
839 parentVector.assign (numberOfNodes, 0);
842 greyNodeList.push (source);
843 parentVector.at (source->
GetId ()) = source;
846 while (greyNodeList.size () != 0)
848 Ptr<Node> currNode = greyNodeList.front ();
851 if (currNode == dest)
860 if (currNode == source && oif)
865 uint32_t interfaceIndex = (ipv4)->GetInterfaceForDevice (oif);
866 if (!(ipv4->IsUp (interfaceIndex)))
872 if (!(oif->IsLinkUp ()))
894 Ptr<Node> remoteNode = (*iter)->GetNode ();
900 if (parentVector.at (remoteNode->
GetId ()) == 0)
902 parentVector.at (remoteNode->
GetId ()) = currNode;
903 greyNodeList.push (remoteNode);
911 for (uint32_t i = 0; i < (currNode->
GetNDevices ()); i++)
921 uint32_t interfaceIndex = (ipv4)->GetInterfaceForDevice (currNode->
GetDevice (i));
922 if (!(ipv4->IsUp (interfaceIndex)))
928 if (!(localNetDevice->IsLinkUp ()))
950 Ptr<Node> remoteNode = (*iter)->GetNode ();
956 if (parentVector.at (remoteNode->
GetId ()) == 0)
958 parentVector.at (remoteNode->
GetId ()) = currNode;
959 greyNodeList.push (remoteNode);
994 std::ios oldState (
nullptr);
995 oldState.copyfmt (*os);
997 *os << std::resetiosflags (std::ios::adjustfield) << std::setiosflags (std::ios::left);
998 *os <<
"Time: " <<
Now().
As (unit)
999 <<
", Nix Routing" << std::endl;
1000 *os <<
"Route Path: ";
1001 *os <<
"(Node " << source->
GetId () <<
" to Node " << destNode->
GetId () <<
", ";
1002 *os <<
"Nix Vector: ";
1007 if (!nixVectorInCache)
1012 nixVectorInCache =
GetNixVector (source, dest,
nullptr);
1015 if (nixVectorInCache || (!nixVectorInCache && source == destNode))
1018 uint32_t totalNeighbors = 0;
1020 if (nixVectorInCache)
1023 m_nixCache.insert (NixMap_t::value_type (dest, nixVectorInCache));
1027 nixVector = nixVectorInCache->
Copy ();
1031 *os <<
")" << std::endl;
1033 if (source == destNode)
1035 std::ostringstream src, dst;
1036 src << dest <<
" (Node " << destNode->
GetId () <<
")";
1037 *os << std::setw (20) << src.str ();
1038 dst <<
"----> " << dest <<
" (Node " << destNode->
GetId () <<
")";
1039 *os << dst.str () << std::endl;
1042 while (curr != destNode)
1047 uint32_t numberOfBits = nixVector->
BitCount (totalNeighbors);
1060 uint32_t interfaceIndex = ipv4->GetInterfaceForDevice (outDevice);
1064 sourceIPAddr = ipv4->SourceAddressSelection (interfaceIndex, dest);
1070 sourceIPAddr = ipv4->GetAddress (interfaceIndex, 0).GetLocal ();
1073 std::ostringstream currNode, nextNode;
1074 currNode << sourceIPAddr <<
" (Node " << curr->
GetId () <<
")";
1075 *os << std::setw (20) << currNode.str ();
1078 nextNode <<
"----> " << ((curr == destNode) ? dest : gatewayIp) <<
" (Node " << curr->GetId () <<
")";
1079 *os << nextNode.str () << std::endl;
1085 *os <<
")" << std::endl;
1087 *os <<
"There does not exist a path from Node " << source->
GetId ()
1088 <<
" to Node " << destNode->
GetId () <<
"." << std::endl;
1091 (*os).copyfmt (oldState);
void FlushGlobalNixRoutingCache(void) const
Called when run-time link topology change occurs which iterates through the node list and flushes any...
TimeWithUnit As(const enum Unit unit=Time::AUTO) const
Attach a unit to a Time, to facilitate output in a specific unit.
void BuildIpv4AddressToNodeMap(void) const
Build map from IPv4 Address to Node for faster lookup.
Ptr< NetDevice > Get(uint32_t i) const
Get the Ptr<NetDevice> stored in this container at a given index.
Smart pointer class similar to boost::intrusive_ptr.
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by "...
static uint32_t GetNNodes(void)
uint32_t GetId(void) const
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Iterator End(void) const
Get an iterator which indicates past-the-last NetDevice in the container.
bool BuildNixVectorLocal(Ptr< NixVector > nixVector)
Special variation of BuildNixVector for when a node is sending to itself.
Ptr< NetDevice > GetDevice(uint32_t index) const
Retrieve the index-th NetDevice associated to this node.
Ptr< Node > GetNodeByIp(Ipv4Address dest) const
Iterates through the node list and finds the one corresponding to the given Ipv4Address.
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file...
virtual void PrintRoutingTable(Ptr< OutputStreamWrapper > stream, Time::Unit unit=Time::S) const
Print the Routing Table entries.
void DoDispose(void)
Destructor implementation.
Ptr< Ipv4 > m_ipv4
IPv4 object.
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
void FlushIpv4RouteCache(void) const
Flushes the cache which stores the Ipv4 route based on the destination IP.
Ptr< NixVector > GetNixVector(Ptr< Node > source, Ipv4Address dest, Ptr< NetDevice > oif) const
Takes in the source node and dest IP and calls GetNodeByIp, BFS, accounting for any output interface ...
virtual void DoDispose(void)
Destructor implementation.
#define NS_LOG_FUNCTION_NOARGS()
Output the name of the function.
uint32_t FindTotalNeighbors(Ptr< Node > node) const
Simply iterates through the nodes net-devices and determines how many neighbors the node has...
a virtual net device that bridges multiple LAN segments
SocketErrno
Enumeration of the possible errors returned by a socket.
bool BuildNixVector(const std::vector< Ptr< Node > > &parentVector, uint32_t source, uint32_t dest, Ptr< NixVector > nixVector) const
Recurses the parent vector, created by BFS and actually builds the nixvector.
bool BFS(uint32_t numberOfNodes, Ptr< Node > source, Ptr< Node > dest, std::vector< Ptr< Node > > &parentVector, Ptr< NetDevice > oif) const
Breadth first search algorithm.
void FlushNixCache(void) const
Flushes the cache which stores nix-vector based on destination IP.
void SetSource(Ipv4Address src)
uint32_t GetRemainingBits(void)
uint32_t ExtractNeighborIndex(uint32_t numberOfBits)
Ptr< Node > m_node
Node object.
void SetNode(Ptr< Node > node)
Set the Node pointer of the node for which this routing protocol is to be placed. ...
void SetNixVector(Ptr< NixVector > nixVector)
Set the packet nix-vector.
Iterator Begin(void) const
Get an iterator which refers to the first NetDevice in the container.
void Add(NetDeviceContainer other)
Append the contents of another NetDeviceContainer to the end of this container.
void SetGateway(Ipv4Address gw)
static Iterator End(void)
Nix-vector routing protocol.
Unit
The unit to use to interpret a number representing time.
holds a vector of ns3::NetDevice pointers
void GetAdjacentNetDevices(Ptr< NetDevice > netDevice, Ptr< Channel > channel, NetDeviceContainer &netDeviceContainer) const
Given a net-device returns all the adjacent net-devices, essentially getting the neighbors on that ch...
std::unordered_map< Ipv4Address, ns3::Ptr< ns3::Node >, Ipv4AddressHash > Ipv4AddressToNodeMap
Mapping of IPv4 address to ns-3 node.
Ptr< Ipv4Route > GetIpv4RouteInCache(Ipv4Address address)
Checks the cache based on dest IP for the Ipv4Route.
static TypeId GetTypeId(void)
The Interface ID of the Global Router interface.
#define NS_LOG_LOGIC(msg)
Use NS_LOG to output a message of level LOG_LOGIC.
Ptr< BridgeNetDevice > NetDeviceIsBridged(Ptr< NetDevice > nd) const
Determine if the NetDevice is bridged.
virtual void NotifyInterfaceDown(uint32_t interface)
Access to the IPv4 forwarding table, interfaces, and configuration.
Ptr< T > GetObject(void) const
Get a pointer to the requested aggregated Object.
virtual void NotifyInterfaceUp(uint32_t interface)
Ptr< NetDevice > GetOutputDevice(void) const
Every class exported by the ns3 library is enclosed in the ns3 namespace.
std::vector< Ptr< Node > >::const_iterator Iterator
Node container iterator.
Ptr< NixVector > GetNixVectorInCache(Ipv4Address address) const
Checks the cache based on dest IP for the nix-vector.
NixMap_t m_nixCache
Cache stores nix-vectors based on destination ip.
static bool g_isCacheDirty
Flag to mark when caches are dirty and need to be flushed.
Ptr< NixVector > Copy(void) const
void SetOutputDevice(Ptr< NetDevice > outputDevice)
Equivalent in Linux to dst_entry.dev.
void PrintRoutingPath(Ptr< Node > source, Ipv4Address dest, Ptr< OutputStreamWrapper > stream, Time::Unit unit) const
Print the Routing Path according to Nix Routing.
uint32_t BitCount(uint32_t numberOfNeighbors) const
virtual void NotifyRemoveAddress(uint32_t interface, Ipv4InterfaceAddress address)
#define NS_ASSERT_MSG(condition, message)
At runtime, in debugging builds, if this condition is not true, the program prints the message to out...
virtual Ptr< Ipv4Route > RouteOutput(Ptr< Packet > p, const Ipv4Header &header, Ptr< NetDevice > oif, Socket::SocketErrno &sockerr)
Query routing cache for an existing route, for an outbound packet.
virtual void SetIpv4(Ptr< Ipv4 > ipv4)
uint32_t m_totalNeighbors
Total neighbors used for nix-vector to determine number of bits.
Ipv4 addresses are stored in host order in this class.
#define NS_ABORT_MSG_UNLESS(cond, msg)
Abnormal program termination if a condition is false, with a message.
#define NS_ABORT_MSG_IF(cond, msg)
Abnormal program termination if a condition is true, with a message.
a class to store IPv4 address information on an interface
static Iterator Begin(void)
std::vector< Ptr< NetDevice > >::const_iterator Iterator
NetDevice container iterator.
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
uint32_t GetN(void) const
Get the number of Ptr<NetDevice> stored in this container.
Ipv4RouteMap_t m_ipv4RouteCache
Cache stores Ipv4Routes based on destination ip.
virtual bool RouteInput(Ptr< const Packet > p, const Ipv4Header &header, Ptr< const NetDevice > idev, UnicastForwardCallback ucb, MulticastForwardCallback mcb, LocalDeliverCallback lcb, ErrorCallback ecb)
Route an input packet (to be forwarded or locally delivered)
Ptr< NixVector > GetNixVector(void) const
Get the packet nix-vector.
static std::string FindName(Ptr< Object > object)
Given a pointer to an object, look to see if that object has a name associated with it and...
Ipv4Address GetLocal(void) const
Get the local address.
Abstract base class for IPv4 routing protocols.
Time Now(void)
create an ns3::Time instance which contains the current simulation time.
#define NS_LOG_ERROR(msg)
Use NS_LOG to output a message of level LOG_ERROR.
void AddNeighborIndex(uint32_t newBits, uint32_t numberOfBits)
void CheckCacheStateAndFlush(void) const
Flushes routing caches if required.
bool IsNull(void) const
Check for null implementation.
virtual void NotifyAddAddress(uint32_t interface, Ipv4InterfaceAddress address)
uint32_t FindNetDeviceForNixIndex(Ptr< Node > node, uint32_t nodeIndex, Ipv4Address &gatewayIp) const
Nix index is with respect to the neighbors.
a unique identifier for an interface.
TypeId SetParent(TypeId tid)
Set the parent TypeId.
std::ostream * GetStream(void)
Return a pointer to an ostream previously set in the wrapper.
void SetDestination(Ipv4Address dest)
uint32_t GetNDevices(void) const
static Ipv4AddressToNodeMap g_ipv4AddressToNodeMap
Address to node map.