27 #include "ns3/abort.h"
28 #include "ns3/ipv4-list-routing.h"
30 #include "ns3/loopback-net-device.h"
31 #include "ns3/names.h"
63 if constexpr (std::is_same_v<T, Ipv4RoutingProtocol>)
71 static TypeId tid =
TypeId(
"ns3::" + name +
"NixVectorRouting")
73 .SetGroupName(
"NixVectorRouting")
74 .template AddConstructor<NixVectorRouting<T>>();
102 template <
typename T>
113 template <
typename T>
119 for (uint32_t i = 0; i < m_ip->GetNInterfaces(); i++)
121 m_ip->SetForwarding(i,
true);
127 template <
typename T>
139 template <
typename T>
148 template <
typename T>
164 rp->FlushIpRouteCache();
165 rp->m_totalNeighbors = 0;
170 g_ipAddressToNodeMap.clear();
173 template <
typename T>
181 template <
typename T>
186 m_ipRouteCache.clear();
189 template <
typename T>
211 if (source == destNode)
220 std::vector<Ptr<Node>> parentVector;
224 if (BuildNixVector(parentVector, source->
GetId(), destNode->
GetId(), nixVector))
242 template <
typename T>
248 CheckCacheStateAndFlush();
250 auto iter = m_nixCache.find(
address);
251 if (iter != m_nixCache.end())
259 foundInCache =
false;
263 template <
typename T>
269 CheckCacheStateAndFlush();
271 auto iter = m_ipRouteCache.find(
address);
272 if (iter != m_ipRouteCache.end())
282 template <
typename T>
296 if (!parentVector.at(dest))
301 Ptr<Node> parentNode = parentVector.at(dest);
303 uint32_t numberOfDevices = parentNode->
GetNDevices();
305 uint32_t totalNeighbors = 0;
309 for (uint32_t i = 0; i < numberOfDevices; i++)
315 if (localNetDevice->IsBridge())
328 GetAdjacentNetDevices(localNetDevice,
channel, netDeviceContainer);
336 for (
auto iter = netDeviceContainer.
Begin(); iter != netDeviceContainer.
End(); iter++)
338 Ptr<Node> remoteNode = (*iter)->GetNode();
340 if (remoteNode->
GetId() == dest)
342 destId = totalNeighbors + offset;
347 totalNeighbors += netDeviceContainer.
GetN();
350 <<
" bits, for node " << parentNode->
GetId());
355 BuildNixVector(parentVector, source, (parentVector.at(dest))->GetId(), nixVector);
359 template <
typename T>
368 if (!netDeviceInterface || !netDeviceInterface->IsUp())
370 NS_LOG_LOGIC(
"IpInterface either doesn't exist or is down");
374 uint32_t netDeviceAddresses = netDeviceInterface->GetNAddresses();
376 for (std::size_t i = 0; i <
channel->GetNDevices(); i++)
379 if (remoteDevice != netDevice)
382 Ptr<IpInterface> remoteDeviceInterface = GetInterfaceByNetDevice(remoteDevice);
383 if (!remoteDeviceInterface || !remoteDeviceInterface->IsUp())
385 NS_LOG_LOGIC(
"IpInterface either doesn't exist or is down");
389 uint32_t remoteDeviceAddresses = remoteDeviceInterface->GetNAddresses();
390 bool commonSubnetFound =
false;
392 for (uint32_t j = 0; j < netDeviceAddresses; ++j)
395 if constexpr (!IsIpv4)
402 for (uint32_t
k = 0;
k < remoteDeviceAddresses; ++
k)
405 if constexpr (!IsIpv4)
412 if (netDeviceIfAddr.IsInSameSubnet(remoteDeviceIfAddr.GetAddress()))
414 commonSubnetFound =
true;
419 if (commonSubnetFound)
425 if (!commonSubnetFound)
435 NS_LOG_LOGIC(
"Looking through bridge ports of bridge net device " << bd);
436 for (uint32_t j = 0; j < bd->GetNBridgePorts(); ++j)
439 if (ndBridged == remoteDevice)
441 NS_LOG_LOGIC(
"That bridge port is me, don't walk backward");
449 GetAdjacentNetDevices(ndBridged, chBridged, netDeviceContainer);
454 netDeviceContainer.
Add(
channel->GetDevice(i));
460 template <
typename T>
475 for (uint32_t deviceId = 0; deviceId < numberOfDevices; deviceId++)
480 if (!DynamicCast<LoopbackNetDevice>(device))
482 int32_t interfaceIndex = (ip)->GetInterfaceForDevice(node->
GetDevice(deviceId));
483 if (interfaceIndex != -1)
485 g_netdeviceToIpInterfaceMap[device] = (ip)->GetInterface(interfaceIndex);
487 uint32_t numberOfAddresses = ip->GetNAddresses(interfaceIndex);
488 for (uint32_t addressIndex = 0; addressIndex < numberOfAddresses;
492 ip->GetAddress(interfaceIndex, addressIndex);
496 g_ipAddressToNodeMap.count(addr),
497 "Duplicate IP address ("
499 <<
") found during NIX Vector map construction for node "
503 << addr <<
" for node " << node->
GetId()
504 <<
" to NIX Vector IP address to node map");
505 g_ipAddressToNodeMap[addr] = node;
514 template <
typename T>
521 if (g_ipAddressToNodeMap.empty())
523 BuildIpAddressToNodeMap();
528 auto iter = g_ipAddressToNodeMap.find(dest);
530 if (iter == g_ipAddressToNodeMap.end())
532 NS_LOG_ERROR(
"Couldn't find dest node given the IP" << dest);
537 destNode = iter->second;
543 template <
typename T>
548 if (g_netdeviceToIpInterfaceMap.empty())
550 BuildIpAddressToNodeMap();
555 auto iter = g_netdeviceToIpInterfaceMap.find(netDevice);
557 if (iter == g_netdeviceToIpInterfaceMap.end())
559 NS_LOG_ERROR(
"Couldn't find IpInterface node given the NetDevice" << netDevice);
560 ipInterface =
nullptr;
564 ipInterface = iter->second;
570 template <
typename T>
577 uint32_t totalNeighbors = 0;
581 for (uint32_t i = 0; i < numberOfDevices; i++)
596 GetAdjacentNetDevices(localNetDevice,
channel, netDeviceContainer);
598 totalNeighbors += netDeviceContainer.
GetN();
601 return totalNeighbors;
604 template <
typename T>
619 for (uint32_t i = 0; i < nDevices; ++i)
624 if (ndTest->IsBridge())
626 NS_LOG_LOGIC(
"device " << i <<
" is a bridge net device");
630 "NixVectorRouting::NetDeviceIsBridged (): GetObject for <BridgeNetDevice> failed");
632 for (uint32_t j = 0; j < bnd->GetNBridgePorts(); ++j)
634 NS_LOG_LOGIC(
"Examine bridge port " << j <<
" " << bnd->GetBridgePort(j));
635 if (bnd->GetBridgePort(j) == nd)
637 NS_LOG_LOGIC(
"Net device " << nd <<
" is bridged by " << bnd);
647 template <
typename T>
657 uint32_t totalNeighbors = 0;
661 for (uint32_t i = 0; i < numberOfDevices; i++)
676 GetAdjacentNetDevices(localNetDevice,
channel, netDeviceContainer);
679 if (nodeIndex < (totalNeighbors + netDeviceContainer.
GetN()))
683 Ptr<NetDevice> gatewayDevice = netDeviceContainer.
Get(nodeIndex - totalNeighbors);
686 gatewayIp = ifAddr.GetAddress();
689 totalNeighbors += netDeviceContainer.
GetN();
695 template <
typename T>
708 CheckCacheStateAndFlush();
710 IpAddress destAddress = header.GetDestination();
714 if (destAddress.IsLocalhost())
716 rtentry = Create<IpRoute>();
717 rtentry->SetSource(IpAddress::GetLoopback());
718 rtentry->SetDestination(destAddress);
719 rtentry->SetGateway(IpAddress::GetZero());
720 for (uint32_t i = 0; i < m_ip->GetNInterfaces(); i++)
723 DynamicCast<LoopbackNetDevice>(m_ip->GetNetDevice(i));
726 rtentry->SetOutputDevice(loNetDevice);
733 if constexpr (!IsIpv4)
736 if (destAddress.IsLinkLocalMulticast())
740 "Try to send on link-local multicast address, and no interface index is given!");
741 rtentry = Create<IpRoute>();
743 m_ip->SourceAddressSelection(m_ip->GetInterfaceForDevice(oif), destAddress));
744 rtentry->SetDestination(destAddress);
746 rtentry->SetOutputDevice(oif);
751 bool foundInCache =
false;
752 nixVectorInCache = GetNixVectorInCache(destAddress, foundInCache);
760 nixVectorInCache = GetNixVector(m_node, destAddress, oif);
761 if (nixVectorInCache)
764 m_nixCache.insert(
typename NixMap_t::value_type(destAddress, nixVectorInCache));
769 if (nixVectorInCache)
771 NS_LOG_LOGIC(
"Nix-vector contents: " << *nixVectorInCache);
775 nixVectorForPacket = nixVectorInCache->
Copy();
779 if (m_totalNeighbors == 0)
781 m_totalNeighbors = FindTotalNeighbors(m_node);
786 uint32_t numberOfBits = nixVectorForPacket->
BitCount(m_totalNeighbors);
791 rtentry = GetIpRouteInCache(destAddress);
793 if (!rtentry || !(rtentry->GetOutputDevice() == oif))
802 m_ipRouteCache.erase(destAddress);
807 uint32_t index = FindNetDeviceForNixIndex(m_node, nodeIndex, gatewayIp);
808 int32_t interfaceIndex = 0;
812 interfaceIndex = (m_ip)->GetInterfaceForDevice(m_node->GetDevice(index));
816 interfaceIndex = (m_ip)->GetInterfaceForDevice(oif);
819 NS_ASSERT_MSG(interfaceIndex != -1,
"Interface index not found for device");
821 IpAddress sourceIPAddr = m_ip->SourceAddressSelection(interfaceIndex, destAddress);
824 rtentry = Create<IpRoute>();
825 rtentry->SetSource(sourceIPAddr);
827 rtentry->SetGateway(gatewayIp);
828 rtentry->SetDestination(destAddress);
832 rtentry->SetOutputDevice(m_ip->GetNetDevice(interfaceIndex));
836 rtentry->SetOutputDevice(oif);
842 m_ipRouteCache.insert(
typename IpRouteMap_t::value_type(destAddress, rtentry));
845 NS_LOG_LOGIC(
"Nix-vector contents: " << *nixVectorInCache <<
" : Remaining bits: "
852 NS_LOG_LOGIC(
"Adding Nix-vector to packet: " << *nixVectorForPacket);
865 template <
typename T>
875 NS_LOG_FUNCTION(
this << p << header << header.GetSource() << header.GetDestination() << idev);
877 CheckCacheStateAndFlush();
881 NS_ASSERT(m_ip->GetInterfaceForDevice(idev) >= 0);
882 uint32_t iif = m_ip->GetInterfaceForDevice(idev);
886 IpAddress destAddress = header.GetDestination();
888 if constexpr (IsIpv4)
891 if (m_ip->IsDestinationAddress(destAddress, iif))
913 if (destAddress.IsMulticast())
915 NS_LOG_LOGIC(
"Multicast route not supported by Nix-Vector routing " << destAddress);
920 if (m_ip->IsForwarding(iif) ==
false)
939 if (nixVector->
GetEpoch() != g_epoch)
942 <<
") - rebuilding it");
943 nixVector = GetNixVector(m_node, destAddress,
nullptr);
949 if (m_totalNeighbors == 0)
951 m_totalNeighbors = FindTotalNeighbors(m_node);
953 uint32_t numberOfBits = nixVector->
BitCount(m_totalNeighbors);
956 rtentry = GetIpRouteInCache(destAddress);
962 uint32_t index = FindNetDeviceForNixIndex(m_node, nodeIndex, gatewayIp);
963 uint32_t interfaceIndex = (m_ip)->GetInterfaceForDevice(m_node->GetDevice(index));
967 rtentry = Create<IpRoute>();
968 rtentry->SetSource(ifAddr.GetAddress());
970 rtentry->SetGateway(gatewayIp);
971 rtentry->SetDestination(destAddress);
972 rtentry->SetOutputDevice(m_ip->GetNetDevice(interfaceIndex));
975 m_ipRouteCache.insert(
typename IpRouteMap_t::value_type(destAddress, rtentry));
978 NS_LOG_LOGIC(
"At Node " << m_node->GetId() <<
", Extracting " << numberOfBits
979 <<
" bits from Nix-vector: " << nixVector <<
" : " << *nixVector);
985 if constexpr (IsIpv4)
987 ucb(rtentry, p, header);
991 ucb(idev, rtentry, p, header);
997 template <
typename T>
1003 CheckCacheStateAndFlush();
1007 std::ios oldState(
nullptr);
1008 oldState.copyfmt(*os);
1010 *os << std::resetiosflags(std::ios::adjustfield) << std::setiosflags(std::ios::left);
1012 *os <<
"Node: " << m_ip->template GetObject<Node>()->GetId() <<
", Time: " <<
Now().
As(unit)
1013 <<
", Local time: " << m_ip->template GetObject<Node>()->GetLocalTime().As(unit)
1014 <<
", Nix Routing" << std::endl;
1016 *os <<
"NixCache:" << std::endl;
1017 if (m_nixCache.size() > 0)
1019 *os << std::setw(30) <<
"Destination";
1020 *os <<
"NixVector" << std::endl;
1021 for (
auto it = m_nixCache.begin(); it != m_nixCache.end(); it++)
1023 std::ostringstream dest;
1025 *os << std::setw(30) << dest.str();
1028 *os << *(it->second) << std::endl;
1032 *os <<
"-" << std::endl;
1037 *os <<
"IpRouteCache:" << std::endl;
1038 if (m_ipRouteCache.size() > 0)
1040 *os << std::setw(30) <<
"Destination";
1041 *os << std::setw(30) <<
"Gateway";
1042 *os << std::setw(30) <<
"Source";
1043 *os <<
"OutputDevice" << std::endl;
1044 for (
auto it = m_ipRouteCache.begin(); it != m_ipRouteCache.end(); it++)
1046 std::ostringstream dest;
1047 std::ostringstream gw;
1048 std::ostringstream src;
1049 dest << it->second->GetDestination();
1050 *os << std::setw(30) << dest.str();
1051 gw << it->second->GetGateway();
1052 *os << std::setw(30) << gw.str();
1053 src << it->second->GetSource();
1054 *os << std::setw(30) << src.str();
1062 *os << it->second->GetOutputDevice()->GetIfIndex();
1069 (*os).copyfmt(oldState);
1073 template <
typename T>
1077 g_isCacheDirty =
true;
1080 template <
typename T>
1084 g_isCacheDirty =
true;
1087 template <
typename T>
1091 g_isCacheDirty =
true;
1094 template <
typename T>
1098 g_isCacheDirty =
true;
1101 template <
typename T>
1109 g_isCacheDirty =
true;
1112 template <
typename T>
1120 g_isCacheDirty =
true;
1123 template <
typename T>
1131 NS_LOG_FUNCTION(
this << numberOfNodes << source << dest << parentVector << oif);
1134 std::queue<Ptr<Node>> greyNodeList;
1137 parentVector.assign(numberOfNodes,
nullptr);
1140 greyNodeList.push(source);
1141 parentVector.at(source->
GetId()) = source;
1144 while (!greyNodeList.empty())
1146 Ptr<Node> currNode = greyNodeList.front();
1149 if (currNode == dest)
1158 if (currNode == source && oif)
1163 uint32_t interfaceIndex = (ip)->GetInterfaceForDevice(oif);
1164 if (!(ip->IsUp(interfaceIndex)))
1170 if (!(oif->IsLinkUp()))
1184 GetAdjacentNetDevices(oif,
channel, netDeviceContainer);
1190 for (
auto iter = netDeviceContainer.
Begin(); iter != netDeviceContainer.
End(); iter++)
1192 Ptr<Node> remoteNode = (*iter)->GetNode();
1194 if (!remoteIpInterface || !(remoteIpInterface->IsUp()))
1196 NS_LOG_LOGIC(
"IpInterface either doesn't exist or is down");
1204 if (!parentVector.at(remoteNode->
GetId()))
1206 parentVector.at(remoteNode->
GetId()) = currNode;
1207 greyNodeList.push(remoteNode);
1215 for (uint32_t i = 0; i < (currNode->
GetNDevices()); i++)
1225 uint32_t interfaceIndex = (ip)->GetInterfaceForDevice(currNode->
GetDevice(i));
1226 if (!(ip->IsUp(interfaceIndex)))
1232 if (!(localNetDevice->IsLinkUp()))
1246 GetAdjacentNetDevices(localNetDevice,
channel, netDeviceContainer);
1252 for (
auto iter = netDeviceContainer.
Begin(); iter != netDeviceContainer.
End();
1255 Ptr<Node> remoteNode = (*iter)->GetNode();
1257 if (!remoteIpInterface || !(remoteIpInterface->IsUp()))
1259 NS_LOG_LOGIC(
"IpInterface either doesn't exist or is down");
1267 if (!parentVector.at(remoteNode->
GetId()))
1269 parentVector.at(remoteNode->
GetId()) = currNode;
1270 greyNodeList.push(remoteNode);
1285 template <
typename T>
1298 CheckCacheStateAndFlush();
1309 std::ios oldState(
nullptr);
1310 oldState.copyfmt(*os);
1312 *os << std::resetiosflags(std::ios::adjustfield) << std::setiosflags(std::ios::left);
1313 *os <<
"Time: " <<
Now().
As(unit) <<
", Nix Routing" << std::endl;
1314 *os <<
"Route path from ";
1315 *os <<
"Node " << source->
GetId() <<
" to Node " << destNode->
GetId() <<
", ";
1316 *os <<
"Nix Vector: ";
1319 bool foundInCache =
true;
1320 nixVectorInCache = GetNixVectorInCache(dest, foundInCache);
1328 nixVectorInCache = GetNixVector(source, dest,
nullptr);
1331 if (nixVectorInCache || (!nixVectorInCache && source == destNode))
1334 uint32_t totalNeighbors = 0;
1336 if (nixVectorInCache)
1341 nixVector = nixVectorInCache->
Copy();
1347 if (source == destNode)
1349 std::ostringstream addr;
1350 std::ostringstream node;
1352 node <<
"(Node " << destNode->
GetId() <<
")";
1353 *os << std::setw(25) << addr.str();
1354 *os << std::setw(10) << node.str();
1356 *os << std::setw(25) << addr.str();
1357 *os << node.str() << std::endl;
1360 while (curr != destNode)
1362 totalNeighbors = FindTotalNeighbors(curr);
1365 uint32_t numberOfBits = nixVector->
BitCount(totalNeighbors);
1372 uint32_t netDeviceIndex = FindNetDeviceForNixIndex(curr, nixIndex, gatewayIp);
1378 uint32_t interfaceIndex = ip->GetInterfaceForDevice(outDevice);
1382 sourceIPAddr = ip->SourceAddressSelection(interfaceIndex, dest);
1388 sourceIPAddr = ip->GetAddress(interfaceIndex, 0).GetAddress();
1391 std::ostringstream currAddr;
1392 std::ostringstream currNode;
1393 std::ostringstream nextAddr;
1394 std::ostringstream nextNode;
1395 currAddr << sourceIPAddr;
1396 currNode <<
"(Node " << curr->
GetId() <<
")";
1397 *os << std::setw(25) << currAddr.str();
1398 *os << std::setw(10) << currNode.str();
1400 curr = GetNodeByIp(gatewayIp);
1401 nextAddr << ((curr == destNode) ? dest : gatewayIp);
1402 nextNode <<
"(Node " << curr->GetId() <<
")";
1404 *os << std::setw(25) << nextAddr.str();
1405 *os << nextNode.str() << std::endl;
1411 *os <<
")" << std::endl;
1413 *os <<
"There does not exist a path from Node " << source->
GetId() <<
" to Node "
1414 << destNode->
GetId() <<
"." << std::endl;
1417 (*os).copyfmt(oldState);
1420 template <
typename T>
1426 FlushGlobalNixRoutingCache();
1428 g_isCacheDirty =
false;
a virtual net device that bridges multiple LAN segments
bool IsNull() const
Check for null implementation.
static Ipv6Address GetZero()
Get the 0 (::) Ipv6Address.
@ LINKLOCAL
Link-local address (fe80::/64)
Describes an IPv6 prefix.
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
uint32_t GetN() const
Get the number of Ptr<NetDevice> stored in this container.
Iterator Begin() 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.
Iterator End() const
Get an iterator which indicates past-the-last NetDevice in the 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() const
uint32_t ExtractNeighborIndex(uint32_t numberOfBits)
void SetEpoch(uint32_t epoch)
Set the NixVector Epoch.
Ptr< NixVector > Copy() const
uint32_t BitCount(uint32_t numberOfNeighbors) const
uint32_t GetEpoch() const
Get the NixVector Epoch.
Nix-vector routing protocol.
void PrintRoutingPath(Ptr< Node > source, IpAddress dest, Ptr< OutputStreamWrapper > stream, Time::Unit unit) const
Print the Routing Path according to Nix Routing.
void BuildIpAddressToNodeMap() const
Build map from IP Address to Node for faster lookup.
Ptr< IpRoute > GetIpRouteInCache(IpAddress address)
Checks the cache based on dest IP for the IpRoute.
virtual void NotifyRemoveRoute(IpAddress dst, Ipv6Prefix mask, IpAddress nextHop, uint32_t interface, IpAddress prefixToUse=IpAddress::GetZero())
Notify route removing.
virtual void NotifyAddRoute(IpAddress dst, Ipv6Prefix mask, IpAddress nextHop, uint32_t interface, IpAddress prefixToUse=IpAddress::GetZero())
Notify a new route.
typename std::conditional_t< IsIpv4, Ipv4InterfaceAddress, Ipv6InterfaceAddress > IpInterfaceAddress
Alias for Ipv4InterfaceAddress and Ipv6InterfaceAddress classes.
static uint32_t g_epoch
Nix Epoch, incremented each time a flush is performed.
virtual void NotifyInterfaceUp(uint32_t interface)
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::conditional_t< IsIpv4, UnicastForwardCallbackv4, UnicastForwardCallbackv6 > UnicastForwardCallback
Callback for unicast packets to be forwarded.
virtual void NotifyInterfaceDown(uint32_t interface)
typename std::conditional_t< IsIpv4, Ipv4Address, Ipv6Address > IpAddress
Alias for Ipv4Address and Ipv6Address classes.
static IpAddressToNodeMap g_ipAddressToNodeMap
Address to node map.
void FlushGlobalNixRoutingCache() const
Called when run-time link topology change occurs which iterates through the node list and flushes any...
virtual void SetIpv6(Ptr< Ip > ipv6)
Typically, invoked directly or indirectly from ns3::Ipv6::SetRoutingProtocol.
virtual Ptr< IpRoute > RouteOutput(Ptr< Packet > p, const IpHeader &header, Ptr< NetDevice > oif, Socket::SocketErrno &sockerr)
Query routing cache for an existing route, for an outbound packet.
virtual void SetIpv4(Ptr< Ip > ipv4)
Typically, invoked directly or indirectly from ns3::Ipv4::SetRoutingProtocol.
Ptr< IpInterface > GetInterfaceByNetDevice(Ptr< NetDevice > netDevice) const
Iterates through the node list and finds the one corresponding to the given IpAddress.
uint32_t FindTotalNeighbors(Ptr< Node > node) const
Simply iterates through the nodes net-devices and determines how many neighbors the node has.
virtual void NotifyAddAddress(uint32_t interface, IpInterfaceAddress address)
std::conditional_t< IsIpv4, MulticastForwardCallbackv4, MulticastForwardCallbackv6 > MulticastForwardCallback
Callback for multicast packets to be forwarded.
void FlushIpRouteCache() const
Flushes the cache which stores the Ip route based on the destination IP.
virtual bool RouteInput(Ptr< const Packet > p, const IpHeader &header, Ptr< const NetDevice > idev, const UnicastForwardCallback &ucb, const MulticastForwardCallback &mcb, const LocalDeliverCallback &lcb, const ErrorCallback &ecb)
Route an input packet (to be forwarded or locally delivered)
Ptr< NixVector > GetNixVector(Ptr< Node > source, IpAddress dest, Ptr< NetDevice > oif) const
Takes in the source node and dest IP and calls GetNodeByIp, BFS, accounting for any output interface ...
typename std::conditional_t< IsIpv4, Ipv4Header, Ipv6Header > IpHeader
Alias for Ipv4Header and Ipv6Header classes.
Ptr< NixVector > GetNixVectorInCache(const IpAddress &address, bool &foundInCache) const
Checks the cache based on dest IP for the nix-vector.
uint32_t FindNetDeviceForNixIndex(Ptr< Node > node, uint32_t nodeIndex, IpAddress &gatewayIp) const
Nix index is with respect to the neighbors.
static NetDeviceToIpInterfaceMap g_netdeviceToIpInterfaceMap
NetDevice pointer to IpInterface pointer map.
void SetNode(Ptr< Node > node)
Set the Node pointer of the node for which this routing protocol is to be placed.
virtual void PrintRoutingTable(Ptr< OutputStreamWrapper > stream, Time::Unit unit=Time::S) const
Print the Routing Table entries.
typename std::conditional_t< IsIpv4, Ipv4L3Protocol, Ipv6L3Protocol > IpL3Protocol
Alias for Ipv4L3Protocol and Ipv4L3Protocol classes.
virtual void NotifyRemoveAddress(uint32_t interface, IpInterfaceAddress address)
static TypeId GetTypeId()
The Interface ID of the Global Router interface.
static bool g_isCacheDirty
Flag to mark when caches are dirty and need to be flushed.
void CheckCacheStateAndFlush() const
Flushes routing caches if required.
std::unordered_map< IpAddress, ns3::Ptr< ns3::Node >, IpAddressHash > IpAddressToNodeMap
Mapping of IP address to ns-3 node.
std::unordered_map< Ptr< NetDevice >, Ptr< IpInterface > > NetDeviceToIpInterfaceMap
Mapping of Ptr<NetDevice> to Ptr<IpInterface>.
Ptr< BridgeNetDevice > NetDeviceIsBridged(Ptr< NetDevice > nd) const
Determine if the NetDevice is bridged.
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() const
Flushes the cache which stores nix-vector based on destination IP.
bool BuildNixVector(const std::vector< Ptr< Node >> &parentVector, uint32_t source, uint32_t dest, Ptr< NixVector > nixVector) const
Recurses the T vector, created by BFS and actually builds the nixvector.
Ptr< Node > GetNodeByIp(IpAddress dest) const
Iterates through the node list and finds the one corresponding to the given IpAddress.
uint32_t GetNDevices() const
Ptr< NetDevice > GetDevice(uint32_t index) const
Retrieve the index-th NetDevice associated to this node.
static uint32_t GetNNodes()
Ptr< T > GetObject() const
Get a pointer to the requested aggregated Object.
std::ostream * GetStream()
Return a pointer to an ostream previously set in the wrapper.
void SetNixVector(Ptr< NixVector > nixVector) const
Set the packet nix-vector.
Ptr< NixVector > GetNixVector() const
Get the packet nix-vector.
SocketErrno
Enumeration of the possible errors returned by a socket.
TimeWithUnit As(const Unit unit=Time::AUTO) const
Attach a unit to a Time, to facilitate output in a specific unit.
Unit
The unit to use to interpret a number representing time.
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_TEMPLATE_CLASS_DEFINE(type, param)
Explicitly instantiate a template class with one template parameter and register the resulting instan...
Time Now()
create an ns3::Time instance which contains the current simulation time.
Every class exported by the ns3 library is enclosed in the ns3 namespace.