30 #include "ns3/abort.h"
31 #include "ns3/names.h"
32 #include "ns3/ipv4-list-routing.h"
33 #include "ns3/loopback-net-device.h"
57 std::string Tname = GetTypeParamName<NixVectorRouting<T> > ();
58 std::string name = (Tname ==
"Ipv4RoutingProtocol" ?
"Ipv4" :
"Ipv6");
59 static TypeId tid =
TypeId ((
"ns3::" + name +
"NixVectorRouting").c_str ())
61 .SetGroupName (
"NixVectorRouting")
62 .template AddConstructor<NixVectorRouting<T> > ()
69 : m_totalNeighbors (0)
102 template <
typename T>
108 for (uint32_t i = 0 ; i < m_ip->GetNInterfaces (); i++)
110 m_ip->SetForwarding (i,
true);
116 template <
typename T>
128 template <
typename T>
137 template <
typename T>
153 rp->FlushNixCache ();
154 rp->FlushIpRouteCache ();
155 rp->m_totalNeighbors = 0;
160 g_ipAddressToNodeMap.clear ();
163 template <
typename T>
171 template <
typename T>
176 m_ipRouteCache.clear ();
179 template <
typename T>
200 if (source == destNode)
209 std::vector< Ptr<Node> > parentVector;
213 if (BuildNixVector (parentVector, source->
GetId (), destNode->
GetId (), nixVector))
232 template <
typename T>
238 CheckCacheStateAndFlush ();
240 typename NixMap_t::iterator iter = m_nixCache.find (
address);
241 if (iter != m_nixCache.end ())
249 foundInCache =
false;
253 template <
typename T>
259 CheckCacheStateAndFlush ();
261 typename IpRouteMap_t::iterator iter = m_ipRouteCache.find (
address);
262 if (iter != m_ipRouteCache.end ())
272 template <
typename T>
278 uint32_t numberOfDevices = m_node->GetNDevices ();
284 for (uint32_t i = 0; i < numberOfDevices; i++)
286 uint32_t interfaceIndex = (m_ip)->GetInterfaceForDevice (m_node->GetDevice (i));
288 IpAddress ifAddrValue = ifAddr.GetAddress ();
289 if (ifAddrValue.IsLocalhost ())
293 <<
" bits, for node " << m_node->GetId ());
301 template <
typename T>
312 if (parentVector.at (dest) == 0)
317 Ptr<Node> parentNode = parentVector.at (dest);
319 uint32_t numberOfDevices = parentNode->
GetNDevices ();
321 uint32_t totalNeighbors = 0;
325 for (uint32_t i = 0; i < numberOfDevices; i++)
344 GetAdjacentNetDevices (localNetDevice,
channel, netDeviceContainer);
354 Ptr<Node> remoteNode = (*iter)->GetNode ();
356 if (remoteNode->
GetId () == dest)
358 destId = totalNeighbors + offset;
363 totalNeighbors += netDeviceContainer.
GetN ();
366 << nixVector->
BitCount (totalNeighbors) <<
" bits, for node " << parentNode->
GetId ());
371 BuildNixVector (parentVector, source, (parentVector.at (dest))->GetId (), nixVector);
375 template <
typename T>
382 if (netDeviceInterface == 0 || !netDeviceInterface->IsUp ())
384 NS_LOG_LOGIC (
"IpInterface either doesn't exist or is down");
388 uint32_t netDeviceAddresses = netDeviceInterface->GetNAddresses ();
390 for (std::size_t i = 0; i <
channel->GetNDevices (); i++)
393 if (remoteDevice != netDevice)
396 Ptr<IpInterface> remoteDeviceInterface = GetInterfaceByNetDevice (remoteDevice);
397 if (remoteDeviceInterface == 0 || !remoteDeviceInterface->IsUp ())
399 NS_LOG_LOGIC (
"IpInterface either doesn't exist or is down");
403 uint32_t remoteDeviceAddresses = remoteDeviceInterface->GetNAddresses ();
404 bool commonSubnetFound =
false;
406 for (uint32_t j = 0; j < netDeviceAddresses; ++j)
409 if constexpr (!IsIpv4::value)
416 for (uint32_t
k = 0;
k < remoteDeviceAddresses; ++
k)
419 if constexpr (!IsIpv4::value)
426 if (netDeviceIfAddr.IsInSameSubnet (remoteDeviceIfAddr.GetAddress ()))
428 commonSubnetFound =
true;
433 if (commonSubnetFound)
439 if (!commonSubnetFound)
449 NS_LOG_LOGIC (
"Looking through bridge ports of bridge net device " << bd);
453 if (ndBridged == remoteDevice)
455 NS_LOG_LOGIC (
"That bridge port is me, don't walk backward");
463 GetAdjacentNetDevices (ndBridged, chBridged, netDeviceContainer);
468 netDeviceContainer.
Add (
channel->GetDevice (i));
474 template <
typename T>
489 for (uint32_t deviceId = 0; deviceId < numberOfDevices; deviceId++)
494 if ( !DynamicCast<LoopbackNetDevice>(device) )
496 int32_t interfaceIndex = (ip)->GetInterfaceForDevice (node->
GetDevice (deviceId));
497 if (interfaceIndex != -1)
499 g_netdeviceToIpInterfaceMap[device] = (ip)->GetInterface (interfaceIndex);
501 uint32_t numberOfAddresses = ip->GetNAddresses (interfaceIndex);
502 for (uint32_t addressIndex = 0; addressIndex < numberOfAddresses; addressIndex++)
508 "Duplicate IP address (" << addr <<
") found during NIX Vector map construction for node " << node->
GetId ());
510 NS_LOG_LOGIC (
"Adding IP address " << addr <<
" for node " << node->
GetId () <<
" to NIX Vector IP address to node map");
511 g_ipAddressToNodeMap[addr] = node;
520 template <
typename T>
527 if ( g_ipAddressToNodeMap.empty () )
529 BuildIpAddressToNodeMap ();
534 typename IpAddressToNodeMap::iterator iter = g_ipAddressToNodeMap.find(dest);
536 if(iter == g_ipAddressToNodeMap.end ())
538 NS_LOG_ERROR (
"Couldn't find dest node given the IP" << dest);
543 destNode = iter ->
second;
549 template <
typename T>
554 if ( g_netdeviceToIpInterfaceMap.empty () )
556 BuildIpAddressToNodeMap ();
561 typename NetDeviceToIpInterfaceMap::iterator iter = g_netdeviceToIpInterfaceMap.find(netDevice);
563 if(iter == g_netdeviceToIpInterfaceMap.end ())
565 NS_LOG_ERROR (
"Couldn't find IpInterface node given the NetDevice" << netDevice);
570 ipInterface = iter ->
second;
576 template <
typename T>
583 uint32_t totalNeighbors = 0;
587 for (uint32_t i = 0; i < numberOfDevices; i++)
602 GetAdjacentNetDevices (localNetDevice,
channel, netDeviceContainer);
604 totalNeighbors += netDeviceContainer.
GetN ();
607 return totalNeighbors;
610 template <
typename T>
625 for (uint32_t i = 0; i < nDevices; ++i)
632 NS_LOG_LOGIC (
"device " << i <<
" is a bridge net device");
634 NS_ABORT_MSG_UNLESS (bnd,
"NixVectorRouting::NetDeviceIsBridged (): GetObject for <BridgeNetDevice> failed");
641 NS_LOG_LOGIC (
"Net device " << nd <<
" is bridged by " << bnd);
647 NS_LOG_LOGIC (
"Net device " << nd <<
" is not bridged");
651 template <
typename T>
659 uint32_t totalNeighbors = 0;
663 for (uint32_t i = 0; i < numberOfDevices; i++)
678 GetAdjacentNetDevices (localNetDevice,
channel, netDeviceContainer);
681 if (nodeIndex < (totalNeighbors + netDeviceContainer.
GetN ()))
685 Ptr<NetDevice> gatewayDevice = netDeviceContainer.
Get (nodeIndex-totalNeighbors);
686 Ptr<IpInterface> gatewayInterface = GetInterfaceByNetDevice (gatewayDevice);
688 gatewayIp = ifAddr.GetAddress ();
691 totalNeighbors += netDeviceContainer.
GetN ();
697 template <
typename T>
707 CheckCacheStateAndFlush ();
709 IpAddress destAddress = header.GetDestination ();
713 if constexpr (!IsIpv4::value)
716 if (destAddress.IsLinkLocalMulticast ())
718 NS_ASSERT_MSG (oif,
"Try to send on link-local multicast address, and no interface index is given!");
719 rtentry = Create<IpRoute> ();
720 rtentry->SetSource (m_ip->SourceAddressSelection (m_ip->GetInterfaceForDevice (oif), destAddress));
721 rtentry->SetDestination (destAddress);
723 rtentry->SetOutputDevice (oif);
728 bool foundInCache =
false;
729 nixVectorInCache = GetNixVectorInCache (destAddress, foundInCache);
737 nixVectorInCache = GetNixVector (m_node, destAddress, oif);
740 m_nixCache.insert (
typename NixMap_t::value_type (destAddress, nixVectorInCache));
744 if (nixVectorInCache)
746 NS_LOG_LOGIC (
"Nix-vector contents: " << *nixVectorInCache);
750 nixVectorForPacket = nixVectorInCache->
Copy ();
754 if (m_totalNeighbors == 0)
756 m_totalNeighbors = FindTotalNeighbors (m_node);
761 uint32_t numberOfBits = nixVectorForPacket->
BitCount (m_totalNeighbors);
766 rtentry = GetIpRouteInCache (destAddress);
768 if (!rtentry || !(rtentry->GetOutputDevice () == oif))
777 m_ipRouteCache.erase (destAddress);
782 uint32_t index = FindNetDeviceForNixIndex (m_node, nodeIndex, gatewayIp);
783 int32_t interfaceIndex = 0;
787 interfaceIndex = (m_ip)->GetInterfaceForDevice (m_node->GetDevice (index));
791 interfaceIndex = (m_ip)->GetInterfaceForDevice (oif);
794 NS_ASSERT_MSG (interfaceIndex != -1,
"Interface index not found for device");
796 IpAddress sourceIPAddr = m_ip->SourceAddressSelection (interfaceIndex, destAddress);
799 rtentry = Create<IpRoute> ();
800 rtentry->SetSource (sourceIPAddr);
802 rtentry->SetGateway (gatewayIp);
803 rtentry->SetDestination (destAddress);
807 rtentry->SetOutputDevice (m_ip->GetNetDevice (interfaceIndex));
811 rtentry->SetOutputDevice (oif);
817 m_ipRouteCache.insert (
typename IpRouteMap_t::value_type (destAddress, rtentry));
826 NS_LOG_LOGIC (
"Adding Nix-vector to packet: " << *nixVectorForPacket);
839 template <
typename T>
845 NS_LOG_FUNCTION (
this << p << header << header.GetSource () << header.GetDestination () << idev);
847 CheckCacheStateAndFlush ();
851 NS_ASSERT (m_ip->GetInterfaceForDevice (idev) >= 0);
852 uint32_t iif = m_ip->GetInterfaceForDevice (idev);
856 IpAddress destAddress = header.GetDestination ();
858 if constexpr (IsIpv4::value)
861 if (m_ip->IsDestinationAddress (destAddress, iif))
866 lcb (p, header, iif);
882 if (destAddress.IsMulticast ())
884 NS_LOG_LOGIC (
"Multicast route not supported by Nix-Vector routing " << destAddress);
889 if (m_ip->IsForwarding (iif) ==
false)
891 NS_LOG_LOGIC (
"Forwarding disabled for this interface");
910 if (m_totalNeighbors == 0)
912 m_totalNeighbors = FindTotalNeighbors (m_node);
914 uint32_t numberOfBits = nixVector->
BitCount (m_totalNeighbors);
917 rtentry = GetIpRouteInCache (destAddress);
923 uint32_t index = FindNetDeviceForNixIndex (m_node, nodeIndex, gatewayIp);
924 uint32_t interfaceIndex = (m_ip)->GetInterfaceForDevice (m_node->GetDevice (index));
928 rtentry = Create<IpRoute> ();
929 rtentry->SetSource (ifAddr.GetAddress ());
931 rtentry->SetGateway (gatewayIp);
932 rtentry->SetDestination (destAddress);
933 rtentry->SetOutputDevice (m_ip->GetNetDevice (interfaceIndex));
936 m_ipRouteCache.insert (
typename IpRouteMap_t::value_type (destAddress, rtentry));
939 NS_LOG_LOGIC (
"At Node " << m_node->GetId () <<
", Extracting " << numberOfBits <<
940 " bits from Nix-vector: " << nixVector <<
" : " << *nixVector);
946 if constexpr (IsIpv4::value)
948 ucb (rtentry, p, header);
952 ucb (idev, rtentry, p, header);
958 template <
typename T>
964 CheckCacheStateAndFlush ();
968 std::ios oldState (
nullptr);
969 oldState.copyfmt (*os);
971 *os << std::resetiosflags (std::ios::adjustfield) << std::setiosflags (std::ios::left);
973 *os <<
"Node: " << m_ip->template GetObject<Node> ()->GetId ()
974 <<
", Time: " <<
Now().
As (unit)
975 <<
", Local time: " << m_ip->template GetObject<Node> ()->GetLocalTime ().As (unit)
976 <<
", Nix Routing" << std::endl;
978 *os <<
"NixCache:" << std::endl;
979 if (m_nixCache.size () > 0)
981 *os << std::setw (30) <<
"Destination";
982 *os <<
"NixVector" << std::endl;
983 for (
typename NixMap_t::const_iterator it = m_nixCache.begin (); it != m_nixCache.end (); it++)
985 std::ostringstream dest;
987 *os << std::setw (30) << dest.str ();
990 *os << *(it->second) << std::endl;
994 *os <<
"IpRouteCache:" << std::endl;
995 if (m_ipRouteCache.size () > 0)
997 *os << std::setw (30) <<
"Destination";
998 *os << std::setw (30) <<
"Gateway";
999 *os << std::setw (30) <<
"Source";
1000 *os <<
"OutputDevice" << std::endl;
1001 for (
typename IpRouteMap_t::const_iterator it = m_ipRouteCache.begin (); it != m_ipRouteCache.end (); it++)
1003 std::ostringstream dest, gw, src;
1004 dest << it->second->GetDestination ();
1005 *os << std::setw (30) << dest.str ();
1006 gw << it->second->GetGateway ();
1007 *os << std::setw (30) << gw.str ();
1008 src << it->second->GetSource ();
1009 *os << std::setw (30) << src.str ();
1017 *os << it->second->GetOutputDevice ()->GetIfIndex ();
1024 (*os).copyfmt (oldState);
1028 template <
typename T>
1032 g_isCacheDirty =
true;
1034 template <
typename T>
1038 g_isCacheDirty =
true;
1040 template <
typename T>
1044 g_isCacheDirty =
true;
1046 template <
typename T>
1050 g_isCacheDirty =
true;
1052 template <
typename T>
1056 g_isCacheDirty =
true;
1058 template <
typename T>
1062 g_isCacheDirty =
true;
1065 template <
typename T>
1071 NS_LOG_FUNCTION (
this << numberOfNodes << source << dest << parentVector << oif);
1074 std::queue< Ptr<Node> > greyNodeList;
1077 parentVector.assign (numberOfNodes, 0);
1080 greyNodeList.push (source);
1081 parentVector.at (source->
GetId ()) = source;
1084 while (greyNodeList.size () != 0)
1086 Ptr<Node> currNode = greyNodeList.front ();
1089 if (currNode == dest)
1098 if (currNode == source && oif)
1103 uint32_t interfaceIndex = (ip)->GetInterfaceForDevice (oif);
1104 if (!(ip->IsUp (interfaceIndex)))
1124 GetAdjacentNetDevices (oif,
channel, netDeviceContainer);
1132 Ptr<Node> remoteNode = (*iter)->GetNode ();
1134 if (remoteIpInterface == 0 || !(remoteIpInterface->IsUp ()))
1136 NS_LOG_LOGIC (
"IpInterface either doesn't exist or is down");
1144 if (parentVector.at (remoteNode->
GetId ()) == 0)
1146 parentVector.at (remoteNode->
GetId ()) = currNode;
1147 greyNodeList.push (remoteNode);
1155 for (uint32_t i = 0; i < (currNode->
GetNDevices ()); i++)
1165 uint32_t interfaceIndex = (ip)->GetInterfaceForDevice (currNode->
GetDevice (i));
1166 if (!(ip->IsUp (interfaceIndex)))
1172 if (!(localNetDevice->
IsLinkUp ()))
1186 GetAdjacentNetDevices (localNetDevice,
channel, netDeviceContainer);
1194 Ptr<Node> remoteNode = (*iter)->GetNode ();
1196 if (remoteIpInterface == 0 || !(remoteIpInterface->IsUp ()))
1198 NS_LOG_LOGIC (
"IpInterface either doesn't exist or is down");
1206 if (parentVector.at (remoteNode->
GetId ()) == 0)
1208 parentVector.at (remoteNode->
GetId ()) = currNode;
1209 greyNodeList.push (remoteNode);
1217 greyNodeList.pop ();
1224 template <
typename T>
1235 CheckCacheStateAndFlush ();
1237 Ptr<Node> destNode = GetNodeByIp (dest);
1244 std::ostream* os = stream->
GetStream ();
1246 std::ios oldState (
nullptr);
1247 oldState.copyfmt (*os);
1249 *os << std::resetiosflags (std::ios::adjustfield) << std::setiosflags (std::ios::left);
1250 *os <<
"Time: " <<
Now().
As (unit)
1251 <<
", Nix Routing" << std::endl;
1252 *os <<
"Route Path: ";
1253 *os <<
"(Node " << source->
GetId () <<
" to Node " << destNode->
GetId () <<
", ";
1254 *os <<
"Nix Vector: ";
1257 bool foundInCache =
true;
1258 nixVectorInCache = GetNixVectorInCache (dest, foundInCache);
1266 nixVectorInCache = GetNixVector (source, dest,
nullptr);
1268 m_nixCache.insert (
typename NixMap_t::value_type (dest, nixVectorInCache));
1271 if (nixVectorInCache || (!nixVectorInCache && source == destNode))
1274 uint32_t totalNeighbors = 0;
1276 if (nixVectorInCache)
1281 nixVector = nixVectorInCache->
Copy ();
1285 *os <<
")" << std::endl;
1287 if (source == destNode)
1289 std::ostringstream addr, node;
1291 node <<
"(Node " << destNode->
GetId () <<
")";
1292 *os << std::setw (25) << addr.str ();
1293 *os << std::setw (10) << node.str ();
1295 *os << std::setw (25) << addr.str ();
1296 *os << node.str () << std::endl;
1299 while (curr != destNode)
1301 totalNeighbors = FindTotalNeighbors (curr);
1304 uint32_t numberOfBits = nixVector->
BitCount (totalNeighbors);
1311 uint32_t netDeviceIndex = FindNetDeviceForNixIndex (curr, nixIndex, gatewayIp);
1317 uint32_t interfaceIndex = ip->GetInterfaceForDevice (outDevice);
1321 sourceIPAddr = ip->SourceAddressSelection (interfaceIndex, dest);
1327 sourceIPAddr = ip->GetAddress (interfaceIndex, 0).GetAddress ();
1330 std::ostringstream currAddr, currNode, nextAddr, nextNode;
1331 currAddr << sourceIPAddr;
1332 currNode <<
"(Node " << curr->
GetId () <<
")";
1333 *os << std::setw (25) << currAddr.str ();
1334 *os << std::setw (10) << currNode.str ();
1336 curr = GetNodeByIp (gatewayIp);
1337 nextAddr << ((curr == destNode) ? dest : gatewayIp);
1338 nextNode <<
"(Node " << curr->GetId () <<
")";
1340 *os << std::setw (25) << nextAddr.str ();
1341 *os << nextNode.str () << std::endl;
1347 *os <<
")" << std::endl;
1349 *os <<
"There does not exist a path from Node " << source->
GetId ()
1350 <<
" to Node " << destNode->
GetId () <<
"." << std::endl;
1353 (*os).copyfmt (oldState);
1356 template <
typename T>
1362 FlushGlobalNixRoutingCache ();
1363 g_isCacheDirty =
false;