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:60
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by "...
static uint32_t GetNNodes(void)
Definition: node-list.cc:246
Callback template class.
Definition: callback.h:924
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register the class in the ns-3 factory.
Definition: object-base.h:38
std::vector< Ptr< Node > >::const_iterator Iterator
Node container 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)
At runtime, in debugging builds, if this condition is not true, the program prints the source file...
Definition: assert.h:61
void DoDispose(void)
This method is called by Object::Dispose or by the object's destructor, whichever comes first...
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:170
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:335
#define NS_LOG_FUNCTION_NOARGS()
Output the name of the function.
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)
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 SetNixVector(Ptr< NixVector > nixVector)
Set the packet nix-vector.
Definition: packet.cc:241
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
static Iterator End(void)
Definition: node-list.cc:234
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:134
Ptr< BridgeNetDevice > NetDeviceIsBridged(Ptr< NetDevice > nd) const
static TypeId GetTypeId(void)
The Interface ID of the Global Router interface.
#define NS_LOG_LOGIC(msg)
Use NS_LOG to output a message of level LOG_LOGIC.
Definition: log.h:233
virtual void NotifyInterfaceDown(uint32_t interface)
Access to the Ipv4 forwarding table, interfaces, and configuration.
Definition: ipv4.h:76
uint32_t GetNDevices(void) const
Definition: node.cc:142
virtual void NotifyInterfaceUp(uint32_t interface)
keep track of a set of node pointers.
std::vector< Ptr< Node > >::const_iterator Iterator
Node container iterator.
Definition: node-list.h:44
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)
At runtime, in debugging builds, if this condition is not true, the program prints the message to out...
Definition: assert.h:84
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
#define NS_ABORT_MSG_UNLESS(cond, msg)
Abnormal program termination if cond is false.
Definition: abort.h:136
uint32_t GetId(void) const
Definition: node.cc:106
a class to store IPv4 address information on an interface
static Iterator Begin(void)
Definition: node-list.cc:228
std::vector< Ptr< NetDevice > >::const_iterator Iterator
NetDevice container iterator.
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition: log.h:213
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:664
Abstract base class for IPv4 routing protocols.
#define NS_LOG_ERROR(msg)
Use NS_LOG to output a message of level LOG_ERROR.
Definition: log.h:193
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:362
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:365
Ptr< Ipv4Route > GetIpv4RouteInCache(Ipv4Address)
std::ostream * GetStream(void)
Return a pointer to an ostream previously set in the wrapper.
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)