A Discrete-Event Network Simulator
API
nix-vector-routing.cc
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2009 The Georgia Institute of Technology
4  * Copyright (c) 2021 NITK Surathkal
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License version 2 as
8  * published by the Free Software Foundation;
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18  *
19  * This file is adapted from the old ipv4-nix-vector-routing.cc.
20  *
21  * Authors: Josh Pelkey <jpelkey@gatech.edu>
22  *
23  * Modified by: Ameya Deshpande <ameyanrd@outlook.com>
24  */
25 
26 #include <queue>
27 #include <iomanip>
28 
29 #include "ns3/log.h"
30 #include "ns3/abort.h"
31 #include "ns3/names.h"
32 #include "ns3/ipv4-list-routing.h"
33 #include "ns3/loopback-net-device.h"
34 
35 #include "nix-vector-routing.h"
36 
37 namespace ns3 {
38 
39 NS_LOG_COMPONENT_DEFINE ("NixVectorRouting");
40 
41 NS_OBJECT_TEMPLATE_CLASS_DEFINE (NixVectorRouting, Ipv4RoutingProtocol);
42 NS_OBJECT_TEMPLATE_CLASS_DEFINE (NixVectorRouting, Ipv6RoutingProtocol);
43 
44 template <typename T>
46 
47 template <typename T>
49 
50 template <typename T>
52 
53 template <typename T>
54 TypeId
56 {
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 ())
60  .SetParent<T> ()
61  .SetGroupName ("NixVectorRouting")
62  .template AddConstructor<NixVectorRouting<T> > ()
63  ;
64  return tid;
65 }
66 
67 template <typename T>
69  : m_totalNeighbors (0)
70 {
72 }
73 
74 template <typename T>
76 {
78 }
79 
80 template <typename T>
81 void
83 {
84  NS_ASSERT (ipv4 != 0);
85  NS_ASSERT (m_ip == 0);
86  NS_LOG_DEBUG ("Created Ipv4NixVectorProtocol");
87 
88  m_ip = ipv4;
89 }
90 
91 template <typename T>
92 void
94 {
95  NS_ASSERT (ipv6 != 0);
96  NS_ASSERT (m_ip == 0);
97  NS_LOG_DEBUG ("Created Ipv6NixVectorProtocol");
98 
99  m_ip = ipv6;
100 }
101 
102 template <typename T>
103 void
105 {
106  NS_LOG_FUNCTION (this);
107 
108  for (uint32_t i = 0 ; i < m_ip->GetNInterfaces (); i++)
109  {
110  m_ip->SetForwarding (i, true);
111  }
112 
113  T::DoInitialize ();
114 }
115 
116 template <typename T>
117 void
119 {
121 
122  m_node = 0;
123  m_ip = 0;
124 
125  T::DoDispose ();
126 }
127 
128 template <typename T>
129 void
131 {
133 
134  m_node = node;
135 }
136 
137 template <typename T>
138 void
140 {
142 
143  NodeList::Iterator listEnd = NodeList::End ();
144  for (NodeList::Iterator i = NodeList::Begin (); i != listEnd; i++)
145  {
146  Ptr<Node> node = *i;
148  if (!rp)
149  {
150  continue;
151  }
152  NS_LOG_LOGIC ("Flushing Nix caches.");
153  rp->FlushNixCache ();
154  rp->FlushIpRouteCache ();
155  rp->m_totalNeighbors = 0;
156  }
157 
158  // IP address to node mapping is potentially invalid so clear it.
159  // Will be repopulated in lazy evaluation when mapping is needed.
160  g_ipAddressToNodeMap.clear ();
161 }
162 
163 template <typename T>
164 void
166 {
168  m_nixCache.clear ();
169 }
170 
171 template <typename T>
172 void
174 {
176  m_ipRouteCache.clear ();
177 }
178 
179 template <typename T>
182 {
183  NS_LOG_FUNCTION (this << source << dest << oif);
184 
185  Ptr<NixVector> nixVector = Create<NixVector> ();
186 
187  // not in cache, must build the nix vector
188  // First, we have to figure out the nodes
189  // associated with these IPs
190  Ptr<Node> destNode = GetNodeByIp (dest);
191  if (destNode == 0)
192  {
193  NS_LOG_ERROR ("No routing path exists");
194  return 0;
195  }
196 
197  // if source == dest, then we have a special case
200  if (source == destNode)
201  {
202  NS_LOG_DEBUG ("Do not process packets to self");
203  return 0;
204  }
205  else
206  {
207  // otherwise proceed as normal
208  // and build the nix vector
209  std::vector< Ptr<Node> > parentVector;
210 
211  if (BFS (NodeList::GetNNodes (), source, destNode, parentVector, oif))
212  {
213  if (BuildNixVector (parentVector, source->GetId (), destNode->GetId (), nixVector))
214  {
215  return nixVector;
216  }
217  else
218  {
219  NS_LOG_ERROR ("No routing path exists");
220  return 0;
221  }
222  }
223  else
224  {
225  NS_LOG_ERROR ("No routing path exists");
226  return 0;
227  }
228 
229  }
230 }
231 
232 template <typename T>
235 {
236  NS_LOG_FUNCTION (this << address);
237 
238  CheckCacheStateAndFlush ();
239 
240  typename NixMap_t::iterator iter = m_nixCache.find (address);
241  if (iter != m_nixCache.end ())
242  {
243  NS_LOG_LOGIC ("Found Nix-vector in cache.");
244  foundInCache = true;
245  return iter->second;
246  }
247 
248  // not in cache
249  foundInCache = false;
250  return 0;
251 }
252 
253 template <typename T>
256 {
257  NS_LOG_FUNCTION (this << address);
258 
259  CheckCacheStateAndFlush ();
260 
261  typename IpRouteMap_t::iterator iter = m_ipRouteCache.find (address);
262  if (iter != m_ipRouteCache.end ())
263  {
264  NS_LOG_LOGIC ("Found IpRoute in cache.");
265  return iter->second;
266  }
267 
268  // not in cache
269  return 0;
270 }
271 
272 template <typename T>
273 bool
274 NixVectorRouting<T>::BuildNixVector (const std::vector< Ptr<Node> > & parentVector, uint32_t source, uint32_t dest, Ptr<NixVector> nixVector) const
275 {
276  NS_LOG_FUNCTION (this << parentVector << source << dest << nixVector);
277 
278  if (source == dest)
279  {
280  return true;
281  }
282 
283  if (parentVector.at (dest) == 0)
284  {
285  return false;
286  }
287 
288  Ptr<Node> parentNode = parentVector.at (dest);
289 
290  uint32_t numberOfDevices = parentNode->GetNDevices ();
291  uint32_t destId = 0;
292  uint32_t totalNeighbors = 0;
293 
294  // scan through the net devices on the T node
295  // and then look at the nodes adjacent to them
296  for (uint32_t i = 0; i < numberOfDevices; i++)
297  {
298  // Get a net device from the node
299  // as well as the channel, and figure
300  // out the adjacent net devices
301  Ptr<NetDevice> localNetDevice = parentNode->GetDevice (i);
302  if (localNetDevice->IsBridge ())
303  {
304  continue;
305  }
306  Ptr<Channel> channel = localNetDevice->GetChannel ();
307  if (channel == 0)
308  {
309  continue;
310  }
311 
312  // this function takes in the local net dev, and channel, and
313  // writes to the netDeviceContainer the adjacent net devs
314  NetDeviceContainer netDeviceContainer;
315  GetAdjacentNetDevices (localNetDevice, channel, netDeviceContainer);
316 
317  // Finally we can get the adjacent nodes
318  // and scan through them. If we find the
319  // node that matches "dest" then we can add
320  // the index to the nix vector.
321  // the index corresponds to the neighbor index
322  uint32_t offset = 0;
323  for (NetDeviceContainer::Iterator iter = netDeviceContainer.Begin (); iter != netDeviceContainer.End (); iter++)
324  {
325  Ptr<Node> remoteNode = (*iter)->GetNode ();
326 
327  if (remoteNode->GetId () == dest)
328  {
329  destId = totalNeighbors + offset;
330  }
331  offset += 1;
332  }
333 
334  totalNeighbors += netDeviceContainer.GetN ();
335  }
336  NS_LOG_LOGIC ("Adding Nix: " << destId << " with "
337  << nixVector->BitCount (totalNeighbors) << " bits, for node " << parentNode->GetId ());
338  nixVector->AddNeighborIndex (destId, nixVector->BitCount (totalNeighbors));
339 
340  // recurse through T vector, grabbing the path
341  // and building the nix vector
342  BuildNixVector (parentVector, source, (parentVector.at (dest))->GetId (), nixVector);
343  return true;
344 }
345 
346 template <typename T>
347 void
349 {
350  NS_LOG_FUNCTION (this << netDevice << channel);
351 
352  Ptr<IpInterface> netDeviceInterface = GetInterfaceByNetDevice (netDevice);
353  if (netDeviceInterface == 0 || !netDeviceInterface->IsUp ())
354  {
355  NS_LOG_LOGIC ("IpInterface either doesn't exist or is down");
356  return;
357  }
358 
359  uint32_t netDeviceAddresses = netDeviceInterface->GetNAddresses ();
360 
361  for (std::size_t i = 0; i < channel->GetNDevices (); i++)
362  {
363  Ptr<NetDevice> remoteDevice = channel->GetDevice (i);
364  if (remoteDevice != netDevice)
365  {
366  // Compare if the remoteDevice shares a common subnet with remoteDevice
367  Ptr<IpInterface> remoteDeviceInterface = GetInterfaceByNetDevice (remoteDevice);
368  if (remoteDeviceInterface == 0 || !remoteDeviceInterface->IsUp ())
369  {
370  NS_LOG_LOGIC ("IpInterface either doesn't exist or is down");
371  continue;
372  }
373 
374  uint32_t remoteDeviceAddresses = remoteDeviceInterface->GetNAddresses ();
375  bool commonSubnetFound = false;
376 
377  for (uint32_t j = 0; j < netDeviceAddresses; ++j)
378  {
379  IpInterfaceAddress netDeviceIfAddr = netDeviceInterface->GetAddress (j);
380  if constexpr (!IsIpv4::value)
381  {
382  if (netDeviceIfAddr.GetScope () == Ipv6InterfaceAddress::LINKLOCAL)
383  {
384  continue;
385  }
386  }
387  for (uint32_t k = 0; k < remoteDeviceAddresses; ++k)
388  {
389  IpInterfaceAddress remoteDeviceIfAddr = remoteDeviceInterface->GetAddress (k);
390  if constexpr (!IsIpv4::value)
391  {
392  if (remoteDeviceIfAddr.GetScope () == Ipv6InterfaceAddress::LINKLOCAL)
393  {
394  continue;
395  }
396  }
397  if (netDeviceIfAddr.IsInSameSubnet (remoteDeviceIfAddr.GetAddress ()))
398  {
399  commonSubnetFound = true;
400  break;
401  }
402  }
403 
404  if (commonSubnetFound)
405  {
406  break;
407  }
408  }
409 
410  if (!commonSubnetFound)
411  {
412  continue;
413  }
414 
415  Ptr<BridgeNetDevice> bd = NetDeviceIsBridged (remoteDevice);
416  // we have a bridged device, we need to add all
417  // bridged devices
418  if (bd)
419  {
420  NS_LOG_LOGIC ("Looking through bridge ports of bridge net device " << bd);
421  for (uint32_t j = 0; j < bd->GetNBridgePorts (); ++j)
422  {
423  Ptr<NetDevice> ndBridged = bd->GetBridgePort (j);
424  if (ndBridged == remoteDevice)
425  {
426  NS_LOG_LOGIC ("That bridge port is me, don't walk backward");
427  continue;
428  }
429  Ptr<Channel> chBridged = ndBridged->GetChannel ();
430  if (chBridged == 0)
431  {
432  continue;
433  }
434  GetAdjacentNetDevices (ndBridged, chBridged, netDeviceContainer);
435  }
436  }
437  else
438  {
439  netDeviceContainer.Add (channel->GetDevice (i));
440  }
441  }
442  }
443 }
444 
445 template <typename T>
446 void
448 {
450 
451  for (NodeList::Iterator it = NodeList::Begin (); it != NodeList::End (); ++it)
452  {
453  Ptr<Node> node = *it;
455 
456  if(ip)
457  {
458  uint32_t numberOfDevices = node->GetNDevices ();
459 
460  for (uint32_t deviceId = 0; deviceId < numberOfDevices; deviceId++)
461  {
462  Ptr<NetDevice> device = node->GetDevice (deviceId);
463 
464  // If this is not a loopback device add the IP address to the map
465  if ( !DynamicCast<LoopbackNetDevice>(device) )
466  {
467  int32_t interfaceIndex = (ip)->GetInterfaceForDevice (node->GetDevice (deviceId));
468  if (interfaceIndex != -1)
469  {
470  g_netdeviceToIpInterfaceMap[device] = (ip)->GetInterface (interfaceIndex);
471 
472  uint32_t numberOfAddresses = ip->GetNAddresses (interfaceIndex);
473  for (uint32_t addressIndex = 0; addressIndex < numberOfAddresses; addressIndex++)
474  {
475  IpInterfaceAddress ifAddr = ip->GetAddress (interfaceIndex, addressIndex);
476  IpAddress addr = ifAddr.GetAddress ();
477 
478  NS_ABORT_MSG_IF (g_ipAddressToNodeMap.count (addr),
479  "Duplicate IP address (" << addr << ") found during NIX Vector map construction for node " << node->GetId ());
480 
481  NS_LOG_LOGIC ("Adding IP address " << addr << " for node " << node->GetId () << " to NIX Vector IP address to node map");
482  g_ipAddressToNodeMap[addr] = node;
483  }
484  }
485  }
486  }
487  }
488  }
489 }
490 
491 template <typename T>
492 Ptr<Node>
494 {
495  NS_LOG_FUNCTION (this << dest);
496 
497  // Populate lookup table if is empty.
498  if ( g_ipAddressToNodeMap.empty () )
499  {
500  BuildIpAddressToNodeMap ();
501  }
502 
503  Ptr<Node> destNode;
504 
505  typename IpAddressToNodeMap::iterator iter = g_ipAddressToNodeMap.find(dest);
506 
507  if(iter == g_ipAddressToNodeMap.end ())
508  {
509  NS_LOG_ERROR ("Couldn't find dest node given the IP" << dest);
510  destNode = 0;
511  }
512  else
513  {
514  destNode = iter -> second;
515  }
516 
517  return destNode;
518 }
519 
520 template <typename T>
523 {
524  // Populate lookup table if is empty.
525  if ( g_netdeviceToIpInterfaceMap.empty () )
526  {
527  BuildIpAddressToNodeMap ();
528  }
529 
530  Ptr<IpInterface> ipInterface;
531 
532  typename NetDeviceToIpInterfaceMap::iterator iter = g_netdeviceToIpInterfaceMap.find(netDevice);
533 
534  if(iter == g_netdeviceToIpInterfaceMap.end ())
535  {
536  NS_LOG_ERROR ("Couldn't find IpInterface node given the NetDevice" << netDevice);
537  ipInterface = 0;
538  }
539  else
540  {
541  ipInterface = iter -> second;
542  }
543 
544  return ipInterface;
545 }
546 
547 template <typename T>
548 uint32_t
550 {
551  NS_LOG_FUNCTION (this << node);
552 
553  uint32_t numberOfDevices = node->GetNDevices ();
554  uint32_t totalNeighbors = 0;
555 
556  // scan through the net devices on the T node
557  // and then look at the nodes adjacent to them
558  for (uint32_t i = 0; i < numberOfDevices; i++)
559  {
560  // Get a net device from the node
561  // as well as the channel, and figure
562  // out the adjacent net devices
563  Ptr<NetDevice> localNetDevice = node->GetDevice (i);
564  Ptr<Channel> channel = localNetDevice->GetChannel ();
565  if (channel == 0)
566  {
567  continue;
568  }
569 
570  // this function takes in the local net dev, and channel, and
571  // writes to the netDeviceContainer the adjacent net devs
572  NetDeviceContainer netDeviceContainer;
573  GetAdjacentNetDevices (localNetDevice, channel, netDeviceContainer);
574 
575  totalNeighbors += netDeviceContainer.GetN ();
576  }
577 
578  return totalNeighbors;
579 }
580 
581 template <typename T>
584 {
585  NS_LOG_FUNCTION (this << nd);
586 
587  Ptr<Node> node = nd->GetNode ();
588  uint32_t nDevices = node->GetNDevices ();
589 
590  //
591  // There is no bit on a net device that says it is being bridged, so we have
592  // to look for bridges on the node to which the device is attached. If we
593  // find a bridge, we need to look through its bridge ports (the devices it
594  // bridges) to see if we find the device in question.
595  //
596  for (uint32_t i = 0; i < nDevices; ++i)
597  {
598  Ptr<NetDevice> ndTest = node->GetDevice (i);
599  NS_LOG_LOGIC ("Examine device " << i << " " << ndTest);
600 
601  if (ndTest->IsBridge ())
602  {
603  NS_LOG_LOGIC ("device " << i << " is a bridge net device");
605  NS_ABORT_MSG_UNLESS (bnd, "NixVectorRouting::NetDeviceIsBridged (): GetObject for <BridgeNetDevice> failed");
606 
607  for (uint32_t j = 0; j < bnd->GetNBridgePorts (); ++j)
608  {
609  NS_LOG_LOGIC ("Examine bridge port " << j << " " << bnd->GetBridgePort (j));
610  if (bnd->GetBridgePort (j) == nd)
611  {
612  NS_LOG_LOGIC ("Net device " << nd << " is bridged by " << bnd);
613  return bnd;
614  }
615  }
616  }
617  }
618  NS_LOG_LOGIC ("Net device " << nd << " is not bridged");
619  return 0;
620 }
621 
622 template <typename T>
623 uint32_t
624 NixVectorRouting<T>::FindNetDeviceForNixIndex (Ptr<Node> node, uint32_t nodeIndex, IpAddress & gatewayIp) const
625 {
626  NS_LOG_FUNCTION (this << node << nodeIndex << gatewayIp);
627 
628  uint32_t numberOfDevices = node->GetNDevices ();
629  uint32_t index = 0;
630  uint32_t totalNeighbors = 0;
631 
632  // scan through the net devices on the parent node
633  // and then look at the nodes adjacent to them
634  for (uint32_t i = 0; i < numberOfDevices; i++)
635  {
636  // Get a net device from the node
637  // as well as the channel, and figure
638  // out the adjacent net devices
639  Ptr<NetDevice> localNetDevice = node->GetDevice (i);
640  Ptr<Channel> channel = localNetDevice->GetChannel ();
641  if (channel == 0)
642  {
643  continue;
644  }
645 
646  // this function takes in the local net dev, and channel, and
647  // writes to the netDeviceContainer the adjacent net devs
648  NetDeviceContainer netDeviceContainer;
649  GetAdjacentNetDevices (localNetDevice, channel, netDeviceContainer);
650 
651  // check how many neighbors we have
652  if (nodeIndex < (totalNeighbors + netDeviceContainer.GetN ()))
653  {
654  // found the proper net device
655  index = i;
656  Ptr<NetDevice> gatewayDevice = netDeviceContainer.Get (nodeIndex-totalNeighbors);
657  Ptr<IpInterface> gatewayInterface = GetInterfaceByNetDevice (gatewayDevice);
658  IpInterfaceAddress ifAddr = gatewayInterface->GetAddress (0);
659  gatewayIp = ifAddr.GetAddress ();
660  break;
661  }
662  totalNeighbors += netDeviceContainer.GetN ();
663  }
664 
665  return index;
666 }
667 
668 template <typename T>
671 {
672  NS_LOG_FUNCTION (this << header << oif);
673 
674  Ptr<IpRoute> rtentry;
675  Ptr<NixVector> nixVectorInCache;
676  Ptr<NixVector> nixVectorForPacket;
677 
678  CheckCacheStateAndFlush ();
679 
680  IpAddress destAddress = header.GetDestination ();
681 
682  NS_LOG_DEBUG ("Dest IP from header: " << destAddress);
683 
684  if (destAddress.IsLocalhost ())
685  {
686  rtentry = Create<IpRoute> ();
687  rtentry->SetSource (IpAddress::GetLoopback ());
688  rtentry->SetDestination (destAddress);
689  rtentry->SetGateway (IpAddress::GetZero ());
690  for (uint32_t i = 0 ; i < m_ip->GetNInterfaces (); i++)
691  {
692  Ptr<LoopbackNetDevice> loNetDevice = DynamicCast<LoopbackNetDevice> (m_ip->GetNetDevice (i));
693  if (loNetDevice)
694  {
695  rtentry->SetOutputDevice (loNetDevice);
696  break;
697  }
698  }
699  return rtentry;
700  }
701 
702  if constexpr (!IsIpv4::value)
703  {
704  /* when sending on link-local multicast, there have to be interface specified */
705  if (destAddress.IsLinkLocalMulticast ())
706  {
707  NS_ASSERT_MSG (oif, "Try to send on link-local multicast address, and no interface index is given!");
708  rtentry = Create<IpRoute> ();
709  rtentry->SetSource (m_ip->SourceAddressSelection (m_ip->GetInterfaceForDevice (oif), destAddress));
710  rtentry->SetDestination (destAddress);
711  rtentry->SetGateway (Ipv6Address::GetZero ());
712  rtentry->SetOutputDevice (oif);
713  return rtentry;
714  }
715  }
716  // Check the Nix cache
717  bool foundInCache = false;
718  nixVectorInCache = GetNixVectorInCache (destAddress, foundInCache);
719 
720  // not in cache
721  if (!foundInCache)
722  {
723  NS_LOG_LOGIC ("Nix-vector not in cache, build: ");
724  // Build the nix-vector, given this node and the
725  // dest IP address
726  nixVectorInCache = GetNixVector (m_node, destAddress, oif);
727 
728  // cache it
729  m_nixCache.insert (typename NixMap_t::value_type (destAddress, nixVectorInCache));
730  }
731 
732  // path exists
733  if (nixVectorInCache)
734  {
735  NS_LOG_LOGIC ("Nix-vector contents: " << *nixVectorInCache);
736 
737  // create a new nix vector to be used,
738  // we want to keep the cached version clean
739  nixVectorForPacket = nixVectorInCache->Copy ();
740 
741  // Get the interface number that we go out of, by extracting
742  // from the nix-vector
743  if (m_totalNeighbors == 0)
744  {
745  m_totalNeighbors = FindTotalNeighbors (m_node);
746  }
747 
748  // Get the interface number that we go out of, by extracting
749  // from the nix-vector
750  uint32_t numberOfBits = nixVectorForPacket->BitCount (m_totalNeighbors);
751  uint32_t nodeIndex = nixVectorForPacket->ExtractNeighborIndex (numberOfBits);
752 
753  // Search here in a cache for this node index
754  // and look for a IpRoute
755  rtentry = GetIpRouteInCache (destAddress);
756 
757  if (!rtentry || !(rtentry->GetOutputDevice () == oif))
758  {
759  // not in cache or a different specified output
760  // device is to be used
761 
762  // first, make sure we erase existing (incorrect)
763  // rtentry from the map
764  if (rtentry)
765  {
766  m_ipRouteCache.erase (destAddress);
767  }
768 
769  NS_LOG_LOGIC ("IpRoute not in cache, build: ");
770  IpAddress gatewayIp;
771  uint32_t index = FindNetDeviceForNixIndex (m_node, nodeIndex, gatewayIp);
772  int32_t interfaceIndex = 0;
773 
774  if (!oif)
775  {
776  interfaceIndex = (m_ip)->GetInterfaceForDevice (m_node->GetDevice (index));
777  }
778  else
779  {
780  interfaceIndex = (m_ip)->GetInterfaceForDevice (oif);
781  }
782 
783  NS_ASSERT_MSG (interfaceIndex != -1, "Interface index not found for device");
784 
785  IpAddress sourceIPAddr = m_ip->SourceAddressSelection (interfaceIndex, destAddress);
786 
787  // start filling in the IpRoute info
788  rtentry = Create<IpRoute> ();
789  rtentry->SetSource (sourceIPAddr);
790 
791  rtentry->SetGateway (gatewayIp);
792  rtentry->SetDestination (destAddress);
793 
794  if (!oif)
795  {
796  rtentry->SetOutputDevice (m_ip->GetNetDevice (interfaceIndex));
797  }
798  else
799  {
800  rtentry->SetOutputDevice (oif);
801  }
802 
803  sockerr = Socket::ERROR_NOTERROR;
804 
805  // add rtentry to cache
806  m_ipRouteCache.insert (typename IpRouteMap_t::value_type (destAddress, rtentry));
807  }
808 
809  NS_LOG_LOGIC ("Nix-vector contents: " << *nixVectorInCache << " : Remaining bits: " << nixVectorForPacket->GetRemainingBits ());
810 
811  // Add nix-vector in the packet class
812  // make sure the packet exists first
813  if (p)
814  {
815  NS_LOG_LOGIC ("Adding Nix-vector to packet: " << *nixVectorForPacket);
816  p->SetNixVector (nixVectorForPacket);
817  }
818  }
819  else // path doesn't exist
820  {
821  NS_LOG_ERROR ("No path to the dest: " << destAddress);
822  sockerr = Socket::ERROR_NOROUTETOHOST;
823  }
824 
825  return rtentry;
826 }
827 
828 template <typename T>
829 bool
833 {
834  NS_LOG_FUNCTION (this << p << header << header.GetSource () << header.GetDestination () << idev);
835 
836  CheckCacheStateAndFlush ();
837 
838  NS_ASSERT (m_ip != 0);
839  // Check if input device supports IP
840  NS_ASSERT (m_ip->GetInterfaceForDevice (idev) >= 0);
841  uint32_t iif = m_ip->GetInterfaceForDevice (idev);
842  // Check if input device supports IP
843  NS_ASSERT (iif >= 0);
844 
845  IpAddress destAddress = header.GetDestination ();
846 
847  if constexpr (IsIpv4::value)
848  {
849  // Local delivery
850  if (m_ip->IsDestinationAddress (destAddress, iif))
851  {
852  if (!lcb.IsNull ())
853  {
854  NS_LOG_LOGIC ("Local delivery to " << destAddress);
855  lcb (p, header, iif);
856  return true;
857  }
858  else
859  {
860  // The local delivery callback is null. This may be a multicast
861  // or broadcast packet, so return false so that another
862  // multicast routing protocol can handle it. It should be possible
863  // to extend this to explicitly check whether it is a unicast
864  // packet, and invoke the error callback if so
865  return false;
866  }
867  }
868  }
869  else
870  {
871  if (destAddress.IsMulticast ())
872  {
873  NS_LOG_LOGIC ("Multicast route not supported by Nix-Vector routing " << destAddress);
874  return false; // Let other routing protocols try to handle this
875  }
876 
877  // Check if input device supports IP forwarding
878  if (m_ip->IsForwarding (iif) == false)
879  {
880  NS_LOG_LOGIC ("Forwarding disabled for this interface");
881  if (!ecb.IsNull ())
882  {
883  ecb (p, header, Socket::ERROR_NOROUTETOHOST);
884  }
885  return true;
886  }
887  }
888 
889  Ptr<IpRoute> rtentry;
890 
891  // Get the nix-vector from the packet
892  Ptr<NixVector> nixVector = p->GetNixVector ();
893 
894  // If nixVector isn't in packet, something went wrong
895  NS_ASSERT (nixVector);
896 
897  // Get the interface number that we go out of, by extracting
898  // from the nix-vector
899  if (m_totalNeighbors == 0)
900  {
901  m_totalNeighbors = FindTotalNeighbors (m_node);
902  }
903  uint32_t numberOfBits = nixVector->BitCount (m_totalNeighbors);
904  uint32_t nodeIndex = nixVector->ExtractNeighborIndex (numberOfBits);
905 
906  rtentry = GetIpRouteInCache (destAddress);
907  // not in cache
908  if (!rtentry)
909  {
910  NS_LOG_LOGIC ("IpRoute not in cache, build: ");
911  IpAddress gatewayIp;
912  uint32_t index = FindNetDeviceForNixIndex (m_node, nodeIndex, gatewayIp);
913  uint32_t interfaceIndex = (m_ip)->GetInterfaceForDevice (m_node->GetDevice (index));
914  IpInterfaceAddress ifAddr = m_ip->GetAddress (interfaceIndex, 0);
915 
916  // start filling in the IpRoute info
917  rtentry = Create<IpRoute> ();
918  rtentry->SetSource (ifAddr.GetAddress ());
919 
920  rtentry->SetGateway (gatewayIp);
921  rtentry->SetDestination (destAddress);
922  rtentry->SetOutputDevice (m_ip->GetNetDevice (interfaceIndex));
923 
924  // add rtentry to cache
925  m_ipRouteCache.insert (typename IpRouteMap_t::value_type (destAddress, rtentry));
926  }
927 
928  NS_LOG_LOGIC ("At Node " << m_node->GetId () << ", Extracting " << numberOfBits <<
929  " bits from Nix-vector: " << nixVector << " : " << *nixVector);
930 
931  // call the unicast callback
932  // local deliver is handled by Ipv4StaticRoutingImpl
933  // so this code is never even called if the packet is
934  // destined for this node.
935  if constexpr (IsIpv4::value)
936  {
937  ucb (rtentry, p, header);
938  }
939  else
940  {
941  ucb (idev, rtentry, p, header);
942  }
943 
944  return true;
945 }
946 
947 template <typename T>
948 void
950 {
952 
953  CheckCacheStateAndFlush ();
954 
955  std::ostream* os = stream->GetStream ();
956  // Copy the current ostream state
957  std::ios oldState (nullptr);
958  oldState.copyfmt (*os);
959 
960  *os << std::resetiosflags (std::ios::adjustfield) << std::setiosflags (std::ios::left);
961 
962  *os << "Node: " << m_ip->template GetObject<Node> ()->GetId ()
963  << ", Time: " << Now().As (unit)
964  << ", Local time: " << m_ip->template GetObject<Node> ()->GetLocalTime ().As (unit)
965  << ", Nix Routing" << std::endl;
966 
967  *os << "NixCache:" << std::endl;
968  if (m_nixCache.size () > 0)
969  {
970  *os << std::setw (30) << "Destination";
971  *os << "NixVector" << std::endl;
972  for (typename NixMap_t::const_iterator it = m_nixCache.begin (); it != m_nixCache.end (); it++)
973  {
974  std::ostringstream dest;
975  dest << it->first;
976  *os << std::setw (30) << dest.str ();
977  if (it->second)
978  {
979  *os << *(it->second) << std::endl;
980  }
981  }
982  }
983  *os << "IpRouteCache:" << std::endl;
984  if (m_ipRouteCache.size () > 0)
985  {
986  *os << std::setw (30) << "Destination";
987  *os << std::setw (30) << "Gateway";
988  *os << std::setw (30) << "Source";
989  *os << "OutputDevice" << std::endl;
990  for (typename IpRouteMap_t::const_iterator it = m_ipRouteCache.begin (); it != m_ipRouteCache.end (); it++)
991  {
992  std::ostringstream dest, gw, src;
993  dest << it->second->GetDestination ();
994  *os << std::setw (30) << dest.str ();
995  gw << it->second->GetGateway ();
996  *os << std::setw (30) << gw.str ();
997  src << it->second->GetSource ();
998  *os << std::setw (30) << src.str ();
999  *os << " ";
1000  if (Names::FindName (it->second->GetOutputDevice ()) != "")
1001  {
1002  *os << Names::FindName (it->second->GetOutputDevice ());
1003  }
1004  else
1005  {
1006  *os << it->second->GetOutputDevice ()->GetIfIndex ();
1007  }
1008  *os << std::endl;
1009  }
1010  }
1011  *os << std::endl;
1012  // Restore the previous ostream state
1013  (*os).copyfmt (oldState);
1014 }
1015 
1016 // virtual functions from Ipv4RoutingProtocol
1017 template <typename T>
1018 void
1020 {
1021  g_isCacheDirty = true;
1022 }
1023 template <typename T>
1024 void
1026 {
1027  g_isCacheDirty = true;
1028 }
1029 template <typename T>
1030 void
1032 {
1033  g_isCacheDirty = true;
1034 }
1035 template <typename T>
1036 void
1038 {
1039  g_isCacheDirty = true;
1040 }
1041 template <typename T>
1042 void
1043 NixVectorRouting<T>::NotifyAddRoute (IpAddress dst, Ipv6Prefix mask, IpAddress nextHop, uint32_t interface, IpAddress prefixToUse)
1044 {
1045  g_isCacheDirty = true;
1046 }
1047 template <typename T>
1048 void
1049 NixVectorRouting<T>::NotifyRemoveRoute (IpAddress dst, Ipv6Prefix mask, IpAddress nextHop, uint32_t interface, IpAddress prefixToUse)
1050 {
1051  g_isCacheDirty = true;
1052 }
1053 
1054 template <typename T>
1055 bool
1056 NixVectorRouting<T>::BFS (uint32_t numberOfNodes, Ptr<Node> source,
1057  Ptr<Node> dest, std::vector< Ptr<Node> > & parentVector,
1058  Ptr<NetDevice> oif) const
1059 {
1060  NS_LOG_FUNCTION (this << numberOfNodes << source << dest << parentVector << oif);
1061 
1062  NS_LOG_LOGIC ("Going from Node " << source->GetId () << " to Node " << dest->GetId ());
1063  std::queue< Ptr<Node> > greyNodeList; // discovered nodes with unexplored children
1064 
1065  // reset the parent vector
1066  parentVector.assign (numberOfNodes, 0); // initialize to 0
1067 
1068  // Add the source node to the queue, set its parent to itself
1069  greyNodeList.push (source);
1070  parentVector.at (source->GetId ()) = source;
1071 
1072  // BFS loop
1073  while (greyNodeList.size () != 0)
1074  {
1075  Ptr<Node> currNode = greyNodeList.front ();
1076  Ptr<IpL3Protocol> ip = currNode->GetObject<IpL3Protocol> ();
1077 
1078  if (currNode == dest)
1079  {
1080  NS_LOG_LOGIC ("Made it to Node " << currNode->GetId ());
1081  return true;
1082  }
1083 
1084  // if this is the first iteration of the loop and a
1085  // specific output interface was given, make sure
1086  // we go this way
1087  if (currNode == source && oif)
1088  {
1089  // make sure that we can go this way
1090  if (ip)
1091  {
1092  uint32_t interfaceIndex = (ip)->GetInterfaceForDevice (oif);
1093  if (!(ip->IsUp (interfaceIndex)))
1094  {
1095  NS_LOG_LOGIC ("IpInterface is down");
1096  return false;
1097  }
1098  }
1099  if (!(oif->IsLinkUp ()))
1100  {
1101  NS_LOG_LOGIC ("Link is down.");
1102  return false;
1103  }
1104  Ptr<Channel> channel = oif->GetChannel ();
1105  if (channel == 0)
1106  {
1107  return false;
1108  }
1109 
1110  // this function takes in the local net dev, and channel, and
1111  // writes to the netDeviceContainer the adjacent net devs
1112  NetDeviceContainer netDeviceContainer;
1113  GetAdjacentNetDevices (oif, channel, netDeviceContainer);
1114 
1115  // Finally we can get the adjacent nodes
1116  // and scan through them. We push them
1117  // to the greyNode queue, if they aren't
1118  // already there.
1119  for (NetDeviceContainer::Iterator iter = netDeviceContainer.Begin (); iter != netDeviceContainer.End (); iter++)
1120  {
1121  Ptr<Node> remoteNode = (*iter)->GetNode ();
1122  Ptr<IpInterface> remoteIpInterface = GetInterfaceByNetDevice(*iter);
1123  if (remoteIpInterface == 0 || !(remoteIpInterface->IsUp ()))
1124  {
1125  NS_LOG_LOGIC ("IpInterface either doesn't exist or is down");
1126  continue;
1127  }
1128 
1129  // check to see if this node has been pushed before
1130  // by checking to see if it has a parent
1131  // if it doesn't (null or 0), then set its parent and
1132  // push to the queue
1133  if (parentVector.at (remoteNode->GetId ()) == 0)
1134  {
1135  parentVector.at (remoteNode->GetId ()) = currNode;
1136  greyNodeList.push (remoteNode);
1137  }
1138  }
1139  }
1140  else
1141  {
1142  // Iterate over the current node's adjacent vertices
1143  // and push them into the queue
1144  for (uint32_t i = 0; i < (currNode->GetNDevices ()); i++)
1145  {
1146  // Get a net device from the node
1147  // as well as the channel, and figure
1148  // out the adjacent net device
1149  Ptr<NetDevice> localNetDevice = currNode->GetDevice (i);
1150 
1151  // make sure that we can go this way
1152  if (ip)
1153  {
1154  uint32_t interfaceIndex = (ip)->GetInterfaceForDevice (currNode->GetDevice (i));
1155  if (!(ip->IsUp (interfaceIndex)))
1156  {
1157  NS_LOG_LOGIC ("IpInterface is down");
1158  continue;
1159  }
1160  }
1161  if (!(localNetDevice->IsLinkUp ()))
1162  {
1163  NS_LOG_LOGIC ("Link is down.");
1164  continue;
1165  }
1166  Ptr<Channel> channel = localNetDevice->GetChannel ();
1167  if (channel == 0)
1168  {
1169  continue;
1170  }
1171 
1172  // this function takes in the local net dev, and channel, and
1173  // writes to the netDeviceContainer the adjacent net devs
1174  NetDeviceContainer netDeviceContainer;
1175  GetAdjacentNetDevices (localNetDevice, channel, netDeviceContainer);
1176 
1177  // Finally we can get the adjacent nodes
1178  // and scan through them. We push them
1179  // to the greyNode queue, if they aren't
1180  // already there.
1181  for (NetDeviceContainer::Iterator iter = netDeviceContainer.Begin (); iter != netDeviceContainer.End (); iter++)
1182  {
1183  Ptr<Node> remoteNode = (*iter)->GetNode ();
1184  Ptr<IpInterface> remoteIpInterface = GetInterfaceByNetDevice(*iter);
1185  if (remoteIpInterface == 0 || !(remoteIpInterface->IsUp ()))
1186  {
1187  NS_LOG_LOGIC ("IpInterface either doesn't exist or is down");
1188  continue;
1189  }
1190 
1191  // check to see if this node has been pushed before
1192  // by checking to see if it has a parent
1193  // if it doesn't (null or 0), then set its parent and
1194  // push to the queue
1195  if (parentVector.at (remoteNode->GetId ()) == 0)
1196  {
1197  parentVector.at (remoteNode->GetId ()) = currNode;
1198  greyNodeList.push (remoteNode);
1199  }
1200  }
1201  }
1202  }
1203 
1204  // Pop off the head grey node. We have all its children.
1205  // It is now black.
1206  greyNodeList.pop ();
1207  }
1208 
1209  // Didn't find the dest...
1210  return false;
1211 }
1212 
1213 template <typename T>
1214 void
1216  Ptr<OutputStreamWrapper> stream, Time::Unit unit) const
1217 {
1218  NS_LOG_FUNCTION (this << source << dest);
1219 
1220  Ptr<NixVector> nixVectorInCache;
1221  Ptr<NixVector> nixVector;
1222  Ptr<IpRoute> rtentry;
1223 
1224  CheckCacheStateAndFlush ();
1225 
1226  Ptr<Node> destNode = GetNodeByIp (dest);
1227  if (destNode == 0)
1228  {
1229  NS_LOG_ERROR ("No routing path exists");
1230  return;
1231  }
1232 
1233  std::ostream* os = stream->GetStream ();
1234  // Copy the current ostream state
1235  std::ios oldState (nullptr);
1236  oldState.copyfmt (*os);
1237 
1238  *os << std::resetiosflags (std::ios::adjustfield) << std::setiosflags (std::ios::left);
1239  *os << "Time: " << Now().As (unit)
1240  << ", Nix Routing" << std::endl;
1241  *os << "Route Path: ";
1242  *os << "(Node " << source->GetId () << " to Node " << destNode->GetId () << ", ";
1243  *os << "Nix Vector: ";
1244 
1245  // Check the Nix cache
1246  bool foundInCache = true;
1247  nixVectorInCache = GetNixVectorInCache (dest, foundInCache);
1248 
1249  // not in cache
1250  if (!foundInCache)
1251  {
1252  NS_LOG_LOGIC ("Nix-vector not in cache, build: ");
1253  // Build the nix-vector, given the source node and the
1254  // dest IP address
1255  nixVectorInCache = GetNixVector (source, dest, nullptr);
1256  // cache it
1257  m_nixCache.insert (typename NixMap_t::value_type (dest, nixVectorInCache));
1258  }
1259 
1260  if (nixVectorInCache || (!nixVectorInCache && source == destNode))
1261  {
1262  Ptr<Node> curr = source;
1263  uint32_t totalNeighbors = 0;
1264 
1265  if (nixVectorInCache)
1266  {
1267  // Make a NixVector copy to work with. This is because
1268  // we don't want to extract the bits from nixVectorInCache
1269  // which is stored in the m_nixCache.
1270  nixVector = nixVectorInCache->Copy ();
1271 
1272  *os << *nixVector;
1273  }
1274  *os << ")" << std::endl;
1275 
1276  if (source == destNode)
1277  {
1278  std::ostringstream addr, node;
1279  addr << dest;
1280  node << "(Node " << destNode->GetId () << ")";
1281  *os << std::setw (25) << addr.str ();
1282  *os << std::setw (10) << node.str ();
1283  *os << "----> ";
1284  *os << std::setw (25) << addr.str ();
1285  *os << node.str () << std::endl;
1286  }
1287 
1288  while (curr != destNode)
1289  {
1290  totalNeighbors = FindTotalNeighbors (curr);
1291  // Get the number of bits required
1292  // to represent all the neighbors
1293  uint32_t numberOfBits = nixVector->BitCount (totalNeighbors);
1294  // Get the nixIndex
1295  uint32_t nixIndex = nixVector->ExtractNeighborIndex (numberOfBits);
1296  // gatewayIP is the IP of next
1297  // node on channel found from nixIndex
1298  IpAddress gatewayIp;
1299  // Get the Net Device index from the nixIndex
1300  uint32_t netDeviceIndex = FindNetDeviceForNixIndex (curr, nixIndex, gatewayIp);
1301  // Get the interfaceIndex with the help of netDeviceIndex.
1302  // It will be used to get the IP address on interfaceIndex
1303  // interface of 'curr' node.
1304  Ptr<IpL3Protocol> ip = curr->GetObject<IpL3Protocol> ();
1305  Ptr<NetDevice> outDevice = curr->GetDevice (netDeviceIndex);
1306  uint32_t interfaceIndex = ip->GetInterfaceForDevice (outDevice);
1307  IpAddress sourceIPAddr;
1308  if (curr == source)
1309  {
1310  sourceIPAddr = ip->SourceAddressSelection (interfaceIndex, dest);
1311  }
1312  else
1313  {
1314  // We use the first address because it's indifferent which one
1315  // we use to identify intermediate routers
1316  sourceIPAddr = ip->GetAddress (interfaceIndex, 0).GetAddress ();
1317  }
1318 
1319  std::ostringstream currAddr, currNode, nextAddr, nextNode;
1320  currAddr << sourceIPAddr;
1321  currNode << "(Node " << curr->GetId () << ")";
1322  *os << std::setw (25) << currAddr.str ();
1323  *os << std::setw (10) << currNode.str ();
1324  // Replace curr with the next node
1325  curr = GetNodeByIp (gatewayIp);
1326  nextAddr << ((curr == destNode) ? dest : gatewayIp);
1327  nextNode << "(Node " << curr->GetId () << ")";
1328  *os << "----> ";
1329  *os << std::setw (25) << nextAddr.str ();
1330  *os << nextNode.str () << std::endl;
1331  }
1332  *os << std::endl;
1333  }
1334  else
1335  {
1336  *os << ")" << std::endl;
1337  // No Route exists
1338  *os << "There does not exist a path from Node " << source->GetId ()
1339  << " to Node " << destNode->GetId () << "." << std::endl;
1340  }
1341  // Restore the previous ostream state
1342  (*os).copyfmt (oldState);
1343 }
1344 
1345 template <typename T>
1346 void
1348 {
1349  if (g_isCacheDirty)
1350  {
1351  FlushGlobalNixRoutingCache ();
1352  g_isCacheDirty = false;
1353  }
1354 }
1355 
1356 /* Public template function declarations */
1361 template void NixVectorRouting<Ipv4RoutingProtocol>::PrintRoutingPath (Ptr<Node> source, IpAddress dest,
1362  Ptr<OutputStreamWrapper> stream, Time::Unit unit) const;
1363 template void NixVectorRouting<Ipv6RoutingProtocol>::PrintRoutingPath (Ptr<Node> source, IpAddress dest,
1364  Ptr<OutputStreamWrapper> stream, Time::Unit unit) const;
1365 
1366 } // namespace ns3
ns3::NetDeviceContainer
holds a vector of ns3::NetDevice pointers
Definition: net-device-container.h:42
ns3::TypeId
a unique identifier for an interface.
Definition: type-id.h:59
NS_LOG_COMPONENT_DEFINE
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:205
ns3::NixVectorRouting::FindNetDeviceForNixIndex
uint32_t FindNetDeviceForNixIndex(Ptr< Node > node, uint32_t nodeIndex, IpAddress &gatewayIp) const
Nix index is with respect to the neighbors.
Definition: nix-vector-routing.cc:624
ns3::NixVectorRouting::NotifyAddRoute
virtual void NotifyAddRoute(IpAddress dst, Ipv6Prefix mask, IpAddress nextHop, uint32_t interface, IpAddress prefixToUse=IpAddress::GetZero())
Notify a new route.
Definition: nix-vector-routing.cc:1043
ns3::NixVectorRouting::g_ipAddressToNodeMap
static IpAddressToNodeMap g_ipAddressToNodeMap
Address to node map.
Definition: nix-vector-routing.h:472
NS_ASSERT
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file,...
Definition: assert.h:67
ns3::NixVector::GetRemainingBits
uint32_t GetRemainingBits(void)
Definition: nix-vector.cc:357
ns3::NixVectorRouting::~NixVectorRouting
~NixVectorRouting()
Definition: nix-vector-routing.cc:75
ns3::NodeList::Begin
static Iterator Begin(void)
Definition: node-list.cc:229
ns3::NixVectorRouting::GetInterfaceByNetDevice
Ptr< IpInterface > GetInterfaceByNetDevice(Ptr< NetDevice > netDevice) const
Iterates through the node list and finds the one corresponding to the given IpAddress.
Definition: nix-vector-routing.cc:522
ns3::Node::GetId
uint32_t GetId(void) const
Definition: node.cc:109
ns3::Socket::SocketErrno
SocketErrno
Enumeration of the possible errors returned by a socket.
Definition: socket.h:82
ns3::Callback
Callback template class.
Definition: callback.h:1279
ns3
Every class exported by the ns3 library is enclosed in the ns3 namespace.
ns3::Packet::SetNixVector
void SetNixVector(Ptr< NixVector > nixVector)
Set the packet nix-vector.
Definition: packet.cc:244
ns3::Callback::IsNull
bool IsNull(void) const
Check for null implementation.
Definition: callback.h:1386
ns3::NixVectorRouting::GetNodeByIp
Ptr< Node > GetNodeByIp(IpAddress dest) const
Iterates through the node list and finds the one corresponding to the given IpAddress.
Definition: nix-vector-routing.cc:493
ns3::Object::GetObject
Ptr< T > GetObject(void) const
Get a pointer to the requested aggregated Object.
Definition: object.h:470
third.channel
channel
Definition: third.py:92
ns3::NodeList::GetNNodes
static uint32_t GetNNodes(void)
Definition: node-list.cc:247
ns3::NixVectorRouting::SetNode
void SetNode(Ptr< Node > node)
Set the Node pointer of the node for which this routing protocol is to be placed.
Definition: nix-vector-routing.cc:130
ns3::NixVectorRouting::GetNixVectorInCache
Ptr< NixVector > GetNixVectorInCache(const IpAddress &address, bool &foundInCache) const
Checks the cache based on dest IP for the nix-vector.
Definition: nix-vector-routing.cc:234
ns3::NixVectorRouting::NotifyAddAddress
virtual void NotifyAddAddress(uint32_t interface, IpInterfaceAddress address)
Definition: nix-vector-routing.cc:1031
ns3::OutputStreamWrapper::GetStream
std::ostream * GetStream(void)
Return a pointer to an ostream previously set in the wrapper.
Definition: output-stream-wrapper.cc:58
ns3::NixVectorRouting::IpL3Protocol
typename std::conditional< IsIpv4::value, Ipv4L3Protocol, Ipv6L3Protocol >::type IpL3Protocol
Alias for Ipv4L3Protocol and Ipv4L3Protocol classes.
Definition: nix-vector-routing.h:94
ns3::NixVectorRouting::NotifyRemoveAddress
virtual void NotifyRemoveAddress(uint32_t interface, IpInterfaceAddress address)
Definition: nix-vector-routing.cc:1037
ns3::Ipv6InterfaceAddress::LINKLOCAL
@ LINKLOCAL
Link-local address (fe80::/64)
Definition: ipv6-interface-address.h:62
ns3::Packet::GetNixVector
Ptr< NixVector > GetNixVector(void) const
Get the packet nix-vector.
Definition: packet.cc:250
ns3::NixVectorRouting::SetIpv4
virtual void SetIpv4(Ptr< Ip > ipv4)
Typically, invoked directly or indirectly from ns3::Ipv4::SetRoutingProtocol.
Definition: nix-vector-routing.cc:82
ns3::Time::As
TimeWithUnit As(const enum Unit unit=Time::AUTO) const
Attach a unit to a Time, to facilitate output in a specific unit.
Definition: time.cc:429
ns3::NixVectorRouting::CheckCacheStateAndFlush
void CheckCacheStateAndFlush(void) const
Flushes routing caches if required.
Definition: nix-vector-routing.cc:1347
ns3::NixVectorRouting::FlushGlobalNixRoutingCache
void FlushGlobalNixRoutingCache(void) const
Called when run-time link topology change occurs which iterates through the node list and flushes any...
Definition: nix-vector-routing.cc:139
ns3::NixVectorRouting::FlushIpRouteCache
void FlushIpRouteCache(void) const
Flushes the cache which stores the Ip route based on the destination IP.
Definition: nix-vector-routing.cc:173
ns3::NixVectorRouting::g_netdeviceToIpInterfaceMap
static NetDeviceToIpInterfaceMap g_netdeviceToIpInterfaceMap
NetDevice pointer to IpInterface pointer map.
Definition: nix-vector-routing.h:476
ns3::TypeId::SetParent
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:923
ns3::NixVectorRouting::NotifyRemoveRoute
virtual void NotifyRemoveRoute(IpAddress dst, Ipv6Prefix mask, IpAddress nextHop, uint32_t interface, IpAddress prefixToUse=IpAddress::GetZero())
Notify route removing.
Definition: nix-vector-routing.cc:1049
ns3::Ptr< Ip >
ns3::NetDevice::IsLinkUp
virtual bool IsLinkUp(void) const =0
ns3::NetDeviceContainer::Begin
Iterator Begin(void) const
Get an iterator which refers to the first NetDevice in the container.
Definition: net-device-container.cc:46
ns3::NixVectorRouting::RouteInput
virtual bool RouteInput(Ptr< const Packet > p, const IpHeader &header, Ptr< const NetDevice > idev, UnicastForwardCallback ucb, MulticastForwardCallback mcb, LocalDeliverCallback lcb, ErrorCallback ecb)
Route an input packet (to be forwarded or locally delivered)
Definition: nix-vector-routing.cc:830
nix-vector-routing.h
ns3::NodeList::Iterator
std::vector< Ptr< Node > >::const_iterator Iterator
Node container iterator.
Definition: node-list.h:44
ns3::NixVectorRouting::NetDeviceIsBridged
Ptr< BridgeNetDevice > NetDeviceIsBridged(Ptr< NetDevice > nd) const
Determine if the NetDevice is bridged.
Definition: nix-vector-routing.cc:583
ns3::Now
Time Now(void)
create an ns3::Time instance which contains the current simulation time.
Definition: simulator.cc:287
bianchi11ax.k
int k
Definition: bianchi11ax.py:129
ns3::NetDevice::GetNode
virtual Ptr< Node > GetNode(void) const =0
ns3::Names::FindName
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,...
Definition: names.cc:817
ns3::NixVectorRouting::IpAddressToNodeMap
std::unordered_map< IpAddress, ns3::Ptr< ns3::Node >, IpAddressHash > IpAddressToNodeMap
Mapping of IP address to ns-3 node.
Definition: nix-vector-routing.h:471
ns3::Node::GetDevice
Ptr< NetDevice > GetDevice(uint32_t index) const
Retrieve the index-th NetDevice associated to this node.
Definition: node.cc:144
ns3::NixVectorRouting::UnicastForwardCallback
std::conditional< IsIpv4::value, UnicastForwardCallbackv4, UnicastForwardCallbackv6 >::type UnicastForwardCallback
Callback for unicast packets to be forwarded.
Definition: nix-vector-routing.h:287
ns3::NixVectorRouting::MulticastForwardCallback
std::conditional< IsIpv4::value, MulticastForwardCallbackv4, MulticastForwardCallbackv6 >::type MulticastForwardCallback
Callback for multicast packets to be forwarded.
Definition: nix-vector-routing.h:296
ns3::NixVector::AddNeighborIndex
void AddNeighborIndex(uint32_t newBits, uint32_t numberOfBits)
Definition: nix-vector.cc:88
ns3::NixVectorRouting::NetDeviceToIpInterfaceMap
std::unordered_map< Ptr< NetDevice >, Ptr< IpInterface > > NetDeviceToIpInterfaceMap
Mapping of Ptr<NetDevice> to Ptr<IpInterface>.
Definition: nix-vector-routing.h:475
ns3::BridgeNetDevice::GetNBridgePorts
uint32_t GetNBridgePorts(void) const
Gets the number of bridged 'ports', i.e., the NetDevices currently bridged.
Definition: bridge-net-device.cc:235
ns3::Socket::ERROR_NOTERROR
@ ERROR_NOTERROR
Definition: socket.h:83
first.address
address
Definition: first.py:44
NS_ABORT_MSG_IF
#define NS_ABORT_MSG_IF(cond, msg)
Abnormal program termination if a condition is true, with a message.
Definition: abort.h:108
NS_ASSERT_MSG
#define NS_ASSERT_MSG(condition, message)
At runtime, in debugging builds, if this condition is not true, the program prints the message to out...
Definition: assert.h:88
ns3::NetDeviceContainer::End
Iterator End(void) const
Get an iterator which indicates past-the-last NetDevice in the container.
Definition: net-device-container.cc:51
ns3::BridgeNetDevice::GetBridgePort
Ptr< NetDevice > GetBridgePort(uint32_t n) const
Gets the n-th bridged port.
Definition: bridge-net-device.cc:243
second
Definition: second.py:1
ns3::NetDevice::GetChannel
virtual Ptr< Channel > GetChannel(void) const =0
ns3::NixVectorRouting
Nix-vector routing protocol.
Definition: nix-vector-routing.h:68
ns3::NixVectorRouting::RouteOutput
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.
Definition: nix-vector-routing.cc:670
ns3::Ipv6Address::GetZero
static Ipv6Address GetZero()
Get the 0 (::) Ipv6Address.
Definition: ipv6-address.cc:890
ns3::NixVectorRouting::IpHeader
typename std::conditional< IsIpv4::value, Ipv4Header, Ipv6Header >::type IpHeader
Alias for Ipv4Header and Ipv6Header classes.
Definition: nix-vector-routing.h:85
NS_LOG_LOGIC
#define NS_LOG_LOGIC(msg)
Use NS_LOG to output a message of level LOG_LOGIC.
Definition: log.h:289
ns3::NixVectorRouting::BuildIpAddressToNodeMap
void BuildIpAddressToNodeMap(void) const
Build map from IP Address to Node for faster lookup.
Definition: nix-vector-routing.cc:447
ns3::NixVectorRouting::BFS
bool BFS(uint32_t numberOfNodes, Ptr< Node > source, Ptr< Node > dest, std::vector< Ptr< Node > > &parentVector, Ptr< NetDevice > oif) const
Breadth first search algorithm.
Definition: nix-vector-routing.cc:1056
ns3::NetDeviceContainer::Iterator
std::vector< Ptr< NetDevice > >::const_iterator Iterator
NetDevice container iterator.
Definition: net-device-container.h:45
NS_LOG_ERROR
#define NS_LOG_ERROR(msg)
Use NS_LOG to output a message of level LOG_ERROR.
Definition: log.h:257
ns3::NixVectorRouting::GetAdjacentNetDevices
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...
Definition: nix-vector-routing.cc:348
ns3::NixVectorRouting::g_isCacheDirty
static bool g_isCacheDirty
Flag to mark when caches are dirty and need to be flushed.
Definition: nix-vector-routing.h:449
NS_ABORT_MSG_UNLESS
#define NS_ABORT_MSG_UNLESS(cond, msg)
Abnormal program termination if a condition is false, with a message.
Definition: abort.h:144
ns3::NixVectorRouting::PrintRoutingPath
void PrintRoutingPath(Ptr< Node > source, IpAddress dest, Ptr< OutputStreamWrapper > stream, Time::Unit unit) const
Print the Routing Path according to Nix Routing.
Definition: nix-vector-routing.cc:1215
NS_LOG_FUNCTION_NOARGS
#define NS_LOG_FUNCTION_NOARGS()
Output the name of the function.
Definition: log-macros-enabled.h:209
ns3::NodeList::End
static Iterator End(void)
Definition: node-list.cc:235
ns3::NixVectorRouting::FindTotalNeighbors
uint32_t FindTotalNeighbors(Ptr< Node > node) const
Simply iterates through the nodes net-devices and determines how many neighbors the node has.
Definition: nix-vector-routing.cc:549
ns3::NixVectorRouting::GetTypeId
static TypeId GetTypeId(void)
The Interface ID of the Global Router interface.
Definition: nix-vector-routing.cc:55
NS_LOG_DEBUG
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition: log.h:273
ns3::NixVectorRouting::IpAddress
typename std::conditional< IsIpv4::value, Ipv4Address, Ipv6Address >::type IpAddress
Alias for Ipv4Address and Ipv6Address classes.
Definition: nix-vector-routing.h:76
ns3::NixVectorRouting::DoInitialize
void DoInitialize()
Definition: nix-vector-routing.cc:104
ns3::NixVectorRouting::BuildNixVector
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.
Definition: nix-vector-routing.cc:274
NS_LOG_FUNCTION
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
Definition: log-macros-enabled.h:244
ns3::NixVectorRouting::IpInterfaceAddress
typename std::conditional< IsIpv4::value, Ipv4InterfaceAddress, Ipv6InterfaceAddress >::type IpInterfaceAddress
Alias for Ipv4InterfaceAddress and Ipv6InterfaceAddress classes.
Definition: nix-vector-routing.h:88
ns3::NixVectorRouting::SetIpv6
virtual void SetIpv6(Ptr< Ip > ipv6)
Typically, invoked directly or indirectly from ns3::Ipv6::SetRoutingProtocol.
Definition: nix-vector-routing.cc:93
ns3::NixVector::Copy
Ptr< NixVector > Copy(void) const
Definition: nix-vector.cc:71
ns3::NixVectorRouting::PrintRoutingTable
virtual void PrintRoutingTable(Ptr< OutputStreamWrapper > stream, Time::Unit unit=Time::S) const
Print the Routing Table entries.
Definition: nix-vector-routing.cc:949
ns3::NixVectorRouting::DoDispose
void DoDispose(void)
Definition: nix-vector-routing.cc:118
ns3::Node::GetNDevices
uint32_t GetNDevices(void) const
Definition: node.cc:152
ns3::NetDeviceContainer::GetN
uint32_t GetN(void) const
Get the number of Ptr<NetDevice> stored in this container.
Definition: net-device-container.cc:57
ns3::NetDevice::IsBridge
virtual bool IsBridge(void) const =0
Return true if the net device is acting as a bridge.
ns3::BridgeNetDevice
a virtual net device that bridges multiple LAN segments
Definition: bridge-net-device.h:72
NS_OBJECT_TEMPLATE_CLASS_DEFINE
#define NS_OBJECT_TEMPLATE_CLASS_DEFINE(type, param)
Explicitly instantiate a template class and register the resulting instance with the TypeId system.
Definition: object-base.h:67
ns3::NixVectorRouting::FlushNixCache
void FlushNixCache(void) const
Flushes the cache which stores nix-vector based on destination IP.
Definition: nix-vector-routing.cc:165
ns3::Ipv6Prefix
Describes an IPv6 prefix.
Definition: ipv6-address.h:456
ns3::NixVectorRouting::GetNixVector
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 ...
Definition: nix-vector-routing.cc:181
ns3::NixVectorRouting::NotifyInterfaceDown
virtual void NotifyInterfaceDown(uint32_t interface)
Definition: nix-vector-routing.cc:1025
ns3::NetDeviceContainer::Get
Ptr< NetDevice > Get(uint32_t i) const
Get the Ptr<NetDevice> stored in this container at a given index.
Definition: net-device-container.cc:62
ns3::Socket::ERROR_NOROUTETOHOST
@ ERROR_NOROUTETOHOST
Definition: socket.h:93
ns3::NixVectorRouting::NotifyInterfaceUp
virtual void NotifyInterfaceUp(uint32_t interface)
Definition: nix-vector-routing.cc:1019
ns3::NetDeviceContainer::Add
void Add(NetDeviceContainer other)
Append the contents of another NetDeviceContainer to the end of this container.
Definition: net-device-container.cc:67
ns3::NixVectorRouting::NixVectorRouting
NixVectorRouting()
Definition: nix-vector-routing.cc:68
ns3::Time::Unit
Unit
The unit to use to interpret a number representing time.
Definition: nstime.h:110
ns3::NixVectorRouting::GetIpRouteInCache
Ptr< IpRoute > GetIpRouteInCache(IpAddress address)
Checks the cache based on dest IP for the IpRoute.
Definition: nix-vector-routing.cc:255
ns3::NixVector::ExtractNeighborIndex
uint32_t ExtractNeighborIndex(uint32_t numberOfBits)
Definition: nix-vector.cc:160
ns3::NixVector::BitCount
uint32_t BitCount(uint32_t numberOfNeighbors) const
Definition: nix-vector.cc:365