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);
a virtual net device that bridges multiple LAN segments
bool IsNull(void) const
Check for null implementation.
Ipv4 addresses are stored in host order in this class.
Access to the IPv4 forwarding table, interfaces, and configuration.
a class to store IPv4 address information on an interface
Ipv4Address GetLocal(void) const
Get the local address.
Nix-vector routing protocol.
virtual void NotifyAddAddress(uint32_t interface, Ipv4InterfaceAddress address)
Ptr< Ipv4 > m_ipv4
IPv4 object.
Ptr< NixVector > GetNixVectorInCache(Ipv4Address address) const
Checks the cache based on dest IP for the nix-vector.
virtual void NotifyRemoveAddress(uint32_t interface, Ipv4InterfaceAddress address)
Ptr< Node > m_node
Node object.
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)
NixMap_t m_nixCache
Cache stores nix-vectors based on destination ip.
virtual void NotifyInterfaceDown(uint32_t interface)
uint32_t FindTotalNeighbors(Ptr< Node > node) const
Simply iterates through the nodes net-devices and determines how many neighbors the node has.
void DoDispose(void)
Destructor implementation.
virtual void NotifyInterfaceUp(uint32_t interface)
void SetNode(Ptr< Node > node)
Set the Node pointer of the node for which this routing protocol is to be placed.
bool BFS(uint32_t numberOfNodes, Ptr< Node > source, Ptr< Node > dest, std::vector< Ptr< Node > > &parentVector, Ptr< NetDevice > oif) const
Breadth first search algorithm.
uint32_t FindNetDeviceForNixIndex(Ptr< Node > node, uint32_t nodeIndex, Ipv4Address &gatewayIp) const
Nix index is with respect to the neighbors.
void BuildIpv4AddressToNodeMap(void) const
Build map from IPv4 Address to Node for faster lookup.
virtual void PrintRoutingTable(Ptr< OutputStreamWrapper > stream, Time::Unit unit=Time::S) const
Print the Routing Table entries.
static bool g_isCacheDirty
Flag to mark when caches are dirty and need to be flushed.
void FlushGlobalNixRoutingCache(void) const
Called when run-time link topology change occurs which iterates through the node list and flushes any...
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 ...
bool BuildNixVectorLocal(Ptr< NixVector > nixVector)
Special variation of BuildNixVector for when a node is sending to itself.
static Ipv4AddressToNodeMap g_ipv4AddressToNodeMap
Address to node map.
void FlushNixCache(void) const
Flushes the cache which stores nix-vector based on destination IP.
std::unordered_map< Ipv4Address, ns3::Ptr< ns3::Node >, Ipv4AddressHash > Ipv4AddressToNodeMap
Mapping of IPv4 address to ns-3 node.
uint32_t m_totalNeighbors
Total neighbors used for nix-vector to determine number of bits.
void PrintRoutingPath(Ptr< Node > source, Ipv4Address dest, Ptr< OutputStreamWrapper > stream, Time::Unit unit) const
Print the Routing Path according to Nix Routing.
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...
Ptr< BridgeNetDevice > NetDeviceIsBridged(Ptr< NetDevice > nd) const
Determine if the NetDevice is bridged.
Ptr< Ipv4Route > GetIpv4RouteInCache(Ipv4Address address)
Checks the cache based on dest IP for the Ipv4Route.
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.
Ptr< Node > GetNodeByIp(Ipv4Address dest) const
Iterates through the node list and finds the one corresponding to the given Ipv4Address.
void FlushIpv4RouteCache(void) const
Flushes the cache which stores the Ipv4 route based on the destination IP.
void CheckCacheStateAndFlush(void) const
Flushes routing caches if required.
Ipv4RouteMap_t m_ipv4RouteCache
Cache stores Ipv4Routes based on destination ip.
static TypeId GetTypeId(void)
The Interface ID of the Global Router interface.
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.
virtual void SetIpv4(Ptr< Ipv4 > ipv4)
void SetGateway(Ipv4Address gw)
Ptr< NetDevice > GetOutputDevice(void) const
void SetDestination(Ipv4Address dest)
void SetSource(Ipv4Address src)
void SetOutputDevice(Ptr< NetDevice > outputDevice)
Equivalent in Linux to dst_entry.dev.
Abstract base class for IPv4 routing protocols.
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,...
holds a vector of ns3::NetDevice pointers
Iterator End(void) const
Get an iterator which indicates past-the-last NetDevice in the container.
uint32_t GetN(void) const
Get the number of Ptr<NetDevice> stored in this container.
std::vector< Ptr< NetDevice > >::const_iterator Iterator
NetDevice container iterator.
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.
Ptr< NetDevice > Get(uint32_t i) const
Get the Ptr<NetDevice> stored in this container at a given index.
void AddNeighborIndex(uint32_t newBits, uint32_t numberOfBits)
uint32_t GetRemainingBits(void)
Ptr< NixVector > Copy(void) const
uint32_t ExtractNeighborIndex(uint32_t numberOfBits)
uint32_t BitCount(uint32_t numberOfNeighbors) const
uint32_t GetId(void) const
uint32_t GetNDevices(void) const
Ptr< NetDevice > GetDevice(uint32_t index) const
Retrieve the index-th NetDevice associated to this node.
static Iterator End(void)
static uint32_t GetNNodes(void)
static Iterator Begin(void)
std::vector< Ptr< Node > >::const_iterator Iterator
Node container iterator.
virtual void DoDispose(void)
Destructor implementation.
Ptr< T > GetObject(void) const
Get a pointer to the requested aggregated Object.
std::ostream * GetStream(void)
Return a pointer to an ostream previously set in the wrapper.
Ptr< NixVector > GetNixVector(void) const
Get the packet nix-vector.
void SetNixVector(Ptr< NixVector > nixVector)
Set the packet nix-vector.
Smart pointer class similar to boost::intrusive_ptr.
SocketErrno
Enumeration of the possible errors returned by a socket.
Unit
The unit to use to interpret a number representing time.
TimeWithUnit As(const enum Unit unit=Time::AUTO) const
Attach a unit to a Time, to facilitate output in a specific unit.
a unique identifier for an interface.
TypeId SetParent(TypeId tid)
Set the parent TypeId.
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file,...
#define NS_ASSERT_MSG(condition, message)
At runtime, in debugging builds, if this condition is not true, the program prints the message to out...
#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.
#define NS_LOG_ERROR(msg)
Use NS_LOG to output a message of level LOG_ERROR.
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
#define NS_LOG_LOGIC(msg)
Use NS_LOG to output a message of level LOG_LOGIC.
#define NS_LOG_FUNCTION_NOARGS()
Output the name of the function.
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Time Now(void)
create an ns3::Time instance which contains the current simulation time.
Every class exported by the ns3 library is enclosed in the ns3 namespace.