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 TypeId
39 {
40  static TypeId tid = TypeId ("ns3::Ipv4NixVectorRouting")
42  .AddConstructor<Ipv4NixVectorRouting> ()
43  ;
44  return tid;
45 }
46 
48  : m_totalNeighbors (0)
49 {
51 }
52 
54 {
56 }
57 
58 void
60 {
61  NS_ASSERT (ipv4 != 0);
62  NS_ASSERT (m_ipv4 == 0);
63  NS_LOG_DEBUG ("Created Ipv4NixVectorProtocol");
64 
65  m_ipv4 = ipv4;
66 }
67 
68 void
70 {
72 
73  m_node = 0;
74  m_ipv4 = 0;
75 
77 }
78 
79 
80 void
82 {
84 
85  m_node = node;
86 }
87 
88 void
90 {
92  NodeList::Iterator listEnd = NodeList::End ();
93  for (NodeList::Iterator i = NodeList::Begin (); i != listEnd; i++)
94  {
95  Ptr<Node> node = *i;
97  if (!rp)
98  {
99  continue;
100  }
101  NS_LOG_LOGIC ("Flushing Nix caches.");
102  rp->FlushNixCache ();
103  rp->FlushIpv4RouteCache ();
104  }
105 }
106 
107 void
109 {
111  m_nixCache.clear ();
112 }
113 
114 void
116 {
118  m_ipv4RouteCache.clear ();
119 }
120 
123 {
125 
126  Ptr<NixVector> nixVector = Create<NixVector> ();
127 
128  // not in cache, must build the nix vector
129  // First, we have to figure out the nodes
130  // associated with these IPs
131  Ptr<Node> destNode = GetNodeByIp (dest);
132  if (destNode == 0)
133  {
134  NS_LOG_ERROR ("No routing path exists");
135  return 0;
136  }
137 
138  // if source == dest, then we have a special case
141  if (source == destNode)
142  {
143  NS_LOG_DEBUG ("Do not processs packets to self");
144  return 0;
145  }
146  else
147  {
148  // otherwise proceed as normal
149  // and build the nix vector
150  std::vector< Ptr<Node> > parentVector;
151 
152  BFS (NodeList::GetNNodes (), source, destNode, parentVector, oif);
153 
154  if (BuildNixVector (parentVector, source->GetId (), destNode->GetId (), nixVector))
155  {
156  return nixVector;
157  }
158  else
159  {
160  NS_LOG_ERROR ("No routing path exists");
161  return 0;
162  }
163  }
164 }
165 
168 {
170 
171  NixMap_t::iterator iter = m_nixCache.find (address);
172  if (iter != m_nixCache.end ())
173  {
174  NS_LOG_LOGIC ("Found Nix-vector in cache.");
175  return iter->second;
176  }
177 
178  // not in cache
179  return 0;
180 }
181 
184 {
186 
187  Ipv4RouteMap_t::iterator iter = m_ipv4RouteCache.find (address);
188  if (iter != m_ipv4RouteCache.end ())
189  {
190  NS_LOG_LOGIC ("Found Ipv4Route in cache.");
191  return iter->second;
192  }
193 
194  // not in cache
195  return 0;
196 }
197 
198 bool
200 {
202 
203  uint32_t numberOfDevices = m_node->GetNDevices ();
204 
205  // here we are building a nix vector to
206  // ourself, so we need to find the loopback
207  // interface and add that to the nix vector
208  Ipv4Address loopback ("127.0.0.1");
209  for (uint32_t i = 0; i < numberOfDevices; i++)
210  {
211  uint32_t interfaceIndex = (m_ipv4)->GetInterfaceForDevice (m_node->GetDevice (i));
212  Ipv4InterfaceAddress ifAddr = m_ipv4->GetAddress (interfaceIndex, 0);
213  if (ifAddr.GetLocal () == loopback)
214  {
215  NS_LOG_LOGIC ("Adding loopback to nix.");
216  NS_LOG_LOGIC ("Adding Nix: " << i << " with " << nixVector->BitCount (numberOfDevices)
217  << " bits, for node " << m_node->GetId ());
218  nixVector->AddNeighborIndex (i, nixVector->BitCount (numberOfDevices));
219  return true;
220  }
221  }
222  return false;
223 }
224 
225 bool
226 Ipv4NixVectorRouting::BuildNixVector (const std::vector< Ptr<Node> > & parentVector, uint32_t source, uint32_t dest, Ptr<NixVector> nixVector)
227 {
229 
230  if (source == dest)
231  {
232  return true;
233  }
234 
235  if (parentVector.at (dest) == 0)
236  {
237  return false;
238  }
239 
240  Ptr<Node> parentNode = parentVector.at (dest);
241 
242  uint32_t numberOfDevices = parentNode->GetNDevices ();
243  uint32_t destId = 0;
244  uint32_t totalNeighbors = 0;
245 
246  // scan through the net devices on the parent node
247  // and then look at the nodes adjacent to them
248  for (uint32_t i = 0; i < numberOfDevices; i++)
249  {
250  // Get a net device from the node
251  // as well as the channel, and figure
252  // out the adjacent net devices
253  Ptr<NetDevice> localNetDevice = parentNode->GetDevice (i);
254  if (localNetDevice->IsBridge ())
255  {
256  continue;
257  }
258  Ptr<Channel> channel = localNetDevice->GetChannel ();
259  if (channel == 0)
260  {
261  continue;
262  }
263 
264  // this function takes in the local net dev, and channnel, and
265  // writes to the netDeviceContainer the adjacent net devs
266  NetDeviceContainer netDeviceContainer;
267  GetAdjacentNetDevices (localNetDevice, channel, netDeviceContainer);
268 
269  // Finally we can get the adjacent nodes
270  // and scan through them. If we find the
271  // node that matches "dest" then we can add
272  // the index to the nix vector.
273  // the index corresponds to the neighbor index
274  uint32_t offset = 0;
275  for (NetDeviceContainer::Iterator iter = netDeviceContainer.Begin (); iter != netDeviceContainer.End (); iter++)
276  {
277  Ptr<Node> remoteNode = (*iter)->GetNode ();
278 
279  if (remoteNode->GetId () == dest)
280  {
281  destId = totalNeighbors + offset;
282  }
283  offset += 1;
284  }
285 
286  totalNeighbors += netDeviceContainer.GetN ();
287  }
288  NS_LOG_LOGIC ("Adding Nix: " << destId << " with "
289  << nixVector->BitCount (totalNeighbors) << " bits, for node " << parentNode->GetId ());
290  nixVector->AddNeighborIndex (destId, nixVector->BitCount (totalNeighbors));
291 
292  // recurse through parent vector, grabbing the path
293  // and building the nix vector
294  BuildNixVector (parentVector, source, (parentVector.at (dest))->GetId (), nixVector);
295  return true;
296 }
297 
298 void
300 {
302 
303  for (uint32_t i = 0; i < channel->GetNDevices (); i++)
304  {
305  Ptr<NetDevice> remoteDevice = channel->GetDevice (i);
306  if (remoteDevice != netDevice)
307  {
308  Ptr<BridgeNetDevice> bd = NetDeviceIsBridged (remoteDevice);
309  // we have a bridged device, we need to add all
310  // bridged devices
311  if (bd)
312  {
313  NS_LOG_LOGIC ("Looking through bridge ports of bridge net device " << bd);
314  for (uint32_t j = 0; j < bd->GetNBridgePorts (); ++j)
315  {
316  Ptr<NetDevice> ndBridged = bd->GetBridgePort (j);
317  if (ndBridged == remoteDevice)
318  {
319  NS_LOG_LOGIC ("That bridge port is me, don't walk backward");
320  continue;
321  }
322  Ptr<Channel> chBridged = ndBridged->GetChannel ();
323  if (chBridged == 0)
324  {
325  continue;
326  }
327  GetAdjacentNetDevices (ndBridged, chBridged, netDeviceContainer);
328  }
329  }
330  else
331  {
332  netDeviceContainer.Add (channel->GetDevice (i));
333  }
334  }
335  }
336 }
337 
338 Ptr<Node>
340 {
342 
344  Ptr<Node> destNode;
345 
346  for (NodeContainer::Iterator i = allNodes.Begin (); i != allNodes.End (); ++i)
347  {
348  Ptr<Node> node = *i;
349  Ptr<Ipv4> ipv4 = node->GetObject<Ipv4> ();
350  if (ipv4->GetInterfaceForAddress (dest) != -1)
351  {
352  destNode = node;
353  break;
354  }
355  }
356 
357  if (!destNode)
358  {
359  NS_LOG_ERROR ("Couldn't find dest node given the IP" << dest);
360  return 0;
361  }
362 
363  return destNode;
364 }
365 
366 uint32_t
368 {
369  uint32_t numberOfDevices = m_node->GetNDevices ();
370  uint32_t totalNeighbors = 0;
371 
372  // scan through the net devices on the parent node
373  // and then look at the nodes adjacent to them
374  for (uint32_t i = 0; i < numberOfDevices; i++)
375  {
376  // Get a net device from the node
377  // as well as the channel, and figure
378  // out the adjacent net devices
379  Ptr<NetDevice> localNetDevice = m_node->GetDevice (i);
380  Ptr<Channel> channel = localNetDevice->GetChannel ();
381  if (channel == 0)
382  {
383  continue;
384  }
385 
386  // this function takes in the local net dev, and channnel, and
387  // writes to the netDeviceContainer the adjacent net devs
388  NetDeviceContainer netDeviceContainer;
389  GetAdjacentNetDevices (localNetDevice, channel, netDeviceContainer);
390 
391  totalNeighbors += netDeviceContainer.GetN ();
392  }
393 
394  return totalNeighbors;
395 }
396 
399 {
400  NS_LOG_FUNCTION (nd);
401 
402  Ptr<Node> node = nd->GetNode ();
403  uint32_t nDevices = node->GetNDevices ();
404 
405  //
406  // There is no bit on a net device that says it is being bridged, so we have
407  // to look for bridges on the node to which the device is attached. If we
408  // find a bridge, we need to look through its bridge ports (the devices it
409  // bridges) to see if we find the device in question.
410  //
411  for (uint32_t i = 0; i < nDevices; ++i)
412  {
413  Ptr<NetDevice> ndTest = node->GetDevice (i);
414  NS_LOG_LOGIC ("Examine device " << i << " " << ndTest);
415 
416  if (ndTest->IsBridge ())
417  {
418  NS_LOG_LOGIC ("device " << i << " is a bridge net device");
419  Ptr<BridgeNetDevice> bnd = ndTest->GetObject<BridgeNetDevice> ();
420  NS_ABORT_MSG_UNLESS (bnd, "Ipv4NixVectorRouting::NetDeviceIsBridged (): GetObject for <BridgeNetDevice> failed");
421 
422  for (uint32_t j = 0; j < bnd->GetNBridgePorts (); ++j)
423  {
424  NS_LOG_LOGIC ("Examine bridge port " << j << " " << bnd->GetBridgePort (j));
425  if (bnd->GetBridgePort (j) == nd)
426  {
427  NS_LOG_LOGIC ("Net device " << nd << " is bridged by " << bnd);
428  return bnd;
429  }
430  }
431  }
432  }
433  NS_LOG_LOGIC ("Net device " << nd << " is not bridged");
434  return 0;
435 }
436 
437 uint32_t
439 {
440  uint32_t numberOfDevices = m_node->GetNDevices ();
441  uint32_t index = 0;
442  uint32_t totalNeighbors = 0;
443 
444  // scan through the net devices on the parent node
445  // and then look at the nodes adjacent to them
446  for (uint32_t i = 0; i < numberOfDevices; i++)
447  {
448  // Get a net device from the node
449  // as well as the channel, and figure
450  // out the adjacent net devices
451  Ptr<NetDevice> localNetDevice = m_node->GetDevice (i);
452  Ptr<Channel> channel = localNetDevice->GetChannel ();
453  if (channel == 0)
454  {
455  continue;
456  }
457 
458  // this function takes in the local net dev, and channnel, and
459  // writes to the netDeviceContainer the adjacent net devs
460  NetDeviceContainer netDeviceContainer;
461  GetAdjacentNetDevices (localNetDevice, channel, netDeviceContainer);
462 
463  // check how many neighbors we have
464  if (nodeIndex < (totalNeighbors + netDeviceContainer.GetN ()))
465  {
466  // found the proper net device
467  index = i;
468  Ptr<NetDevice> gatewayDevice = netDeviceContainer.Get (nodeIndex-totalNeighbors);
469  Ptr<Node> gatewayNode = gatewayDevice->GetNode ();
470  Ptr<Ipv4> ipv4 = gatewayNode->GetObject<Ipv4> ();
471 
472  uint32_t interfaceIndex = (ipv4)->GetInterfaceForDevice (gatewayDevice);
473  Ipv4InterfaceAddress ifAddr = ipv4->GetAddress (interfaceIndex, 0);
474  gatewayIp = ifAddr.GetLocal ();
475  break;
476  }
477  totalNeighbors += netDeviceContainer.GetN ();
478  }
479 
480  return index;
481 }
482 
485 {
487  Ptr<Ipv4Route> rtentry;
488  Ptr<NixVector> nixVectorInCache;
489  Ptr<NixVector> nixVectorForPacket;
490 
491  NS_LOG_DEBUG ("Dest IP from header: " << header.GetDestination ());
492  // check if cache
493  nixVectorInCache = GetNixVectorInCache (header.GetDestination ());
494 
495  // not in cache
496  if (!nixVectorInCache)
497  {
498  NS_LOG_LOGIC ("Nix-vector not in cache, build: ");
499  // Build the nix-vector, given this node and the
500  // dest IP address
501  nixVectorInCache = GetNixVector (m_node, header.GetDestination (), oif);
502 
503  // cache it
504  m_nixCache.insert (NixMap_t::value_type (header.GetDestination (), nixVectorInCache));
505  }
506 
507  // path exists
508  if (nixVectorInCache)
509  {
510  NS_LOG_LOGIC ("Nix-vector contents: " << *nixVectorInCache);
511 
512  // create a new nix vector to be used,
513  // we want to keep the cached version clean
514  nixVectorForPacket = Create<NixVector> ();
515  nixVectorForPacket = nixVectorInCache->Copy ();
516 
517  // Get the interface number that we go out of, by extracting
518  // from the nix-vector
519  if (m_totalNeighbors == 0)
520  {
522  }
523 
524  // Get the interface number that we go out of, by extracting
525  // from the nix-vector
526  uint32_t numberOfBits = nixVectorForPacket->BitCount (m_totalNeighbors);
527  uint32_t nodeIndex = nixVectorForPacket->ExtractNeighborIndex (numberOfBits);
528 
529  // Search here in a cache for this node index
530  // and look for a Ipv4Route
531  rtentry = GetIpv4RouteInCache (header.GetDestination ());
532 
533  if (!rtentry || !(rtentry->GetOutputDevice () == oif))
534  {
535  // not in cache or a different specified output
536  // device is to be used
537 
538  // first, make sure we erase existing (incorrect)
539  // rtentry from the map
540  if (rtentry)
541  {
542  m_ipv4RouteCache.erase (header.GetDestination ());
543  }
544 
545  NS_LOG_LOGIC ("Ipv4Route not in cache, build: ");
546  Ipv4Address gatewayIp;
547  uint32_t index = FindNetDeviceForNixIndex (nodeIndex, gatewayIp);
548  int32_t interfaceIndex = 0;
549 
550  if (!oif)
551  {
552  interfaceIndex = (m_ipv4)->GetInterfaceForDevice (m_node->GetDevice (index));
553  }
554  else
555  {
556  interfaceIndex = (m_ipv4)->GetInterfaceForDevice (oif);
557  }
558 
559  NS_ASSERT_MSG (interfaceIndex != -1, "Interface index not found for device");
560 
561  Ipv4InterfaceAddress ifAddr = m_ipv4->GetAddress (interfaceIndex, 0);
562 
563  // start filling in the Ipv4Route info
564  rtentry = Create<Ipv4Route> ();
565  rtentry->SetSource (ifAddr.GetLocal ());
566 
567  rtentry->SetGateway (gatewayIp);
568  rtentry->SetDestination (header.GetDestination ());
569 
570  if (!oif)
571  {
572  rtentry->SetOutputDevice (m_ipv4->GetNetDevice (interfaceIndex));
573  }
574  else
575  {
576  rtentry->SetOutputDevice (oif);
577  }
578 
579  sockerr = Socket::ERROR_NOTERROR;
580 
581  // add rtentry to cache
582  m_ipv4RouteCache.insert (Ipv4RouteMap_t::value_type (header.GetDestination (), rtentry));
583  }
584 
585  NS_LOG_LOGIC ("Nix-vector contents: " << *nixVectorInCache << " : Remaining bits: " << nixVectorForPacket->GetRemainingBits ());
586 
587  // Add nix-vector in the packet class
588  // make sure the packet exists first
589  if (p)
590  {
591  NS_LOG_LOGIC ("Adding Nix-vector to packet: " << *nixVectorForPacket);
592  p->SetNixVector (nixVectorForPacket);
593  }
594  }
595  else // path doesn't exist
596  {
597  NS_LOG_ERROR ("No path to the dest: " << header.GetDestination ());
598  sockerr = Socket::ERROR_NOROUTETOHOST;
599  }
600 
601  return rtentry;
602 }
603 
604 bool
608 {
610 
611  Ptr<Ipv4Route> rtentry;
612 
613  // Get the nix-vector from the packet
614  Ptr<NixVector> nixVector = p->GetNixVector ();
615 
616  // If nixVector isn't in packet, something went wrong
617  NS_ASSERT (nixVector);
618 
619  // Get the interface number that we go out of, by extracting
620  // from the nix-vector
621  if (m_totalNeighbors == 0)
622  {
624  }
625  uint32_t numberOfBits = nixVector->BitCount (m_totalNeighbors);
626  uint32_t nodeIndex = nixVector->ExtractNeighborIndex (numberOfBits);
627 
628  rtentry = GetIpv4RouteInCache (header.GetDestination ());
629  // not in cache
630  if (!rtentry)
631  {
632  NS_LOG_LOGIC ("Ipv4Route not in cache, build: ");
633  Ipv4Address gatewayIp;
634  uint32_t index = FindNetDeviceForNixIndex (nodeIndex, gatewayIp);
635  uint32_t interfaceIndex = (m_ipv4)->GetInterfaceForDevice (m_node->GetDevice (index));
636  Ipv4InterfaceAddress ifAddr = m_ipv4->GetAddress (interfaceIndex, 0);
637 
638  // start filling in the Ipv4Route info
639  rtentry = Create<Ipv4Route> ();
640  rtentry->SetSource (ifAddr.GetLocal ());
641 
642  rtentry->SetGateway (gatewayIp);
643  rtentry->SetDestination (header.GetDestination ());
644  rtentry->SetOutputDevice (m_ipv4->GetNetDevice (interfaceIndex));
645 
646  // add rtentry to cache
647  m_ipv4RouteCache.insert (Ipv4RouteMap_t::value_type (header.GetDestination (), rtentry));
648  }
649 
650  NS_LOG_LOGIC ("At Node " << m_node->GetId () << ", Extracting " << numberOfBits <<
651  " bits from Nix-vector: " << nixVector << " : " << *nixVector);
652 
653  // call the unicast callback
654  // local deliver is handled by Ipv4StaticRoutingImpl
655  // so this code is never even called if the packet is
656  // destined for this node.
657  ucb (rtentry, p, header);
658 
659  return true;
660 }
661 
662 void
664 {
665 
666  std::ostream* os = stream->GetStream ();
667  *os << "NixCache:" << std::endl;
668  if (m_nixCache.size () > 0)
669  {
670  *os << "Destination NixVector" << std::endl;
671  for (NixMap_t::const_iterator it = m_nixCache.begin (); it != m_nixCache.end (); it++)
672  {
673  std::ostringstream dest;
674  dest << it->first;
675  *os << std::setiosflags (std::ios::left) << std::setw (16) << dest.str ();
676  *os << *(it->second) << std::endl;
677  }
678  }
679  *os << "Ipv4RouteCache:" << std::endl;
680  if (m_ipv4RouteCache.size () > 0)
681  {
682  *os << "Destination Gateway Source OutputDevice" << std::endl;
683  for (Ipv4RouteMap_t::const_iterator it = m_ipv4RouteCache.begin (); it != m_ipv4RouteCache.end (); it++)
684  {
685  std::ostringstream dest, gw, src;
686  dest << it->second->GetDestination ();
687  *os << std::setiosflags (std::ios::left) << std::setw (16) << dest.str ();
688  gw << it->second->GetGateway ();
689  *os << std::setiosflags (std::ios::left) << std::setw (16) << gw.str ();
690  src << it->second->GetSource ();
691  *os << std::setiosflags (std::ios::left) << std::setw (16) << src.str ();
692  *os << " ";
693  if (Names::FindName (it->second->GetOutputDevice ()) != "")
694  {
695  *os << Names::FindName (it->second->GetOutputDevice ());
696  }
697  else
698  {
699  *os << it->second->GetOutputDevice ()->GetIfIndex ();
700  }
701  *os << std::endl;
702  }
703  }
704 }
705 
706 // virtual functions from Ipv4RoutingProtocol
707 void
709 {
711 }
712 void
714 {
716 }
717 void
719 {
721 }
722 void
724 {
726 }
727 
728 bool
729 Ipv4NixVectorRouting::BFS (uint32_t numberOfNodes, Ptr<Node> source,
730  Ptr<Node> dest, std::vector< Ptr<Node> > & parentVector,
731  Ptr<NetDevice> oif)
732 {
734 
735  NS_LOG_LOGIC ("Going from Node " << source->GetId () << " to Node " << dest->GetId ());
736  std::queue< Ptr<Node> > greyNodeList; // discovered nodes with unexplored children
737 
738  // reset the parent vector
739  parentVector.clear ();
740  parentVector.reserve (sizeof (Ptr<Node>)*numberOfNodes);
741  parentVector.insert (parentVector.begin (), sizeof (Ptr<Node>)*numberOfNodes, 0); // initialize to 0
742 
743  // Add the source node to the queue, set its parent to itself
744  greyNodeList.push (source);
745  parentVector.at (source->GetId ()) = source;
746 
747  // BFS loop
748  while (greyNodeList.size () != 0)
749  {
750  Ptr<Node> currNode = greyNodeList.front ();
751  Ptr<Ipv4> ipv4 = currNode->GetObject<Ipv4> ();
752 
753  if (currNode == dest)
754  {
755  NS_LOG_LOGIC ("Made it to Node " << currNode->GetId ());
756  return true;
757  }
758 
759  // if this is the first iteration of the loop and a
760  // specific output interface was given, make sure
761  // we go this way
762  if (currNode == source && oif)
763  {
764  // make sure that we can go this way
765  if (ipv4)
766  {
767  uint32_t interfaceIndex = (ipv4)->GetInterfaceForDevice (oif);
768  if (!(ipv4->IsUp (interfaceIndex)))
769  {
770  NS_LOG_LOGIC ("Ipv4Interface is down");
771  return false;
772  }
773  }
774  if (!(oif->IsLinkUp ()))
775  {
776  NS_LOG_LOGIC ("Link is down.");
777  return false;
778  }
779  Ptr<Channel> channel = oif->GetChannel ();
780  if (channel == 0)
781  {
782  return false;
783  }
784 
785  // this function takes in the local net dev, and channnel, and
786  // writes to the netDeviceContainer the adjacent net devs
787  NetDeviceContainer netDeviceContainer;
788  GetAdjacentNetDevices (oif, channel, netDeviceContainer);
789 
790  // Finally we can get the adjacent nodes
791  // and scan through them. We push them
792  // to the greyNode queue, if they aren't
793  // already there.
794  for (NetDeviceContainer::Iterator iter = netDeviceContainer.Begin (); iter != netDeviceContainer.End (); iter++)
795  {
796  Ptr<Node> remoteNode = (*iter)->GetNode ();
797 
798  // check to see if this node has been pushed before
799  // by checking to see if it has a parent
800  // if it doesn't (null or 0), then set its parent and
801  // push to the queue
802  if (parentVector.at (remoteNode->GetId ()) == 0)
803  {
804  parentVector.at (remoteNode->GetId ()) = currNode;
805  greyNodeList.push (remoteNode);
806  }
807  }
808  }
809  else
810  {
811  // Iterate over the current node's adjacent vertices
812  // and push them into the queue
813  for (uint32_t i = 0; i < (currNode->GetNDevices ()); i++)
814  {
815  // Get a net device from the node
816  // as well as the channel, and figure
817  // out the adjacent net device
818  Ptr<NetDevice> localNetDevice = currNode->GetDevice (i);
819 
820  // make sure that we can go this way
821  if (ipv4)
822  {
823  uint32_t interfaceIndex = (ipv4)->GetInterfaceForDevice (currNode->GetDevice (i));
824  if (!(ipv4->IsUp (interfaceIndex)))
825  {
826  NS_LOG_LOGIC ("Ipv4Interface is down");
827  continue;
828  }
829  }
830  if (!(localNetDevice->IsLinkUp ()))
831  {
832  NS_LOG_LOGIC ("Link is down.");
833  continue;
834  }
835  Ptr<Channel> channel = localNetDevice->GetChannel ();
836  if (channel == 0)
837  {
838  continue;
839  }
840 
841  // this function takes in the local net dev, and channnel, and
842  // writes to the netDeviceContainer the adjacent net devs
843  NetDeviceContainer netDeviceContainer;
844  GetAdjacentNetDevices (localNetDevice, channel, netDeviceContainer);
845 
846  // Finally we can get the adjacent nodes
847  // and scan through them. We push them
848  // to the greyNode queue, if they aren't
849  // already there.
850  for (NetDeviceContainer::Iterator iter = netDeviceContainer.Begin (); iter != netDeviceContainer.End (); iter++)
851  {
852  Ptr<Node> remoteNode = (*iter)->GetNode ();
853 
854  // check to see if this node has been pushed before
855  // by checking to see if it has a parent
856  // if it doesn't (null or 0), then set its parent and
857  // push to the queue
858  if (parentVector.at (remoteNode->GetId ()) == 0)
859  {
860  parentVector.at (remoteNode->GetId ()) = currNode;
861  greyNodeList.push (remoteNode);
862  }
863  }
864  }
865  }
866 
867  // Pop off the head grey node. We have all its children.
868  // It is now black.
869  greyNodeList.pop ();
870  }
871 
872  // Didn't find the dest...
873  return false;
874 }
875 
876 } // 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:311
static uint32_t GetNNodes(void)
Definition: node-list.cc:198
Callback template class.
Definition: callback.h:920
std::vector< Ptr< Node > >::const_iterator Iterator
Ipv4Address GetLocal(void) const
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:303
#define NS_ASSERT(condition)
Definition: assert.h:64
Iterator End(void) const
Get an iterator which indicates past-the-last Node in the container.
virtual void DoDispose(void)
Definition: object.cc:335
#define NS_LOG_FUNCTION_NOARGS()
Definition: log.h:275
a virtual net device that bridges multiple LAN segments
Ptr< NixVector > GetNixVector(void) const
Definition: packet.cc:247
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:159
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 >)
Definition: packet.cc:241
static Iterator End(void)
Definition: node-list.cc:186
NS_OBJECT_ENSURE_REGISTERED(AntennaModel)
Ptr< Node > GetNodeByIp(Ipv4Address)
holds a vector of ns3::NetDevice pointers
Ptr< NetDevice > GetDevice(uint32_t index) const
Definition: node.cc:131
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:334
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:139
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)
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:103
a class to store IPv4 address information on an interface
static Iterator Begin(void)
Definition: node-list.cc:180
std::vector< Ptr< NetDevice > >::const_iterator Iterator
#define NS_LOG_DEBUG(msg)
Definition: log.h:255
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)
Definition: names.cc:664
Abstract base class for IPv4 routing protocols.
#define NS_LOG_ERROR(msg)
Definition: log.h:237
void AddNeighborIndex(uint32_t newBits, uint32_t numberOfBits)
Definition: nix-vector.cc:87
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:360
a unique identifier for an interface.
Definition: type-id.h:49
TypeId SetParent(TypeId tid)
Definition: type-id.cc:610
virtual void PrintRoutingTable(Ptr< OutputStreamWrapper > stream) const
Print the Routing Table entries.
uint32_t BitCount(uint32_t numberOfNeighbors) const
Definition: nix-vector.cc:364
Ptr< Ipv4Route > GetIpv4RouteInCache(Ipv4Address)
std::ostream * GetStream(void)
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)