A Discrete-Event Network Simulator
API
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
ipv4-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  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License version 2 as
7  * published by the Free Software Foundation;
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17  *
18  * Authors: Josh Pelkey <jpelkey@gatech.edu>
19  */
20 
21 #include <queue>
22 #include <iomanip>
23 
24 #include "ns3/log.h"
25 #include "ns3/abort.h"
26 #include "ns3/names.h"
27 #include "ns3/ipv4-list-routing.h"
28 
30 
31 NS_LOG_COMPONENT_DEFINE ("Ipv4NixVectorRouting");
32 
33 namespace ns3 {
34 
35 NS_OBJECT_ENSURE_REGISTERED (Ipv4NixVectorRouting)
36  ;
37 
38 TypeId
40 {
41  static TypeId tid = TypeId ("ns3::Ipv4NixVectorRouting")
43  .AddConstructor<Ipv4NixVectorRouting> ()
44  ;
45  return tid;
46 }
47 
49  : m_totalNeighbors (0)
50 {
52 }
53 
55 {
57 }
58 
59 void
61 {
62  NS_ASSERT (ipv4 != 0);
63  NS_ASSERT (m_ipv4 == 0);
64  NS_LOG_DEBUG ("Created Ipv4NixVectorProtocol");
65 
66  m_ipv4 = ipv4;
67 }
68 
69 void
71 {
73 
74  m_node = 0;
75  m_ipv4 = 0;
76 
78 }
79 
80 
81 void
83 {
85 
86  m_node = node;
87 }
88 
89 void
91 {
93  NodeList::Iterator listEnd = NodeList::End ();
94  for (NodeList::Iterator i = NodeList::Begin (); i != listEnd; i++)
95  {
96  Ptr<Node> node = *i;
98  if (!rp)
99  {
100  continue;
101  }
102  NS_LOG_LOGIC ("Flushing Nix caches.");
103  rp->FlushNixCache ();
104  rp->FlushIpv4RouteCache ();
105  }
106 }
107 
108 void
110 {
112  m_nixCache.clear ();
113 }
114 
115 void
117 {
119  m_ipv4RouteCache.clear ();
120 }
121 
124 {
126 
127  Ptr<NixVector> nixVector = Create<NixVector> ();
128 
129  // not in cache, must build the nix vector
130  // First, we have to figure out the nodes
131  // associated with these IPs
132  Ptr<Node> destNode = GetNodeByIp (dest);
133  if (destNode == 0)
134  {
135  NS_LOG_ERROR ("No routing path exists");
136  return 0;
137  }
138 
139  // if source == dest, then we have a special case
142  if (source == destNode)
143  {
144  NS_LOG_DEBUG ("Do not processs packets to self");
145  return 0;
146  }
147  else
148  {
149  // otherwise proceed as normal
150  // and build the nix vector
151  std::vector< Ptr<Node> > parentVector;
152 
153  BFS (NodeList::GetNNodes (), source, destNode, parentVector, oif);
154 
155  if (BuildNixVector (parentVector, source->GetId (), destNode->GetId (), nixVector))
156  {
157  return nixVector;
158  }
159  else
160  {
161  NS_LOG_ERROR ("No routing path exists");
162  return 0;
163  }
164  }
165 }
166 
169 {
171 
172  NixMap_t::iterator iter = m_nixCache.find (address);
173  if (iter != m_nixCache.end ())
174  {
175  NS_LOG_LOGIC ("Found Nix-vector in cache.");
176  return iter->second;
177  }
178 
179  // not in cache
180  return 0;
181 }
182 
185 {
187 
188  Ipv4RouteMap_t::iterator iter = m_ipv4RouteCache.find (address);
189  if (iter != m_ipv4RouteCache.end ())
190  {
191  NS_LOG_LOGIC ("Found Ipv4Route in cache.");
192  return iter->second;
193  }
194 
195  // not in cache
196  return 0;
197 }
198 
199 bool
201 {
203 
204  uint32_t numberOfDevices = m_node->GetNDevices ();
205 
206  // here we are building a nix vector to
207  // ourself, so we need to find the loopback
208  // interface and add that to the nix vector
209  Ipv4Address loopback ("127.0.0.1");
210  for (uint32_t i = 0; i < numberOfDevices; i++)
211  {
212  uint32_t interfaceIndex = (m_ipv4)->GetInterfaceForDevice (m_node->GetDevice (i));
213  Ipv4InterfaceAddress ifAddr = m_ipv4->GetAddress (interfaceIndex, 0);
214  if (ifAddr.GetLocal () == loopback)
215  {
216  NS_LOG_LOGIC ("Adding loopback to nix.");
217  NS_LOG_LOGIC ("Adding Nix: " << i << " with " << nixVector->BitCount (numberOfDevices)
218  << " bits, for node " << m_node->GetId ());
219  nixVector->AddNeighborIndex (i, nixVector->BitCount (numberOfDevices));
220  return true;
221  }
222  }
223  return false;
224 }
225 
226 bool
227 Ipv4NixVectorRouting::BuildNixVector (const std::vector< Ptr<Node> > & parentVector, uint32_t source, uint32_t dest, Ptr<NixVector> nixVector)
228 {
230 
231  if (source == dest)
232  {
233  return true;
234  }
235 
236  if (parentVector.at (dest) == 0)
237  {
238  return false;
239  }
240 
241  Ptr<Node> parentNode = parentVector.at (dest);
242 
243  uint32_t numberOfDevices = parentNode->GetNDevices ();
244  uint32_t destId = 0;
245  uint32_t totalNeighbors = 0;
246 
247  // scan through the net devices on the parent node
248  // and then look at the nodes adjacent to them
249  for (uint32_t i = 0; i < numberOfDevices; i++)
250  {
251  // Get a net device from the node
252  // as well as the channel, and figure
253  // out the adjacent net devices
254  Ptr<NetDevice> localNetDevice = parentNode->GetDevice (i);
255  if (localNetDevice->IsBridge ())
256  {
257  continue;
258  }
259  Ptr<Channel> channel = localNetDevice->GetChannel ();
260  if (channel == 0)
261  {
262  continue;
263  }
264 
265  // this function takes in the local net dev, and channnel, and
266  // writes to the netDeviceContainer the adjacent net devs
267  NetDeviceContainer netDeviceContainer;
268  GetAdjacentNetDevices (localNetDevice, channel, netDeviceContainer);
269 
270  // Finally we can get the adjacent nodes
271  // and scan through them. If we find the
272  // node that matches "dest" then we can add
273  // the index to the nix vector.
274  // the index corresponds to the neighbor index
275  uint32_t offset = 0;
276  for (NetDeviceContainer::Iterator iter = netDeviceContainer.Begin (); iter != netDeviceContainer.End (); iter++)
277  {
278  Ptr<Node> remoteNode = (*iter)->GetNode ();
279 
280  if (remoteNode->GetId () == dest)
281  {
282  destId = totalNeighbors + offset;
283  }
284  offset += 1;
285  }
286 
287  totalNeighbors += netDeviceContainer.GetN ();
288  }
289  NS_LOG_LOGIC ("Adding Nix: " << destId << " with "
290  << nixVector->BitCount (totalNeighbors) << " bits, for node " << parentNode->GetId ());
291  nixVector->AddNeighborIndex (destId, nixVector->BitCount (totalNeighbors));
292 
293  // recurse through parent vector, grabbing the path
294  // and building the nix vector
295  BuildNixVector (parentVector, source, (parentVector.at (dest))->GetId (), nixVector);
296  return true;
297 }
298 
299 void
301 {
303 
304  for (uint32_t i = 0; i < channel->GetNDevices (); i++)
305  {
306  Ptr<NetDevice> remoteDevice = channel->GetDevice (i);
307  if (remoteDevice != netDevice)
308  {
309  Ptr<BridgeNetDevice> bd = NetDeviceIsBridged (remoteDevice);
310  // we have a bridged device, we need to add all
311  // bridged devices
312  if (bd)
313  {
314  NS_LOG_LOGIC ("Looking through bridge ports of bridge net device " << bd);
315  for (uint32_t j = 0; j < bd->GetNBridgePorts (); ++j)
316  {
317  Ptr<NetDevice> ndBridged = bd->GetBridgePort (j);
318  if (ndBridged == remoteDevice)
319  {
320  NS_LOG_LOGIC ("That bridge port is me, don't walk backward");
321  continue;
322  }
323  Ptr<Channel> chBridged = ndBridged->GetChannel ();
324  if (chBridged == 0)
325  {
326  continue;
327  }
328  GetAdjacentNetDevices (ndBridged, chBridged, netDeviceContainer);
329  }
330  }
331  else
332  {
333  netDeviceContainer.Add (channel->GetDevice (i));
334  }
335  }
336  }
337 }
338 
339 Ptr<Node>
341 {
343 
345  Ptr<Node> destNode;
346 
347  for (NodeContainer::Iterator i = allNodes.Begin (); i != allNodes.End (); ++i)
348  {
349  Ptr<Node> node = *i;
350  Ptr<Ipv4> ipv4 = node->GetObject<Ipv4> ();
351  if (ipv4->GetInterfaceForAddress (dest) != -1)
352  {
353  destNode = node;
354  break;
355  }
356  }
357 
358  if (!destNode)
359  {
360  NS_LOG_ERROR ("Couldn't find dest node given the IP" << dest);
361  return 0;
362  }
363 
364  return destNode;
365 }
366 
367 uint32_t
369 {
370  uint32_t numberOfDevices = m_node->GetNDevices ();
371  uint32_t totalNeighbors = 0;
372 
373  // scan through the net devices on the parent node
374  // and then look at the nodes adjacent to them
375  for (uint32_t i = 0; i < numberOfDevices; i++)
376  {
377  // Get a net device from the node
378  // as well as the channel, and figure
379  // out the adjacent net devices
380  Ptr<NetDevice> localNetDevice = m_node->GetDevice (i);
381  Ptr<Channel> channel = localNetDevice->GetChannel ();
382  if (channel == 0)
383  {
384  continue;
385  }
386 
387  // this function takes in the local net dev, and channnel, and
388  // writes to the netDeviceContainer the adjacent net devs
389  NetDeviceContainer netDeviceContainer;
390  GetAdjacentNetDevices (localNetDevice, channel, netDeviceContainer);
391 
392  totalNeighbors += netDeviceContainer.GetN ();
393  }
394 
395  return totalNeighbors;
396 }
397 
400 {
401  NS_LOG_FUNCTION (nd);
402 
403  Ptr<Node> node = nd->GetNode ();
404  uint32_t nDevices = node->GetNDevices ();
405 
406  //
407  // There is no bit on a net device that says it is being bridged, so we have
408  // to look for bridges on the node to which the device is attached. If we
409  // find a bridge, we need to look through its bridge ports (the devices it
410  // bridges) to see if we find the device in question.
411  //
412  for (uint32_t i = 0; i < nDevices; ++i)
413  {
414  Ptr<NetDevice> ndTest = node->GetDevice (i);
415  NS_LOG_LOGIC ("Examine device " << i << " " << ndTest);
416 
417  if (ndTest->IsBridge ())
418  {
419  NS_LOG_LOGIC ("device " << i << " is a bridge net device");
420  Ptr<BridgeNetDevice> bnd = ndTest->GetObject<BridgeNetDevice> ();
421  NS_ABORT_MSG_UNLESS (bnd, "Ipv4NixVectorRouting::NetDeviceIsBridged (): GetObject for <BridgeNetDevice> failed");
422 
423  for (uint32_t j = 0; j < bnd->GetNBridgePorts (); ++j)
424  {
425  NS_LOG_LOGIC ("Examine bridge port " << j << " " << bnd->GetBridgePort (j));
426  if (bnd->GetBridgePort (j) == nd)
427  {
428  NS_LOG_LOGIC ("Net device " << nd << " is bridged by " << bnd);
429  return bnd;
430  }
431  }
432  }
433  }
434  NS_LOG_LOGIC ("Net device " << nd << " is not bridged");
435  return 0;
436 }
437 
438 uint32_t
440 {
441  uint32_t numberOfDevices = m_node->GetNDevices ();
442  uint32_t index = 0;
443  uint32_t totalNeighbors = 0;
444 
445  // scan through the net devices on the parent node
446  // and then look at the nodes adjacent to them
447  for (uint32_t i = 0; i < numberOfDevices; i++)
448  {
449  // Get a net device from the node
450  // as well as the channel, and figure
451  // out the adjacent net devices
452  Ptr<NetDevice> localNetDevice = m_node->GetDevice (i);
453  Ptr<Channel> channel = localNetDevice->GetChannel ();
454  if (channel == 0)
455  {
456  continue;
457  }
458 
459  // this function takes in the local net dev, and channnel, and
460  // writes to the netDeviceContainer the adjacent net devs
461  NetDeviceContainer netDeviceContainer;
462  GetAdjacentNetDevices (localNetDevice, channel, netDeviceContainer);
463 
464  // check how many neighbors we have
465  if (nodeIndex < (totalNeighbors + netDeviceContainer.GetN ()))
466  {
467  // found the proper net device
468  index = i;
469  Ptr<NetDevice> gatewayDevice = netDeviceContainer.Get (nodeIndex-totalNeighbors);
470  Ptr<Node> gatewayNode = gatewayDevice->GetNode ();
471  Ptr<Ipv4> ipv4 = gatewayNode->GetObject<Ipv4> ();
472 
473  uint32_t interfaceIndex = (ipv4)->GetInterfaceForDevice (gatewayDevice);
474  Ipv4InterfaceAddress ifAddr = ipv4->GetAddress (interfaceIndex, 0);
475  gatewayIp = ifAddr.GetLocal ();
476  break;
477  }
478  totalNeighbors += netDeviceContainer.GetN ();
479  }
480 
481  return index;
482 }
483 
486 {
488  Ptr<Ipv4Route> rtentry;
489  Ptr<NixVector> nixVectorInCache;
490  Ptr<NixVector> nixVectorForPacket;
491 
492  NS_LOG_DEBUG ("Dest IP from header: " << header.GetDestination ());
493  // check if cache
494  nixVectorInCache = GetNixVectorInCache (header.GetDestination ());
495 
496  // not in cache
497  if (!nixVectorInCache)
498  {
499  NS_LOG_LOGIC ("Nix-vector not in cache, build: ");
500  // Build the nix-vector, given this node and the
501  // dest IP address
502  nixVectorInCache = GetNixVector (m_node, header.GetDestination (), oif);
503 
504  // cache it
505  m_nixCache.insert (NixMap_t::value_type (header.GetDestination (), nixVectorInCache));
506  }
507 
508  // path exists
509  if (nixVectorInCache)
510  {
511  NS_LOG_LOGIC ("Nix-vector contents: " << *nixVectorInCache);
512 
513  // create a new nix vector to be used,
514  // we want to keep the cached version clean
515  nixVectorForPacket = Create<NixVector> ();
516  nixVectorForPacket = nixVectorInCache->Copy ();
517 
518  // Get the interface number that we go out of, by extracting
519  // from the nix-vector
520  if (m_totalNeighbors == 0)
521  {
523  }
524 
525  // Get the interface number that we go out of, by extracting
526  // from the nix-vector
527  uint32_t numberOfBits = nixVectorForPacket->BitCount (m_totalNeighbors);
528  uint32_t nodeIndex = nixVectorForPacket->ExtractNeighborIndex (numberOfBits);
529 
530  // Search here in a cache for this node index
531  // and look for a Ipv4Route
532  rtentry = GetIpv4RouteInCache (header.GetDestination ());
533 
534  if (!rtentry || !(rtentry->GetOutputDevice () == oif))
535  {
536  // not in cache or a different specified output
537  // device is to be used
538 
539  // first, make sure we erase existing (incorrect)
540  // rtentry from the map
541  if (rtentry)
542  {
543  m_ipv4RouteCache.erase (header.GetDestination ());
544  }
545 
546  NS_LOG_LOGIC ("Ipv4Route not in cache, build: ");
547  Ipv4Address gatewayIp;
548  uint32_t index = FindNetDeviceForNixIndex (nodeIndex, gatewayIp);
549  int32_t interfaceIndex = 0;
550 
551  if (!oif)
552  {
553  interfaceIndex = (m_ipv4)->GetInterfaceForDevice (m_node->GetDevice (index));
554  }
555  else
556  {
557  interfaceIndex = (m_ipv4)->GetInterfaceForDevice (oif);
558  }
559 
560  NS_ASSERT_MSG (interfaceIndex != -1, "Interface index not found for device");
561 
562  Ipv4InterfaceAddress ifAddr = m_ipv4->GetAddress (interfaceIndex, 0);
563 
564  // start filling in the Ipv4Route info
565  rtentry = Create<Ipv4Route> ();
566  rtentry->SetSource (ifAddr.GetLocal ());
567 
568  rtentry->SetGateway (gatewayIp);
569  rtentry->SetDestination (header.GetDestination ());
570 
571  if (!oif)
572  {
573  rtentry->SetOutputDevice (m_ipv4->GetNetDevice (interfaceIndex));
574  }
575  else
576  {
577  rtentry->SetOutputDevice (oif);
578  }
579 
580  sockerr = Socket::ERROR_NOTERROR;
581 
582  // add rtentry to cache
583  m_ipv4RouteCache.insert (Ipv4RouteMap_t::value_type (header.GetDestination (), rtentry));
584  }
585 
586  NS_LOG_LOGIC ("Nix-vector contents: " << *nixVectorInCache << " : Remaining bits: " << nixVectorForPacket->GetRemainingBits ());
587 
588  // Add nix-vector in the packet class
589  // make sure the packet exists first
590  if (p)
591  {
592  NS_LOG_LOGIC ("Adding Nix-vector to packet: " << *nixVectorForPacket);
593  p->SetNixVector (nixVectorForPacket);
594  }
595  }
596  else // path doesn't exist
597  {
598  NS_LOG_ERROR ("No path to the dest: " << header.GetDestination ());
599  sockerr = Socket::ERROR_NOROUTETOHOST;
600  }
601 
602  return rtentry;
603 }
604 
605 bool
609 {
611 
612  Ptr<Ipv4Route> rtentry;
613 
614  // Get the nix-vector from the packet
615  Ptr<NixVector> nixVector = p->GetNixVector ();
616 
617  // If nixVector isn't in packet, something went wrong
618  NS_ASSERT (nixVector);
619 
620  // Get the interface number that we go out of, by extracting
621  // from the nix-vector
622  if (m_totalNeighbors == 0)
623  {
625  }
626  uint32_t numberOfBits = nixVector->BitCount (m_totalNeighbors);
627  uint32_t nodeIndex = nixVector->ExtractNeighborIndex (numberOfBits);
628 
629  rtentry = GetIpv4RouteInCache (header.GetDestination ());
630  // not in cache
631  if (!rtentry)
632  {
633  NS_LOG_LOGIC ("Ipv4Route not in cache, build: ");
634  Ipv4Address gatewayIp;
635  uint32_t index = FindNetDeviceForNixIndex (nodeIndex, gatewayIp);
636  uint32_t interfaceIndex = (m_ipv4)->GetInterfaceForDevice (m_node->GetDevice (index));
637  Ipv4InterfaceAddress ifAddr = m_ipv4->GetAddress (interfaceIndex, 0);
638 
639  // start filling in the Ipv4Route info
640  rtentry = Create<Ipv4Route> ();
641  rtentry->SetSource (ifAddr.GetLocal ());
642 
643  rtentry->SetGateway (gatewayIp);
644  rtentry->SetDestination (header.GetDestination ());
645  rtentry->SetOutputDevice (m_ipv4->GetNetDevice (interfaceIndex));
646 
647  // add rtentry to cache
648  m_ipv4RouteCache.insert (Ipv4RouteMap_t::value_type (header.GetDestination (), rtentry));
649  }
650 
651  NS_LOG_LOGIC ("At Node " << m_node->GetId () << ", Extracting " << numberOfBits <<
652  " bits from Nix-vector: " << nixVector << " : " << *nixVector);
653 
654  // call the unicast callback
655  // local deliver is handled by Ipv4StaticRoutingImpl
656  // so this code is never even called if the packet is
657  // destined for this node.
658  ucb (rtentry, p, header);
659 
660  return true;
661 }
662 
663 void
665 {
666 
667  std::ostream* os = stream->GetStream ();
668  *os << "NixCache:" << std::endl;
669  if (m_nixCache.size () > 0)
670  {
671  *os << "Destination NixVector" << std::endl;
672  for (NixMap_t::const_iterator it = m_nixCache.begin (); it != m_nixCache.end (); it++)
673  {
674  std::ostringstream dest;
675  dest << it->first;
676  *os << std::setiosflags (std::ios::left) << std::setw (16) << dest.str ();
677  *os << *(it->second) << std::endl;
678  }
679  }
680  *os << "Ipv4RouteCache:" << std::endl;
681  if (m_ipv4RouteCache.size () > 0)
682  {
683  *os << "Destination Gateway Source OutputDevice" << std::endl;
684  for (Ipv4RouteMap_t::const_iterator it = m_ipv4RouteCache.begin (); it != m_ipv4RouteCache.end (); it++)
685  {
686  std::ostringstream dest, gw, src;
687  dest << it->second->GetDestination ();
688  *os << std::setiosflags (std::ios::left) << std::setw (16) << dest.str ();
689  gw << it->second->GetGateway ();
690  *os << std::setiosflags (std::ios::left) << std::setw (16) << gw.str ();
691  src << it->second->GetSource ();
692  *os << std::setiosflags (std::ios::left) << std::setw (16) << src.str ();
693  *os << " ";
694  if (Names::FindName (it->second->GetOutputDevice ()) != "")
695  {
696  *os << Names::FindName (it->second->GetOutputDevice ());
697  }
698  else
699  {
700  *os << it->second->GetOutputDevice ()->GetIfIndex ();
701  }
702  *os << std::endl;
703  }
704  }
705 }
706 
707 // virtual functions from Ipv4RoutingProtocol
708 void
710 {
712 }
713 void
715 {
717 }
718 void
720 {
722 }
723 void
725 {
727 }
728 
729 bool
730 Ipv4NixVectorRouting::BFS (uint32_t numberOfNodes, Ptr<Node> source,
731  Ptr<Node> dest, std::vector< Ptr<Node> > & parentVector,
732  Ptr<NetDevice> oif)
733 {
735 
736  NS_LOG_LOGIC ("Going from Node " << source->GetId () << " to Node " << dest->GetId ());
737  std::queue< Ptr<Node> > greyNodeList; // discovered nodes with unexplored children
738 
739  // reset the parent vector
740  parentVector.clear ();
741  parentVector.reserve (sizeof (Ptr<Node>)*numberOfNodes);
742  parentVector.insert (parentVector.begin (), sizeof (Ptr<Node>)*numberOfNodes, 0); // initialize to 0
743 
744  // Add the source node to the queue, set its parent to itself
745  greyNodeList.push (source);
746  parentVector.at (source->GetId ()) = source;
747 
748  // BFS loop
749  while (greyNodeList.size () != 0)
750  {
751  Ptr<Node> currNode = greyNodeList.front ();
752  Ptr<Ipv4> ipv4 = currNode->GetObject<Ipv4> ();
753 
754  if (currNode == dest)
755  {
756  NS_LOG_LOGIC ("Made it to Node " << currNode->GetId ());
757  return true;
758  }
759 
760  // if this is the first iteration of the loop and a
761  // specific output interface was given, make sure
762  // we go this way
763  if (currNode == source && oif)
764  {
765  // make sure that we can go this way
766  if (ipv4)
767  {
768  uint32_t interfaceIndex = (ipv4)->GetInterfaceForDevice (oif);
769  if (!(ipv4->IsUp (interfaceIndex)))
770  {
771  NS_LOG_LOGIC ("Ipv4Interface is down");
772  return false;
773  }
774  }
775  if (!(oif->IsLinkUp ()))
776  {
777  NS_LOG_LOGIC ("Link is down.");
778  return false;
779  }
780  Ptr<Channel> channel = oif->GetChannel ();
781  if (channel == 0)
782  {
783  return false;
784  }
785 
786  // this function takes in the local net dev, and channnel, and
787  // writes to the netDeviceContainer the adjacent net devs
788  NetDeviceContainer netDeviceContainer;
789  GetAdjacentNetDevices (oif, channel, netDeviceContainer);
790 
791  // Finally we can get the adjacent nodes
792  // and scan through them. We push them
793  // to the greyNode queue, if they aren't
794  // already there.
795  for (NetDeviceContainer::Iterator iter = netDeviceContainer.Begin (); iter != netDeviceContainer.End (); iter++)
796  {
797  Ptr<Node> remoteNode = (*iter)->GetNode ();
798 
799  // check to see if this node has been pushed before
800  // by checking to see if it has a parent
801  // if it doesn't (null or 0), then set its parent and
802  // push to the queue
803  if (parentVector.at (remoteNode->GetId ()) == 0)
804  {
805  parentVector.at (remoteNode->GetId ()) = currNode;
806  greyNodeList.push (remoteNode);
807  }
808  }
809  }
810  else
811  {
812  // Iterate over the current node's adjacent vertices
813  // and push them into the queue
814  for (uint32_t i = 0; i < (currNode->GetNDevices ()); i++)
815  {
816  // Get a net device from the node
817  // as well as the channel, and figure
818  // out the adjacent net device
819  Ptr<NetDevice> localNetDevice = currNode->GetDevice (i);
820 
821  // make sure that we can go this way
822  if (ipv4)
823  {
824  uint32_t interfaceIndex = (ipv4)->GetInterfaceForDevice (currNode->GetDevice (i));
825  if (!(ipv4->IsUp (interfaceIndex)))
826  {
827  NS_LOG_LOGIC ("Ipv4Interface is down");
828  continue;
829  }
830  }
831  if (!(localNetDevice->IsLinkUp ()))
832  {
833  NS_LOG_LOGIC ("Link is down.");
834  continue;
835  }
836  Ptr<Channel> channel = localNetDevice->GetChannel ();
837  if (channel == 0)
838  {
839  continue;
840  }
841 
842  // this function takes in the local net dev, and channnel, and
843  // writes to the netDeviceContainer the adjacent net devs
844  NetDeviceContainer netDeviceContainer;
845  GetAdjacentNetDevices (localNetDevice, channel, netDeviceContainer);
846 
847  // Finally we can get the adjacent nodes
848  // and scan through them. We push them
849  // to the greyNode queue, if they aren't
850  // already there.
851  for (NetDeviceContainer::Iterator iter = netDeviceContainer.Begin (); iter != netDeviceContainer.End (); iter++)
852  {
853  Ptr<Node> remoteNode = (*iter)->GetNode ();
854 
855  // check to see if this node has been pushed before
856  // by checking to see if it has a parent
857  // if it doesn't (null or 0), then set its parent and
858  // push to the queue
859  if (parentVector.at (remoteNode->GetId ()) == 0)
860  {
861  parentVector.at (remoteNode->GetId ()) = currNode;
862  greyNodeList.push (remoteNode);
863  }
864  }
865  }
866  }
867 
868  // Pop off the head grey node. We have all its children.
869  // It is now black.
870  greyNodeList.pop ();
871  }
872 
873  // Didn't find the dest...
874  return false;
875 }
876 
877 } // namespace ns3
Iterator Begin(void) const
Get an iterator which refers to the first NetDevice in the container.
smart pointer class similar to boost::intrusive_ptr
Definition: ptr.h:59
#define NS_LOG_FUNCTION(parameters)
Definition: log.h:345
static uint32_t GetNNodes(void)
Definition: node-list.cc:200
Callback template class.
Definition: callback.h:920
std::vector< Ptr< Node > >::const_iterator Iterator
Ipv4Address GetLocal(void) const
Get the local address.
Ptr< NetDevice > Get(uint32_t i) const
Get the Ptr stored in this container at a given index.
bool BuildNixVectorLocal(Ptr< NixVector > nixVector)
Ptr< NixVector > Copy(void) const
Definition: nix-vector.cc:71
Ipv4Address GetDestination(void) const
Definition: ipv4-header.cc:304
#define NS_ASSERT(condition)
Definition: assert.h:64
NS_OBJECT_ENSURE_REGISTERED(NullMessageSimulatorImpl)
void DoDispose(void)
This method is called by Object::Dispose or by the object's destructor, whichever comes first...
Iterator End(void) const
Get an iterator which indicates past-the-last Node in the container.
virtual void DoDispose(void)
This method is called by Object::Dispose or by the object's destructor, whichever comes first...
Definition: object.cc:336
#define NS_LOG_FUNCTION_NOARGS()
Output the name of the function.
Definition: log.h:309
a virtual net device that bridges multiple LAN segments
Ptr< NixVector > GetNixVector(void) const
Get the packet nix-vector.
Definition: packet.cc:247
SocketErrno
Enumeration of the possible errors returned by a socket.
Definition: socket.h:82
uint32_t FindNetDeviceForNixIndex(uint32_t nodeIndex, Ipv4Address &gatewayIp)
#define NS_ABORT_MSG_UNLESS(cond, msg)
Abnormal program termination if cond is false.
Definition: abort.h:131
Ptr< NixVector > GetNixVector(Ptr< Node >, Ipv4Address, Ptr< NetDevice >)
void SetSource(Ipv4Address src)
Definition: ipv4-route.cc:49
uint32_t GetN(void) const
Get the number of Ptr stored in this container.
Ptr< NetDevice > GetOutputDevice(void) const
Definition: ipv4-route.cc:84
Ptr< NixVector > GetNixVectorInCache(Ipv4Address)
Packet header for IPv4.
Definition: ipv4-header.h:31
uint32_t ExtractNeighborIndex(uint32_t numberOfBits)
Definition: nix-vector.cc:160
void SetNode(Ptr< Node > node)
Set the Node pointer of the node for which this routing protocol is to be placed. ...
void FlushGlobalNixRoutingCache(void)
Called when run-time link topology change occurs which iterates through the node list and flushes any...
void Add(NetDeviceContainer other)
Append the contents of another NetDeviceContainer to the end of this container.
void SetGateway(Ipv4Address gw)
Definition: ipv4-route.cc:63
void SetNixVector(Ptr< NixVector >)
Set the packet nix-vector.
Definition: packet.cc:241
static Iterator End(void)
Definition: node-list.cc:188
Nix-vector routing protocol.
Ptr< Node > GetNodeByIp(Ipv4Address)
holds a vector of ns3::NetDevice pointers
Ptr< NetDevice > GetDevice(uint32_t index) const
Definition: node.cc:132
Ptr< BridgeNetDevice > NetDeviceIsBridged(Ptr< NetDevice > nd) const
static TypeId GetTypeId(void)
The Interface ID of the Global Router interface.
#define NS_LOG_LOGIC(msg)
Definition: log.h:368
virtual void NotifyInterfaceDown(uint32_t interface)
Access to the Ipv4 forwarding table, interfaces, and configuration.
Definition: ipv4.h:75
uint32_t GetNDevices(void) const
Definition: node.cc:140
virtual void NotifyInterfaceUp(uint32_t interface)
keep track of a set of node pointers.
std::vector< Ptr< Node > >::const_iterator Iterator
Definition: node-list.h:43
Iterator Begin(void) const
Get an iterator which refers to the first Node in the container.
void SetOutputDevice(Ptr< NetDevice > outputDevice)
Equivalent in Linux to dst_entry.dev.
Definition: ipv4-route.cc:77
virtual void NotifyRemoveAddress(uint32_t interface, Ipv4InterfaceAddress address)
bool BuildNixVector(const std::vector< Ptr< Node > > &parentVector, uint32_t source, uint32_t dest, Ptr< NixVector > nixVector)
void GetAdjacentNetDevices(Ptr< NetDevice >, Ptr< Channel >, NetDeviceContainer &)
#define NS_ASSERT_MSG(condition, message)
Definition: assert.h:86
static NodeContainer GetGlobal(void)
Create a NodeContainer that contains a list of all nodes created through NodeContainer::Create() and ...
virtual Ptr< Ipv4Route > RouteOutput(Ptr< Packet > p, const Ipv4Header &header, Ptr< NetDevice > oif, Socket::SocketErrno &sockerr)
Query routing cache for an existing route, for an outbound packet.
virtual void SetIpv4(Ptr< Ipv4 > ipv4)
Ipv4 addresses are stored in host order in this class.
Definition: ipv4-address.h:38
uint32_t GetId(void) const
Definition: node.cc:104
a class to store IPv4 address information on an interface
static Iterator Begin(void)
Definition: node-list.cc:182
std::vector< Ptr< NetDevice > >::const_iterator Iterator
#define NS_LOG_DEBUG(msg)
Definition: log.h:289
virtual bool RouteInput(Ptr< const Packet > p, const Ipv4Header &header, Ptr< const NetDevice > idev, UnicastForwardCallback ucb, MulticastForwardCallback mcb, LocalDeliverCallback lcb, ErrorCallback ecb)
Route an input packet (to be forwarded or locally delivered)
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:665
Abstract base class for IPv4 routing protocols.
#define NS_LOG_ERROR(msg)
Definition: log.h:271
void AddNeighborIndex(uint32_t newBits, uint32_t numberOfBits)
Definition: nix-vector.cc:88
tuple address
Definition: first.py:37
Iterator End(void) const
Get an iterator which indicates past-the-last NetDevice in the container.
virtual void NotifyAddAddress(uint32_t interface, Ipv4InterfaceAddress address)
Ptr< T > GetObject(void) const
Definition: object.h:361
a unique identifier for an interface.
Definition: type-id.h:49
TypeId SetParent(TypeId tid)
Definition: type-id.cc:611
virtual void PrintRoutingTable(Ptr< OutputStreamWrapper > stream) const
Print the Routing Table entries.
uint32_t BitCount(uint32_t numberOfNeighbors) const
Definition: nix-vector.cc:365
Ptr< Ipv4Route > GetIpv4RouteInCache(Ipv4Address)
std::ostream * GetStream(void)
Return a pointer to an ostream previously set in the wrapper.
NS_LOG_COMPONENT_DEFINE("Ipv4NixVectorRouting")
void SetDestination(Ipv4Address dest)
Definition: ipv4-route.cc:35
bool BFS(uint32_t numberOfNodes, Ptr< Node > source, Ptr< Node > dest, std::vector< Ptr< Node > > &parentVector, Ptr< NetDevice > oif)