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
275 {
277 
278  uint32_t numberOfDevices = m_node->GetNDevices ();
279 
280  // here we are building a nix vector to
281  // ourself, so we need to find the loopback
282  // interface and add that to the nix vector
283 
284  for (uint32_t i = 0; i < numberOfDevices; i++)
285  {
286  uint32_t interfaceIndex = (m_ip)->GetInterfaceForDevice (m_node->GetDevice (i));
287  IpInterfaceAddress ifAddr = m_ip->GetAddress (interfaceIndex, 0);
288  IpAddress ifAddrValue = ifAddr.GetAddress ();
289  if (ifAddrValue.IsLocalhost ())
290  {
291  NS_LOG_LOGIC ("Adding loopback to nix.");
292  NS_LOG_LOGIC ("Adding Nix: " << i << " with " << nixVector->BitCount (numberOfDevices)
293  << " bits, for node " << m_node->GetId ());
294  nixVector->AddNeighborIndex (i, nixVector->BitCount (numberOfDevices));
295  return true;
296  }
297  }
298  return false;
299 }
300 
301 template <typename T>
302 bool
303 NixVectorRouting<T>::BuildNixVector (const std::vector< Ptr<Node> > & parentVector, uint32_t source, uint32_t dest, Ptr<NixVector> nixVector) const
304 {
305  NS_LOG_FUNCTION (this << parentVector << source << dest << nixVector);
306 
307  if (source == dest)
308  {
309  return true;
310  }
311 
312  if (parentVector.at (dest) == 0)
313  {
314  return false;
315  }
316 
317  Ptr<Node> parentNode = parentVector.at (dest);
318 
319  uint32_t numberOfDevices = parentNode->GetNDevices ();
320  uint32_t destId = 0;
321  uint32_t totalNeighbors = 0;
322 
323  // scan through the net devices on the T node
324  // and then look at the nodes adjacent to them
325  for (uint32_t i = 0; i < numberOfDevices; i++)
326  {
327  // Get a net device from the node
328  // as well as the channel, and figure
329  // out the adjacent net devices
330  Ptr<NetDevice> localNetDevice = parentNode->GetDevice (i);
331  if (localNetDevice->IsBridge ())
332  {
333  continue;
334  }
335  Ptr<Channel> channel = localNetDevice->GetChannel ();
336  if (channel == 0)
337  {
338  continue;
339  }
340 
341  // this function takes in the local net dev, and channel, and
342  // writes to the netDeviceContainer the adjacent net devs
343  NetDeviceContainer netDeviceContainer;
344  GetAdjacentNetDevices (localNetDevice, channel, netDeviceContainer);
345 
346  // Finally we can get the adjacent nodes
347  // and scan through them. If we find the
348  // node that matches "dest" then we can add
349  // the index to the nix vector.
350  // the index corresponds to the neighbor index
351  uint32_t offset = 0;
352  for (NetDeviceContainer::Iterator iter = netDeviceContainer.Begin (); iter != netDeviceContainer.End (); iter++)
353  {
354  Ptr<Node> remoteNode = (*iter)->GetNode ();
355 
356  if (remoteNode->GetId () == dest)
357  {
358  destId = totalNeighbors + offset;
359  }
360  offset += 1;
361  }
362 
363  totalNeighbors += netDeviceContainer.GetN ();
364  }
365  NS_LOG_LOGIC ("Adding Nix: " << destId << " with "
366  << nixVector->BitCount (totalNeighbors) << " bits, for node " << parentNode->GetId ());
367  nixVector->AddNeighborIndex (destId, nixVector->BitCount (totalNeighbors));
368 
369  // recurse through T vector, grabbing the path
370  // and building the nix vector
371  BuildNixVector (parentVector, source, (parentVector.at (dest))->GetId (), nixVector);
372  return true;
373 }
374 
375 template <typename T>
376 void
378 {
379  NS_LOG_FUNCTION (this << netDevice << channel);
380 
381  Ptr<IpInterface> netDeviceInterface = GetInterfaceByNetDevice (netDevice);
382  if (netDeviceInterface == 0 || !netDeviceInterface->IsUp ())
383  {
384  NS_LOG_LOGIC ("IpInterface either doesn't exist or is down");
385  return;
386  }
387 
388  uint32_t netDeviceAddresses = netDeviceInterface->GetNAddresses ();
389 
390  for (std::size_t i = 0; i < channel->GetNDevices (); i++)
391  {
392  Ptr<NetDevice> remoteDevice = channel->GetDevice (i);
393  if (remoteDevice != netDevice)
394  {
395  // Compare if the remoteDevice shares a common subnet with remoteDevice
396  Ptr<IpInterface> remoteDeviceInterface = GetInterfaceByNetDevice (remoteDevice);
397  if (remoteDeviceInterface == 0 || !remoteDeviceInterface->IsUp ())
398  {
399  NS_LOG_LOGIC ("IpInterface either doesn't exist or is down");
400  continue;
401  }
402 
403  uint32_t remoteDeviceAddresses = remoteDeviceInterface->GetNAddresses ();
404  bool commonSubnetFound = false;
405 
406  for (uint32_t j = 0; j < netDeviceAddresses; ++j)
407  {
408  IpInterfaceAddress netDeviceIfAddr = netDeviceInterface->GetAddress (j);
409  if constexpr (!IsIpv4::value)
410  {
411  if (netDeviceIfAddr.GetScope () == Ipv6InterfaceAddress::LINKLOCAL)
412  {
413  continue;
414  }
415  }
416  for (uint32_t k = 0; k < remoteDeviceAddresses; ++k)
417  {
418  IpInterfaceAddress remoteDeviceIfAddr = remoteDeviceInterface->GetAddress (k);
419  if constexpr (!IsIpv4::value)
420  {
421  if (remoteDeviceIfAddr.GetScope () == Ipv6InterfaceAddress::LINKLOCAL)
422  {
423  continue;
424  }
425  }
426  if (netDeviceIfAddr.IsInSameSubnet (remoteDeviceIfAddr.GetAddress ()))
427  {
428  commonSubnetFound = true;
429  break;
430  }
431  }
432 
433  if (commonSubnetFound)
434  {
435  break;
436  }
437  }
438 
439  if (!commonSubnetFound)
440  {
441  continue;
442  }
443 
444  Ptr<BridgeNetDevice> bd = NetDeviceIsBridged (remoteDevice);
445  // we have a bridged device, we need to add all
446  // bridged devices
447  if (bd)
448  {
449  NS_LOG_LOGIC ("Looking through bridge ports of bridge net device " << bd);
450  for (uint32_t j = 0; j < bd->GetNBridgePorts (); ++j)
451  {
452  Ptr<NetDevice> ndBridged = bd->GetBridgePort (j);
453  if (ndBridged == remoteDevice)
454  {
455  NS_LOG_LOGIC ("That bridge port is me, don't walk backward");
456  continue;
457  }
458  Ptr<Channel> chBridged = ndBridged->GetChannel ();
459  if (chBridged == 0)
460  {
461  continue;
462  }
463  GetAdjacentNetDevices (ndBridged, chBridged, netDeviceContainer);
464  }
465  }
466  else
467  {
468  netDeviceContainer.Add (channel->GetDevice (i));
469  }
470  }
471  }
472 }
473 
474 template <typename T>
475 void
477 {
479 
480  for (NodeList::Iterator it = NodeList::Begin (); it != NodeList::End (); ++it)
481  {
482  Ptr<Node> node = *it;
484 
485  if(ip)
486  {
487  uint32_t numberOfDevices = node->GetNDevices ();
488 
489  for (uint32_t deviceId = 0; deviceId < numberOfDevices; deviceId++)
490  {
491  Ptr<NetDevice> device = node->GetDevice (deviceId);
492 
493  // If this is not a loopback device add the IP address to the map
494  if ( !DynamicCast<LoopbackNetDevice>(device) )
495  {
496  int32_t interfaceIndex = (ip)->GetInterfaceForDevice (node->GetDevice (deviceId));
497  if (interfaceIndex != -1)
498  {
499  g_netdeviceToIpInterfaceMap[device] = (ip)->GetInterface (interfaceIndex);
500 
501  uint32_t numberOfAddresses = ip->GetNAddresses (interfaceIndex);
502  for (uint32_t addressIndex = 0; addressIndex < numberOfAddresses; addressIndex++)
503  {
504  IpInterfaceAddress ifAddr = ip->GetAddress (interfaceIndex, addressIndex);
505  IpAddress addr = ifAddr.GetAddress ();
506 
507  NS_ABORT_MSG_IF (g_ipAddressToNodeMap.count (addr),
508  "Duplicate IP address (" << addr << ") found during NIX Vector map construction for node " << node->GetId ());
509 
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;
512  }
513  }
514  }
515  }
516  }
517  }
518 }
519 
520 template <typename T>
521 Ptr<Node>
523 {
524  NS_LOG_FUNCTION (this << dest);
525 
526  // Populate lookup table if is empty.
527  if ( g_ipAddressToNodeMap.empty () )
528  {
529  BuildIpAddressToNodeMap ();
530  }
531 
532  Ptr<Node> destNode;
533 
534  typename IpAddressToNodeMap::iterator iter = g_ipAddressToNodeMap.find(dest);
535 
536  if(iter == g_ipAddressToNodeMap.end ())
537  {
538  NS_LOG_ERROR ("Couldn't find dest node given the IP" << dest);
539  destNode = 0;
540  }
541  else
542  {
543  destNode = iter -> second;
544  }
545 
546  return destNode;
547 }
548 
549 template <typename T>
552 {
553  // Populate lookup table if is empty.
554  if ( g_netdeviceToIpInterfaceMap.empty () )
555  {
556  BuildIpAddressToNodeMap ();
557  }
558 
559  Ptr<IpInterface> ipInterface;
560 
561  typename NetDeviceToIpInterfaceMap::iterator iter = g_netdeviceToIpInterfaceMap.find(netDevice);
562 
563  if(iter == g_netdeviceToIpInterfaceMap.end ())
564  {
565  NS_LOG_ERROR ("Couldn't find IpInterface node given the NetDevice" << netDevice);
566  ipInterface = 0;
567  }
568  else
569  {
570  ipInterface = iter -> second;
571  }
572 
573  return ipInterface;
574 }
575 
576 template <typename T>
577 uint32_t
579 {
580  NS_LOG_FUNCTION (this << node);
581 
582  uint32_t numberOfDevices = node->GetNDevices ();
583  uint32_t totalNeighbors = 0;
584 
585  // scan through the net devices on the T node
586  // and then look at the nodes adjacent to them
587  for (uint32_t i = 0; i < numberOfDevices; i++)
588  {
589  // Get a net device from the node
590  // as well as the channel, and figure
591  // out the adjacent net devices
592  Ptr<NetDevice> localNetDevice = node->GetDevice (i);
593  Ptr<Channel> channel = localNetDevice->GetChannel ();
594  if (channel == 0)
595  {
596  continue;
597  }
598 
599  // this function takes in the local net dev, and channel, and
600  // writes to the netDeviceContainer the adjacent net devs
601  NetDeviceContainer netDeviceContainer;
602  GetAdjacentNetDevices (localNetDevice, channel, netDeviceContainer);
603 
604  totalNeighbors += netDeviceContainer.GetN ();
605  }
606 
607  return totalNeighbors;
608 }
609 
610 template <typename T>
613 {
614  NS_LOG_FUNCTION (this << nd);
615 
616  Ptr<Node> node = nd->GetNode ();
617  uint32_t nDevices = node->GetNDevices ();
618 
619  //
620  // There is no bit on a net device that says it is being bridged, so we have
621  // to look for bridges on the node to which the device is attached. If we
622  // find a bridge, we need to look through its bridge ports (the devices it
623  // bridges) to see if we find the device in question.
624  //
625  for (uint32_t i = 0; i < nDevices; ++i)
626  {
627  Ptr<NetDevice> ndTest = node->GetDevice (i);
628  NS_LOG_LOGIC ("Examine device " << i << " " << ndTest);
629 
630  if (ndTest->IsBridge ())
631  {
632  NS_LOG_LOGIC ("device " << i << " is a bridge net device");
634  NS_ABORT_MSG_UNLESS (bnd, "NixVectorRouting::NetDeviceIsBridged (): GetObject for <BridgeNetDevice> failed");
635 
636  for (uint32_t j = 0; j < bnd->GetNBridgePorts (); ++j)
637  {
638  NS_LOG_LOGIC ("Examine bridge port " << j << " " << bnd->GetBridgePort (j));
639  if (bnd->GetBridgePort (j) == nd)
640  {
641  NS_LOG_LOGIC ("Net device " << nd << " is bridged by " << bnd);
642  return bnd;
643  }
644  }
645  }
646  }
647  NS_LOG_LOGIC ("Net device " << nd << " is not bridged");
648  return 0;
649 }
650 
651 template <typename T>
652 uint32_t
653 NixVectorRouting<T>::FindNetDeviceForNixIndex (Ptr<Node> node, uint32_t nodeIndex, IpAddress & gatewayIp) const
654 {
655  NS_LOG_FUNCTION (this << node << nodeIndex << gatewayIp);
656 
657  uint32_t numberOfDevices = node->GetNDevices ();
658  uint32_t index = 0;
659  uint32_t totalNeighbors = 0;
660 
661  // scan through the net devices on the parent node
662  // and then look at the nodes adjacent to them
663  for (uint32_t i = 0; i < numberOfDevices; i++)
664  {
665  // Get a net device from the node
666  // as well as the channel, and figure
667  // out the adjacent net devices
668  Ptr<NetDevice> localNetDevice = node->GetDevice (i);
669  Ptr<Channel> channel = localNetDevice->GetChannel ();
670  if (channel == 0)
671  {
672  continue;
673  }
674 
675  // this function takes in the local net dev, and channel, and
676  // writes to the netDeviceContainer the adjacent net devs
677  NetDeviceContainer netDeviceContainer;
678  GetAdjacentNetDevices (localNetDevice, channel, netDeviceContainer);
679 
680  // check how many neighbors we have
681  if (nodeIndex < (totalNeighbors + netDeviceContainer.GetN ()))
682  {
683  // found the proper net device
684  index = i;
685  Ptr<NetDevice> gatewayDevice = netDeviceContainer.Get (nodeIndex-totalNeighbors);
686  Ptr<IpInterface> gatewayInterface = GetInterfaceByNetDevice (gatewayDevice);
687  IpInterfaceAddress ifAddr = gatewayInterface->GetAddress (0);
688  gatewayIp = ifAddr.GetAddress ();
689  break;
690  }
691  totalNeighbors += netDeviceContainer.GetN ();
692  }
693 
694  return index;
695 }
696 
697 template <typename T>
700 {
701  NS_LOG_FUNCTION (this << header << oif);
702 
703  Ptr<IpRoute> rtentry;
704  Ptr<NixVector> nixVectorInCache;
705  Ptr<NixVector> nixVectorForPacket;
706 
707  CheckCacheStateAndFlush ();
708 
709  IpAddress destAddress = header.GetDestination ();
710 
711  NS_LOG_DEBUG ("Dest IP from header: " << destAddress);
712 
713  if constexpr (!IsIpv4::value)
714  {
715  /* when sending on link-local multicast, there have to be interface specified */
716  if (destAddress.IsLinkLocalMulticast ())
717  {
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);
722  rtentry->SetGateway (Ipv6Address::GetZero ());
723  rtentry->SetOutputDevice (oif);
724  return rtentry;
725  }
726  }
727  // Check the Nix cache
728  bool foundInCache = false;
729  nixVectorInCache = GetNixVectorInCache (destAddress, foundInCache);
730 
731  // not in cache
732  if (!foundInCache)
733  {
734  NS_LOG_LOGIC ("Nix-vector not in cache, build: ");
735  // Build the nix-vector, given this node and the
736  // dest IP address
737  nixVectorInCache = GetNixVector (m_node, destAddress, oif);
738 
739  // cache it
740  m_nixCache.insert (typename NixMap_t::value_type (destAddress, nixVectorInCache));
741  }
742 
743  // path exists
744  if (nixVectorInCache)
745  {
746  NS_LOG_LOGIC ("Nix-vector contents: " << *nixVectorInCache);
747 
748  // create a new nix vector to be used,
749  // we want to keep the cached version clean
750  nixVectorForPacket = nixVectorInCache->Copy ();
751 
752  // Get the interface number that we go out of, by extracting
753  // from the nix-vector
754  if (m_totalNeighbors == 0)
755  {
756  m_totalNeighbors = FindTotalNeighbors (m_node);
757  }
758 
759  // Get the interface number that we go out of, by extracting
760  // from the nix-vector
761  uint32_t numberOfBits = nixVectorForPacket->BitCount (m_totalNeighbors);
762  uint32_t nodeIndex = nixVectorForPacket->ExtractNeighborIndex (numberOfBits);
763 
764  // Search here in a cache for this node index
765  // and look for a IpRoute
766  rtentry = GetIpRouteInCache (destAddress);
767 
768  if (!rtentry || !(rtentry->GetOutputDevice () == oif))
769  {
770  // not in cache or a different specified output
771  // device is to be used
772 
773  // first, make sure we erase existing (incorrect)
774  // rtentry from the map
775  if (rtentry)
776  {
777  m_ipRouteCache.erase (destAddress);
778  }
779 
780  NS_LOG_LOGIC ("IpRoute not in cache, build: ");
781  IpAddress gatewayIp;
782  uint32_t index = FindNetDeviceForNixIndex (m_node, nodeIndex, gatewayIp);
783  int32_t interfaceIndex = 0;
784 
785  if (!oif)
786  {
787  interfaceIndex = (m_ip)->GetInterfaceForDevice (m_node->GetDevice (index));
788  }
789  else
790  {
791  interfaceIndex = (m_ip)->GetInterfaceForDevice (oif);
792  }
793 
794  NS_ASSERT_MSG (interfaceIndex != -1, "Interface index not found for device");
795 
796  IpAddress sourceIPAddr = m_ip->SourceAddressSelection (interfaceIndex, destAddress);
797 
798  // start filling in the IpRoute info
799  rtentry = Create<IpRoute> ();
800  rtentry->SetSource (sourceIPAddr);
801 
802  rtentry->SetGateway (gatewayIp);
803  rtentry->SetDestination (destAddress);
804 
805  if (!oif)
806  {
807  rtentry->SetOutputDevice (m_ip->GetNetDevice (interfaceIndex));
808  }
809  else
810  {
811  rtentry->SetOutputDevice (oif);
812  }
813 
814  sockerr = Socket::ERROR_NOTERROR;
815 
816  // add rtentry to cache
817  m_ipRouteCache.insert (typename IpRouteMap_t::value_type (destAddress, rtentry));
818  }
819 
820  NS_LOG_LOGIC ("Nix-vector contents: " << *nixVectorInCache << " : Remaining bits: " << nixVectorForPacket->GetRemainingBits ());
821 
822  // Add nix-vector in the packet class
823  // make sure the packet exists first
824  if (p)
825  {
826  NS_LOG_LOGIC ("Adding Nix-vector to packet: " << *nixVectorForPacket);
827  p->SetNixVector (nixVectorForPacket);
828  }
829  }
830  else // path doesn't exist
831  {
832  NS_LOG_ERROR ("No path to the dest: " << destAddress);
833  sockerr = Socket::ERROR_NOROUTETOHOST;
834  }
835 
836  return rtentry;
837 }
838 
839 template <typename T>
840 bool
844 {
845  NS_LOG_FUNCTION (this << p << header << header.GetSource () << header.GetDestination () << idev);
846 
847  CheckCacheStateAndFlush ();
848 
849  NS_ASSERT (m_ip != 0);
850  // Check if input device supports IP
851  NS_ASSERT (m_ip->GetInterfaceForDevice (idev) >= 0);
852  uint32_t iif = m_ip->GetInterfaceForDevice (idev);
853  // Check if input device supports IP
854  NS_ASSERT (iif >= 0);
855 
856  IpAddress destAddress = header.GetDestination ();
857 
858  if constexpr (IsIpv4::value)
859  {
860  // Local delivery
861  if (m_ip->IsDestinationAddress (destAddress, iif))
862  {
863  if (!lcb.IsNull ())
864  {
865  NS_LOG_LOGIC ("Local delivery to " << destAddress);
866  lcb (p, header, iif);
867  return true;
868  }
869  else
870  {
871  // The local delivery callback is null. This may be a multicast
872  // or broadcast packet, so return false so that another
873  // multicast routing protocol can handle it. It should be possible
874  // to extend this to explicitly check whether it is a unicast
875  // packet, and invoke the error callback if so
876  return false;
877  }
878  }
879  }
880  else
881  {
882  if (destAddress.IsMulticast ())
883  {
884  NS_LOG_LOGIC ("Multicast route not supported by Nix-Vector routing " << destAddress);
885  return false; // Let other routing protocols try to handle this
886  }
887 
888  // Check if input device supports IP forwarding
889  if (m_ip->IsForwarding (iif) == false)
890  {
891  NS_LOG_LOGIC ("Forwarding disabled for this interface");
892  if (!ecb.IsNull ())
893  {
894  ecb (p, header, Socket::ERROR_NOROUTETOHOST);
895  }
896  return true;
897  }
898  }
899 
900  Ptr<IpRoute> rtentry;
901 
902  // Get the nix-vector from the packet
903  Ptr<NixVector> nixVector = p->GetNixVector ();
904 
905  // If nixVector isn't in packet, something went wrong
906  NS_ASSERT (nixVector);
907 
908  // Get the interface number that we go out of, by extracting
909  // from the nix-vector
910  if (m_totalNeighbors == 0)
911  {
912  m_totalNeighbors = FindTotalNeighbors (m_node);
913  }
914  uint32_t numberOfBits = nixVector->BitCount (m_totalNeighbors);
915  uint32_t nodeIndex = nixVector->ExtractNeighborIndex (numberOfBits);
916 
917  rtentry = GetIpRouteInCache (destAddress);
918  // not in cache
919  if (!rtentry)
920  {
921  NS_LOG_LOGIC ("IpRoute not in cache, build: ");
922  IpAddress gatewayIp;
923  uint32_t index = FindNetDeviceForNixIndex (m_node, nodeIndex, gatewayIp);
924  uint32_t interfaceIndex = (m_ip)->GetInterfaceForDevice (m_node->GetDevice (index));
925  IpInterfaceAddress ifAddr = m_ip->GetAddress (interfaceIndex, 0);
926 
927  // start filling in the IpRoute info
928  rtentry = Create<IpRoute> ();
929  rtentry->SetSource (ifAddr.GetAddress ());
930 
931  rtentry->SetGateway (gatewayIp);
932  rtentry->SetDestination (destAddress);
933  rtentry->SetOutputDevice (m_ip->GetNetDevice (interfaceIndex));
934 
935  // add rtentry to cache
936  m_ipRouteCache.insert (typename IpRouteMap_t::value_type (destAddress, rtentry));
937  }
938 
939  NS_LOG_LOGIC ("At Node " << m_node->GetId () << ", Extracting " << numberOfBits <<
940  " bits from Nix-vector: " << nixVector << " : " << *nixVector);
941 
942  // call the unicast callback
943  // local deliver is handled by Ipv4StaticRoutingImpl
944  // so this code is never even called if the packet is
945  // destined for this node.
946  if constexpr (IsIpv4::value)
947  {
948  ucb (rtentry, p, header);
949  }
950  else
951  {
952  ucb (idev, rtentry, p, header);
953  }
954 
955  return true;
956 }
957 
958 template <typename T>
959 void
961 {
963 
964  CheckCacheStateAndFlush ();
965 
966  std::ostream* os = stream->GetStream ();
967  // Copy the current ostream state
968  std::ios oldState (nullptr);
969  oldState.copyfmt (*os);
970 
971  *os << std::resetiosflags (std::ios::adjustfield) << std::setiosflags (std::ios::left);
972 
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;
977 
978  *os << "NixCache:" << std::endl;
979  if (m_nixCache.size () > 0)
980  {
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++)
984  {
985  std::ostringstream dest;
986  dest << it->first;
987  *os << std::setw (30) << dest.str ();
988  if (it->second)
989  {
990  *os << *(it->second) << std::endl;
991  }
992  }
993  }
994  *os << "IpRouteCache:" << std::endl;
995  if (m_ipRouteCache.size () > 0)
996  {
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++)
1002  {
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 ();
1010  *os << " ";
1011  if (Names::FindName (it->second->GetOutputDevice ()) != "")
1012  {
1013  *os << Names::FindName (it->second->GetOutputDevice ());
1014  }
1015  else
1016  {
1017  *os << it->second->GetOutputDevice ()->GetIfIndex ();
1018  }
1019  *os << std::endl;
1020  }
1021  }
1022  *os << std::endl;
1023  // Restore the previous ostream state
1024  (*os).copyfmt (oldState);
1025 }
1026 
1027 // virtual functions from Ipv4RoutingProtocol
1028 template <typename T>
1029 void
1031 {
1032  g_isCacheDirty = true;
1033 }
1034 template <typename T>
1035 void
1037 {
1038  g_isCacheDirty = true;
1039 }
1040 template <typename T>
1041 void
1043 {
1044  g_isCacheDirty = true;
1045 }
1046 template <typename T>
1047 void
1049 {
1050  g_isCacheDirty = true;
1051 }
1052 template <typename T>
1053 void
1054 NixVectorRouting<T>::NotifyAddRoute (IpAddress dst, Ipv6Prefix mask, IpAddress nextHop, uint32_t interface, IpAddress prefixToUse)
1055 {
1056  g_isCacheDirty = true;
1057 }
1058 template <typename T>
1059 void
1060 NixVectorRouting<T>::NotifyRemoveRoute (IpAddress dst, Ipv6Prefix mask, IpAddress nextHop, uint32_t interface, IpAddress prefixToUse)
1061 {
1062  g_isCacheDirty = true;
1063 }
1064 
1065 template <typename T>
1066 bool
1067 NixVectorRouting<T>::BFS (uint32_t numberOfNodes, Ptr<Node> source,
1068  Ptr<Node> dest, std::vector< Ptr<Node> > & parentVector,
1069  Ptr<NetDevice> oif) const
1070 {
1071  NS_LOG_FUNCTION (this << numberOfNodes << source << dest << parentVector << oif);
1072 
1073  NS_LOG_LOGIC ("Going from Node " << source->GetId () << " to Node " << dest->GetId ());
1074  std::queue< Ptr<Node> > greyNodeList; // discovered nodes with unexplored children
1075 
1076  // reset the parent vector
1077  parentVector.assign (numberOfNodes, 0); // initialize to 0
1078 
1079  // Add the source node to the queue, set its parent to itself
1080  greyNodeList.push (source);
1081  parentVector.at (source->GetId ()) = source;
1082 
1083  // BFS loop
1084  while (greyNodeList.size () != 0)
1085  {
1086  Ptr<Node> currNode = greyNodeList.front ();
1087  Ptr<IpL3Protocol> ip = currNode->GetObject<IpL3Protocol> ();
1088 
1089  if (currNode == dest)
1090  {
1091  NS_LOG_LOGIC ("Made it to Node " << currNode->GetId ());
1092  return true;
1093  }
1094 
1095  // if this is the first iteration of the loop and a
1096  // specific output interface was given, make sure
1097  // we go this way
1098  if (currNode == source && oif)
1099  {
1100  // make sure that we can go this way
1101  if (ip)
1102  {
1103  uint32_t interfaceIndex = (ip)->GetInterfaceForDevice (oif);
1104  if (!(ip->IsUp (interfaceIndex)))
1105  {
1106  NS_LOG_LOGIC ("IpInterface is down");
1107  return false;
1108  }
1109  }
1110  if (!(oif->IsLinkUp ()))
1111  {
1112  NS_LOG_LOGIC ("Link is down.");
1113  return false;
1114  }
1115  Ptr<Channel> channel = oif->GetChannel ();
1116  if (channel == 0)
1117  {
1118  return false;
1119  }
1120 
1121  // this function takes in the local net dev, and channel, and
1122  // writes to the netDeviceContainer the adjacent net devs
1123  NetDeviceContainer netDeviceContainer;
1124  GetAdjacentNetDevices (oif, channel, netDeviceContainer);
1125 
1126  // Finally we can get the adjacent nodes
1127  // and scan through them. We push them
1128  // to the greyNode queue, if they aren't
1129  // already there.
1130  for (NetDeviceContainer::Iterator iter = netDeviceContainer.Begin (); iter != netDeviceContainer.End (); iter++)
1131  {
1132  Ptr<Node> remoteNode = (*iter)->GetNode ();
1133  Ptr<IpInterface> remoteIpInterface = GetInterfaceByNetDevice(*iter);
1134  if (remoteIpInterface == 0 || !(remoteIpInterface->IsUp ()))
1135  {
1136  NS_LOG_LOGIC ("IpInterface either doesn't exist or is down");
1137  continue;
1138  }
1139 
1140  // check to see if this node has been pushed before
1141  // by checking to see if it has a parent
1142  // if it doesn't (null or 0), then set its parent and
1143  // push to the queue
1144  if (parentVector.at (remoteNode->GetId ()) == 0)
1145  {
1146  parentVector.at (remoteNode->GetId ()) = currNode;
1147  greyNodeList.push (remoteNode);
1148  }
1149  }
1150  }
1151  else
1152  {
1153  // Iterate over the current node's adjacent vertices
1154  // and push them into the queue
1155  for (uint32_t i = 0; i < (currNode->GetNDevices ()); i++)
1156  {
1157  // Get a net device from the node
1158  // as well as the channel, and figure
1159  // out the adjacent net device
1160  Ptr<NetDevice> localNetDevice = currNode->GetDevice (i);
1161 
1162  // make sure that we can go this way
1163  if (ip)
1164  {
1165  uint32_t interfaceIndex = (ip)->GetInterfaceForDevice (currNode->GetDevice (i));
1166  if (!(ip->IsUp (interfaceIndex)))
1167  {
1168  NS_LOG_LOGIC ("IpInterface is down");
1169  continue;
1170  }
1171  }
1172  if (!(localNetDevice->IsLinkUp ()))
1173  {
1174  NS_LOG_LOGIC ("Link is down.");
1175  continue;
1176  }
1177  Ptr<Channel> channel = localNetDevice->GetChannel ();
1178  if (channel == 0)
1179  {
1180  continue;
1181  }
1182 
1183  // this function takes in the local net dev, and channel, and
1184  // writes to the netDeviceContainer the adjacent net devs
1185  NetDeviceContainer netDeviceContainer;
1186  GetAdjacentNetDevices (localNetDevice, channel, netDeviceContainer);
1187 
1188  // Finally we can get the adjacent nodes
1189  // and scan through them. We push them
1190  // to the greyNode queue, if they aren't
1191  // already there.
1192  for (NetDeviceContainer::Iterator iter = netDeviceContainer.Begin (); iter != netDeviceContainer.End (); iter++)
1193  {
1194  Ptr<Node> remoteNode = (*iter)->GetNode ();
1195  Ptr<IpInterface> remoteIpInterface = GetInterfaceByNetDevice(*iter);
1196  if (remoteIpInterface == 0 || !(remoteIpInterface->IsUp ()))
1197  {
1198  NS_LOG_LOGIC ("IpInterface either doesn't exist or is down");
1199  continue;
1200  }
1201 
1202  // check to see if this node has been pushed before
1203  // by checking to see if it has a parent
1204  // if it doesn't (null or 0), then set its parent and
1205  // push to the queue
1206  if (parentVector.at (remoteNode->GetId ()) == 0)
1207  {
1208  parentVector.at (remoteNode->GetId ()) = currNode;
1209  greyNodeList.push (remoteNode);
1210  }
1211  }
1212  }
1213  }
1214 
1215  // Pop off the head grey node. We have all its children.
1216  // It is now black.
1217  greyNodeList.pop ();
1218  }
1219 
1220  // Didn't find the dest...
1221  return false;
1222 }
1223 
1224 template <typename T>
1225 void
1227  Ptr<OutputStreamWrapper> stream, Time::Unit unit) const
1228 {
1229  NS_LOG_FUNCTION (this << source << dest);
1230 
1231  Ptr<NixVector> nixVectorInCache;
1232  Ptr<NixVector> nixVector;
1233  Ptr<IpRoute> rtentry;
1234 
1235  CheckCacheStateAndFlush ();
1236 
1237  Ptr<Node> destNode = GetNodeByIp (dest);
1238  if (destNode == 0)
1239  {
1240  NS_LOG_ERROR ("No routing path exists");
1241  return;
1242  }
1243 
1244  std::ostream* os = stream->GetStream ();
1245  // Copy the current ostream state
1246  std::ios oldState (nullptr);
1247  oldState.copyfmt (*os);
1248 
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: ";
1255 
1256  // Check the Nix cache
1257  bool foundInCache = true;
1258  nixVectorInCache = GetNixVectorInCache (dest, foundInCache);
1259 
1260  // not in cache
1261  if (!foundInCache)
1262  {
1263  NS_LOG_LOGIC ("Nix-vector not in cache, build: ");
1264  // Build the nix-vector, given the source node and the
1265  // dest IP address
1266  nixVectorInCache = GetNixVector (source, dest, nullptr);
1267  // cache it
1268  m_nixCache.insert (typename NixMap_t::value_type (dest, nixVectorInCache));
1269  }
1270 
1271  if (nixVectorInCache || (!nixVectorInCache && source == destNode))
1272  {
1273  Ptr<Node> curr = source;
1274  uint32_t totalNeighbors = 0;
1275 
1276  if (nixVectorInCache)
1277  {
1278  // Make a NixVector copy to work with. This is because
1279  // we don't want to extract the bits from nixVectorInCache
1280  // which is stored in the m_nixCache.
1281  nixVector = nixVectorInCache->Copy ();
1282 
1283  *os << *nixVector;
1284  }
1285  *os << ")" << std::endl;
1286 
1287  if (source == destNode)
1288  {
1289  std::ostringstream addr, node;
1290  addr << dest;
1291  node << "(Node " << destNode->GetId () << ")";
1292  *os << std::setw (25) << addr.str ();
1293  *os << std::setw (10) << node.str ();
1294  *os << "----> ";
1295  *os << std::setw (25) << addr.str ();
1296  *os << node.str () << std::endl;
1297  }
1298 
1299  while (curr != destNode)
1300  {
1301  totalNeighbors = FindTotalNeighbors (curr);
1302  // Get the number of bits required
1303  // to represent all the neighbors
1304  uint32_t numberOfBits = nixVector->BitCount (totalNeighbors);
1305  // Get the nixIndex
1306  uint32_t nixIndex = nixVector->ExtractNeighborIndex (numberOfBits);
1307  // gatewayIP is the IP of next
1308  // node on channel found from nixIndex
1309  IpAddress gatewayIp;
1310  // Get the Net Device index from the nixIndex
1311  uint32_t netDeviceIndex = FindNetDeviceForNixIndex (curr, nixIndex, gatewayIp);
1312  // Get the interfaceIndex with the help of netDeviceIndex.
1313  // It will be used to get the IP address on interfaceIndex
1314  // interface of 'curr' node.
1315  Ptr<IpL3Protocol> ip = curr->GetObject<IpL3Protocol> ();
1316  Ptr<NetDevice> outDevice = curr->GetDevice (netDeviceIndex);
1317  uint32_t interfaceIndex = ip->GetInterfaceForDevice (outDevice);
1318  IpAddress sourceIPAddr;
1319  if (curr == source)
1320  {
1321  sourceIPAddr = ip->SourceAddressSelection (interfaceIndex, dest);
1322  }
1323  else
1324  {
1325  // We use the first address because it's indifferent which one
1326  // we use to identify intermediate routers
1327  sourceIPAddr = ip->GetAddress (interfaceIndex, 0).GetAddress ();
1328  }
1329 
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 ();
1335  // Replace curr with the next node
1336  curr = GetNodeByIp (gatewayIp);
1337  nextAddr << ((curr == destNode) ? dest : gatewayIp);
1338  nextNode << "(Node " << curr->GetId () << ")";
1339  *os << "----> ";
1340  *os << std::setw (25) << nextAddr.str ();
1341  *os << nextNode.str () << std::endl;
1342  }
1343  *os << std::endl;
1344  }
1345  else
1346  {
1347  *os << ")" << std::endl;
1348  // No Route exists
1349  *os << "There does not exist a path from Node " << source->GetId ()
1350  << " to Node " << destNode->GetId () << "." << std::endl;
1351  }
1352  // Restore the previous ostream state
1353  (*os).copyfmt (oldState);
1354 }
1355 
1356 template <typename T>
1357 void
1359 {
1360  if (g_isCacheDirty)
1361  {
1362  FlushGlobalNixRoutingCache ();
1363  g_isCacheDirty = false;
1364  }
1365 }
1366 
1367 /* Public template function declarations */
1372 template void NixVectorRouting<Ipv4RoutingProtocol>::PrintRoutingPath (Ptr<Node> source, IpAddress dest,
1373  Ptr<OutputStreamWrapper> stream, Time::Unit unit) const;
1374 template void NixVectorRouting<Ipv6RoutingProtocol>::PrintRoutingPath (Ptr<Node> source, IpAddress dest,
1375  Ptr<OutputStreamWrapper> stream, Time::Unit unit) const;
1376 
1377 } // 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:653
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:1054
ns3::NixVectorRouting::g_ipAddressToNodeMap
static IpAddressToNodeMap g_ipAddressToNodeMap
Address to node map.
Definition: nix-vector-routing.h:479
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:551
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:522
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:1042
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:1048
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:1358
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:483
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:1060
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:841
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:612
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:478
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:294
ns3::NixVectorRouting::MulticastForwardCallback
std::conditional< IsIpv4::value, MulticastForwardCallbackv4, MulticastForwardCallbackv6 >::type MulticastForwardCallback
Callback for multicast packets to be forwarded.
Definition: nix-vector-routing.h:303
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:482
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:699
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:476
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:1067
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:377
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:456
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:1226
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:578
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:303
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:960
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:1036
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:1030
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::NixVectorRouting::BuildNixVectorLocal
bool BuildNixVectorLocal(Ptr< NixVector > nixVector)
Special variation of BuildNixVector for when a node is sending to itself.
Definition: nix-vector-routing.cc:274
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