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