src/routing/nix-vector-routing/ipv4-nix-vector-routing.cc
changeset 5899 a46168c7f4a2
parent 5898 408970e134cb
child 5910 681058254595
equal deleted inserted replaced
5898:408970e134cb 5899:a46168c7f4a2
   115   NS_LOG_FUNCTION_NOARGS ();
   115   NS_LOG_FUNCTION_NOARGS ();
   116   m_ipv4RouteCache.clear ();
   116   m_ipv4RouteCache.clear ();
   117 }
   117 }
   118 
   118 
   119 Ptr<NixVector>
   119 Ptr<NixVector>
   120 Ipv4NixVectorRouting::GetNixVector (Ptr<Node> source, Ipv4Address dest, Ptr<NetDevice> oif)
   120 Ipv4NixVectorRouting::GetNixVector (Ptr<Node> source, Ipv4Address dest)
   121 {
   121 {
   122   NS_LOG_FUNCTION_NOARGS ();
   122   NS_LOG_FUNCTION_NOARGS ();
   123 
   123 
   124   Ptr<NixVector> nixVector = CreateObject<NixVector> ();
   124   Ptr<NixVector> nixVector = CreateObject<NixVector> ();
   125 
   125 
   144   else
   144   else
   145     {
   145     {
   146       // otherwise proceed as normal 
   146       // otherwise proceed as normal 
   147       // and build the nix vector
   147       // and build the nix vector
   148       std::vector< Ptr<Node> > parentVector;
   148       std::vector< Ptr<Node> > parentVector;
   149 
   149       BFS (NodeList::GetNNodes (), source, destNode, parentVector);
   150       BFS (NodeList::GetNNodes (), source, destNode, parentVector, oif);
       
   151 
   150 
   152       if (BuildNixVector (parentVector, source->GetId (), destNode->GetId (), nixVector))
   151       if (BuildNixVector (parentVector, source->GetId (), destNode->GetId (), nixVector))
   153         {
   152         {
   154           return nixVector;
   153           return nixVector;
   155         }
   154         }
   494   if (!nixVectorInCache)
   493   if (!nixVectorInCache)
   495     {
   494     {
   496       NS_LOG_LOGIC ("Nix-vector not in cache, build: ");
   495       NS_LOG_LOGIC ("Nix-vector not in cache, build: ");
   497       // Build the nix-vector, given this node and the
   496       // Build the nix-vector, given this node and the
   498       // dest IP address
   497       // dest IP address
   499       nixVectorInCache = GetNixVector (m_node, header.GetDestination (), oif);
   498       nixVectorInCache = GetNixVector (m_node, header.GetDestination ());
   500 
   499 
   501       // cache it
   500       // cache it
   502       m_nixCache.insert (NixMap_t::value_type (header.GetDestination (), nixVectorInCache));
   501       m_nixCache.insert (NixMap_t::value_type (header.GetDestination (), nixVectorInCache));
   503     }
   502     }
   504 
   503 
   522       // Get the interface number that we go out of, by extracting
   521       // Get the interface number that we go out of, by extracting
   523       // from the nix-vector
   522       // from the nix-vector
   524       uint32_t numberOfBits = nixVectorForPacket->BitCount (m_totalNeighbors);
   523       uint32_t numberOfBits = nixVectorForPacket->BitCount (m_totalNeighbors);
   525       uint32_t nodeIndex = nixVectorForPacket->ExtractNeighborIndex (numberOfBits);
   524       uint32_t nodeIndex = nixVectorForPacket->ExtractNeighborIndex (numberOfBits);
   526 
   525 
   527       // Search here in a cache for this node index 
   526       // Possibly search here in a cache for this node index 
   528       // and look for a Ipv4Route
   527       // and look for a Ipv4Route.  If we have it, don't 
       
   528       // need to do the next 3 lines.
   529       rtentry = GetIpv4RouteInCache (header.GetDestination ());
   529       rtentry = GetIpv4RouteInCache (header.GetDestination ());
   530 
   530       // not in cache
   531       if (!rtentry || !(rtentry->GetOutputDevice () == oif))
   531       if (!rtentry)
   532         {
   532         {
   533           // not in cache or a different specified output
       
   534           // device is to be used
       
   535 
       
   536           // first, make sure we erase existing (incorrect)
       
   537           // rtentry from the map
       
   538           if (rtentry)
       
   539             {
       
   540               m_ipv4RouteCache.erase(header.GetDestination ());
       
   541             }
       
   542 
       
   543           NS_LOG_LOGIC ("Ipv4Route not in cache, build: ");
   533           NS_LOG_LOGIC ("Ipv4Route not in cache, build: ");
   544           Ipv4Address gatewayIp;
   534           Ipv4Address gatewayIp;
   545           uint32_t index = FindNetDeviceForNixIndex (nodeIndex, gatewayIp);
   535           uint32_t index = FindNetDeviceForNixIndex (nodeIndex, gatewayIp);
   546           int32_t interfaceIndex = 0;
   536 
   547 
   537           uint32_t interfaceIndex = (m_ipv4)->GetInterfaceForDevice(m_node->GetDevice(index));
   548           if (!oif)
       
   549             {
       
   550               interfaceIndex = (m_ipv4)->GetInterfaceForDevice(m_node->GetDevice(index));
       
   551             }
       
   552           else
       
   553             {
       
   554               interfaceIndex = (m_ipv4)->GetInterfaceForDevice(oif);
       
   555             }
       
   556 
       
   557           NS_ASSERT_MSG (interfaceIndex != -1, "Interface index not found for device");
       
   558 
       
   559           Ipv4InterfaceAddress ifAddr = m_ipv4->GetAddress (interfaceIndex, 0);
   538           Ipv4InterfaceAddress ifAddr = m_ipv4->GetAddress (interfaceIndex, 0);
   560 
   539 
   561           // start filling in the Ipv4Route info
   540           // start filling in the Ipv4Route info
   562           rtentry = Create<Ipv4Route> ();
   541           rtentry = Create<Ipv4Route> ();
   563           rtentry->SetSource (ifAddr.GetLocal ());
   542           rtentry->SetSource (ifAddr.GetLocal ());
   564 
   543 
   565           rtentry->SetGateway (gatewayIp);
   544           rtentry->SetGateway (gatewayIp);
   566           rtentry->SetDestination (header.GetDestination ());
   545           rtentry->SetDestination (header.GetDestination ());
   567 
   546           rtentry->SetOutputDevice (m_ipv4->GetNetDevice (interfaceIndex));
   568           if (!oif)
       
   569             {
       
   570               rtentry->SetOutputDevice (m_ipv4->GetNetDevice (interfaceIndex));
       
   571             }
       
   572           else
       
   573             {
       
   574               rtentry->SetOutputDevice (oif);
       
   575             }
       
   576 
   547 
   577           sockerr = Socket::ERROR_NOTERROR;
   548           sockerr = Socket::ERROR_NOTERROR;
   578 
   549 
   579           // add rtentry to cache
   550           // add rtentry to cache
   580           m_ipv4RouteCache.insert(Ipv4RouteMap_t::value_type(header.GetDestination (), rtentry));
   551           m_ipv4RouteCache.insert(Ipv4RouteMap_t::value_type(header.GetDestination (), rtentry));
   609   Ptr<Ipv4Route> rtentry;
   580   Ptr<Ipv4Route> rtentry;
   610 
   581 
   611   // Get the nix-vector from the packet
   582   // Get the nix-vector from the packet
   612   Ptr<NixVector> nixVector = p->GetNixVector();
   583   Ptr<NixVector> nixVector = p->GetNixVector();
   613 
   584 
   614   // If nixVector isn't in packet, something went wrong
   585   // make sure it exists, if not something
   615   NS_ASSERT (nixVector);
   586   // went wrong
   616 
   587   if (!nixVector)
   617   // Get the interface number that we go out of, by extracting
   588     {
   618   // from the nix-vector
   589       NS_LOG_ERROR ("Nix-vector wasn't in the packet! Rebuild.");
   619   if (m_totalNeighbors == 0)
   590 
   620     {
   591       Ptr<NixVector> nixVectorInCache;
   621       m_totalNeighbors = FindTotalNeighbors ();
   592 
   622     }
   593       NS_LOG_DEBUG ("Dest IP from header: " << header.GetDestination ());
   623   uint32_t numberOfBits = nixVector->BitCount (m_totalNeighbors);
   594 
   624   uint32_t nodeIndex = nixVector->ExtractNeighborIndex (numberOfBits);
   595       // check if cache
   625 
   596       nixVectorInCache = GetNixVectorInCache(header.GetDestination ());
   626   rtentry = GetIpv4RouteInCache (header.GetDestination ());
   597 
   627   // not in cache
   598       // not in cache
   628   if (!rtentry)
   599       if (!nixVectorInCache)
   629     {
   600         {
   630       NS_LOG_LOGIC ("Ipv4Route not in cache, build: ");
   601           NS_LOG_LOGIC ("RouteInput(): Nix-vector not in cache, build: ");
   631       Ipv4Address gatewayIp;
   602 
   632       uint32_t index = FindNetDeviceForNixIndex (nodeIndex, gatewayIp);
   603           // Build the nix-vector, given this node and the
   633       uint32_t interfaceIndex = (m_ipv4)->GetInterfaceForDevice(m_node->GetDevice(index));
   604           // dest IP address
   634       Ipv4InterfaceAddress ifAddr = m_ipv4->GetAddress (interfaceIndex, 0);
   605           nixVectorInCache = GetNixVector (m_node, header.GetDestination ());
   635 
   606         }
   636       // start filling in the Ipv4Route info
   607 
   637       rtentry = Create<Ipv4Route> ();
   608       // path exists
   638       rtentry->SetSource (ifAddr.GetLocal ());
   609       if (nixVectorInCache)
   639 
   610         {
   640       rtentry->SetGateway (gatewayIp);
   611           NS_LOG_LOGIC ("Nix-vector contents: " << *nixVectorInCache);
   641       rtentry->SetDestination (header.GetDestination ());
   612 
   642       rtentry->SetOutputDevice (m_ipv4->GetNetDevice (interfaceIndex));
   613           // cache it
   643 
   614           m_nixCache.insert(NixMap_t::value_type(header.GetDestination (), nixVectorInCache));
   644       // add rtentry to cache
   615 
   645       m_ipv4RouteCache.insert(Ipv4RouteMap_t::value_type(header.GetDestination (), rtentry));
   616           // create a new nix vector to be used, 
   646     }
   617           // we want to keep the cached version clean
   647 
   618           Ptr<NixVector> nixVectorForPacket;
   648   NS_LOG_LOGIC ("At Node " << m_node->GetId() << ", Extracting " << numberOfBits << 
   619           nixVectorForPacket = CreateObject<NixVector> ();
   649                        " bits from Nix-vector: " << nixVector << " : " << *nixVector);
   620           nixVectorForPacket = nixVectorInCache->Copy(); 
   650 
   621 
   651   // call the unicast callback
   622           // Get the interface number that we go out of, by extracting
   652   // local deliver is handled by Ipv4StaticRoutingImpl
   623           // from the nix-vector
   653   // so this code is never even called if the packet is
   624           if (m_totalNeighbors == 0)
   654   // destined for this node.
   625             {
   655   ucb (rtentry, p, header);
   626               m_totalNeighbors = FindTotalNeighbors ();
   656 
   627             }
   657   return true;
   628           uint32_t numberOfBits = nixVectorForPacket->BitCount (m_totalNeighbors);
       
   629           uint32_t nodeIndex = nixVectorForPacket->ExtractNeighborIndex (numberOfBits);
       
   630 
       
   631           rtentry = GetIpv4RouteInCache (header.GetDestination ());
       
   632           // not in cache
       
   633           if (!rtentry)
       
   634             {
       
   635               NS_LOG_LOGIC ("Ipv4Route not in cache, build: ");
       
   636               Ipv4Address gatewayIp;
       
   637               uint32_t index = FindNetDeviceForNixIndex (nodeIndex, gatewayIp);
       
   638 
       
   639               uint32_t interfaceIndex = (m_ipv4)->GetInterfaceForDevice(m_node->GetDevice(index));
       
   640               Ipv4InterfaceAddress ifAddr = m_ipv4->GetAddress (interfaceIndex, 0);
       
   641 
       
   642               // start filling in the Ipv4Route info
       
   643               rtentry = Create<Ipv4Route> ();
       
   644               rtentry->SetSource (ifAddr.GetLocal ());
       
   645 
       
   646               rtentry->SetGateway (Ipv4Address(gatewayIp));
       
   647               rtentry->SetDestination (header.GetDestination ());
       
   648               rtentry->SetOutputDevice (m_ipv4->GetNetDevice (interfaceIndex));
       
   649 
       
   650               // add rtentry to cache
       
   651               m_ipv4RouteCache.insert(Ipv4RouteMap_t::value_type(header.GetDestination (), rtentry));
       
   652             }
       
   653 
       
   654           NS_LOG_LOGIC ("Nix-vector contents: " << *nixVectorInCache << " : Remaining bits: " << nixVectorForPacket->GetRemainingBits());
       
   655 
       
   656           // Add  nix-vector in the packet class 
       
   657           // have to copy the packet first b/c 
       
   658           // it is const
       
   659           Ptr<Packet> newPacket = Create<Packet> ();
       
   660           newPacket = p->Copy();
       
   661 
       
   662           NS_LOG_LOGIC ("Adding Nix-vector to packet: " << *nixVectorForPacket);
       
   663           newPacket->SetNixVector(nixVectorForPacket);
       
   664 
       
   665           // call the unicast callback
       
   666           // local deliver is handled by Ipv4StaticRoutingImpl
       
   667           // so this code is never even called if the packet is
       
   668           // destined for this node.
       
   669           ucb (rtentry, newPacket, header);
       
   670           return true;
       
   671         }
       
   672       else // path doesn't exist
       
   673         {
       
   674           NS_LOG_ERROR ("No path to the dest: " << header.GetDestination ());
       
   675           return false;
       
   676         }
       
   677     }
       
   678   else
       
   679     {
       
   680       // Get the interface number that we go out of, by extracting
       
   681       // from the nix-vector
       
   682       if (m_totalNeighbors == 0)
       
   683         {
       
   684           m_totalNeighbors = FindTotalNeighbors ();
       
   685         }
       
   686       uint32_t numberOfBits = nixVector->BitCount (m_totalNeighbors);
       
   687       uint32_t nodeIndex = nixVector->ExtractNeighborIndex (numberOfBits);
       
   688 
       
   689       rtentry = GetIpv4RouteInCache (header.GetDestination ());
       
   690       // not in cache
       
   691       if (!rtentry)
       
   692         {
       
   693           NS_LOG_LOGIC ("Ipv4Route not in cache, build: ");
       
   694           Ipv4Address gatewayIp;
       
   695           uint32_t index = FindNetDeviceForNixIndex (nodeIndex, gatewayIp);
       
   696           uint32_t interfaceIndex = (m_ipv4)->GetInterfaceForDevice(m_node->GetDevice(index));
       
   697           Ipv4InterfaceAddress ifAddr = m_ipv4->GetAddress (interfaceIndex, 0);
       
   698 
       
   699           // start filling in the Ipv4Route info
       
   700           rtentry = Create<Ipv4Route> ();
       
   701           rtentry->SetSource (ifAddr.GetLocal ());
       
   702 
       
   703           rtentry->SetGateway (gatewayIp);
       
   704           rtentry->SetDestination (header.GetDestination ());
       
   705           rtentry->SetOutputDevice (m_ipv4->GetNetDevice (interfaceIndex));
       
   706 
       
   707           // add rtentry to cache
       
   708           m_ipv4RouteCache.insert(Ipv4RouteMap_t::value_type(header.GetDestination (), rtentry));
       
   709         }
       
   710 
       
   711       NS_LOG_LOGIC ("At Node " << m_node->GetId() << ", Extracting " << numberOfBits << 
       
   712                            " bits from Nix-vector: " << nixVector << " : " << *nixVector);
       
   713 
       
   714       // call the unicast callback
       
   715       // local deliver is handled by Ipv4StaticRoutingImpl
       
   716       // so this code is never even called if the packet is
       
   717       // destined for this node.
       
   718       ucb (rtentry, p, header);
       
   719 
       
   720       return true;
       
   721     }
   658 }
   722 }
   659 
   723 
   660 // virtual functions from Ipv4RoutingProtocol 
   724 // virtual functions from Ipv4RoutingProtocol 
   661 void
   725 void
   662 Ipv4NixVectorRouting::NotifyInterfaceUp (uint32_t i)
   726 Ipv4NixVectorRouting::NotifyInterfaceUp (uint32_t i)
   678 {
   742 {
   679   FlushGlobalNixRoutingCache ();
   743   FlushGlobalNixRoutingCache ();
   680 }
   744 }
   681 
   745 
   682 bool
   746 bool
   683 Ipv4NixVectorRouting::BFS (uint32_t numberOfNodes, Ptr<Node> source, 
   747 Ipv4NixVectorRouting::BFS (uint32_t numberOfNodes, Ptr<Node> source, Ptr<Node> dest, std::vector< Ptr<Node> > & parentVector)
   684                            Ptr<Node> dest, std::vector< Ptr<Node> > & parentVector,
       
   685                            Ptr<NetDevice> oif)
       
   686 {
   748 {
   687   NS_LOG_FUNCTION_NOARGS ();
   749   NS_LOG_FUNCTION_NOARGS ();
   688 
   750 
   689   NS_LOG_LOGIC ("Going from Node " << source->GetId() << " to Node " << dest->GetId());
   751   NS_LOG_LOGIC ("Going from Node " << source->GetId() << " to Node " << dest->GetId());
   690   std::queue< Ptr<Node> > greyNodeList;  // discovered nodes with unexplored children
   752   std::queue< Ptr<Node> > greyNodeList;  // discovered nodes with unexplored children
   708         {
   770         {
   709           NS_LOG_LOGIC ("Made it to Node " << currNode->GetId()); 
   771           NS_LOG_LOGIC ("Made it to Node " << currNode->GetId()); 
   710           return true;
   772           return true;
   711         }
   773         }
   712 
   774 
   713       // if this is the first iteration of the loop and a 
   775 
   714       // specific output interface was given, make sure 
   776       // Iterate over the current node's adjacent vertices
   715       // we go this way
   777       // and push them into the queue
   716       if (currNode == source && oif)
   778       for (uint32_t i = 0; i < (currNode->GetNDevices ()); i++)
   717         {
   779         {
       
   780           // Get a net device from the node
       
   781           // as well as the channel, and figure
       
   782           // out the adjacent net device
       
   783           Ptr<NetDevice> localNetDevice = currNode->GetDevice (i);
       
   784 
   718           // make sure that we can go this way
   785           // make sure that we can go this way
   719           if (ipv4)
   786           if (ipv4)
   720             {
   787             {
   721               uint32_t interfaceIndex = (ipv4)->GetInterfaceForDevice(oif);
   788               uint32_t interfaceIndex = (ipv4)->GetInterfaceForDevice(currNode->GetDevice(i));
   722               if (!(ipv4->IsUp (interfaceIndex)))
   789               if (!(ipv4->IsUp (interfaceIndex)))
   723                 {
   790                 {
   724                   NS_LOG_LOGIC ("Ipv4Interface is down");
   791                   NS_LOG_LOGIC ("Ipv4Interface is down");
   725                   return false;
   792                   continue;
   726                 }
   793                 }
   727             }
   794             }
   728           if (!(oif->IsLinkUp ()))
   795             if (!(localNetDevice->IsLinkUp ()))
   729             {
   796               {
   730               NS_LOG_LOGIC ("Link is down.");
   797                 NS_LOG_LOGIC ("Link is down.");
   731               return false;
   798                 continue;
   732             }
   799               }
   733           Ptr<Channel> channel = oif->GetChannel ();
   800           Ptr<Channel> channel = localNetDevice->GetChannel ();
   734           if (channel == 0)
   801           if (channel == 0)
   735             { 
   802             { 
   736               return false;
   803               continue;
   737             }
   804             }
   738 
   805 
   739           // this function takes in the local net dev, and channnel, and
   806           // this function takes in the local net dev, and channnel, and
   740           // writes to the netDeviceContainer the adjacent net devs
   807           // writes to the netDeviceContainer the adjacent net devs
   741           NetDeviceContainer netDeviceContainer;
   808           NetDeviceContainer netDeviceContainer;
   742           GetAdjacentNetDevices (oif, channel, netDeviceContainer);
   809           GetAdjacentNetDevices (localNetDevice, channel, netDeviceContainer);
   743 
   810 
   744           // Finally we can get the adjacent nodes
   811           // Finally we can get the adjacent nodes
   745           // and scan through them.  We push them
   812           // and scan through them.  We push them
   746           // to the greyNode queue, if they aren't 
   813           // to the greyNode queue, if they aren't 
   747           // already there.
   814           // already there.
   758                   parentVector.at (remoteNode->GetId ()) = currNode;
   825                   parentVector.at (remoteNode->GetId ()) = currNode;
   759                   greyNodeList.push (remoteNode);
   826                   greyNodeList.push (remoteNode);
   760                 }
   827                 }
   761             }
   828             }
   762         }
   829         }
   763       else
       
   764         {
       
   765           // Iterate over the current node's adjacent vertices
       
   766           // and push them into the queue
       
   767           for (uint32_t i = 0; i < (currNode->GetNDevices ()); i++)
       
   768             {
       
   769               // Get a net device from the node
       
   770               // as well as the channel, and figure
       
   771               // out the adjacent net device
       
   772               Ptr<NetDevice> localNetDevice = currNode->GetDevice (i);
       
   773 
       
   774               // make sure that we can go this way
       
   775               if (ipv4)
       
   776                 {
       
   777                   uint32_t interfaceIndex = (ipv4)->GetInterfaceForDevice(currNode->GetDevice(i));
       
   778                   if (!(ipv4->IsUp (interfaceIndex)))
       
   779                     {
       
   780                       NS_LOG_LOGIC ("Ipv4Interface is down");
       
   781                       continue;
       
   782                     }
       
   783                 }
       
   784                 if (!(localNetDevice->IsLinkUp ()))
       
   785                   {
       
   786                     NS_LOG_LOGIC ("Link is down.");
       
   787                     continue;
       
   788                   }
       
   789               Ptr<Channel> channel = localNetDevice->GetChannel ();
       
   790               if (channel == 0)
       
   791                 { 
       
   792                   continue;
       
   793                 }
       
   794 
       
   795               // this function takes in the local net dev, and channnel, and
       
   796               // writes to the netDeviceContainer the adjacent net devs
       
   797               NetDeviceContainer netDeviceContainer;
       
   798               GetAdjacentNetDevices (localNetDevice, channel, netDeviceContainer);
       
   799 
       
   800               // Finally we can get the adjacent nodes
       
   801               // and scan through them.  We push them
       
   802               // to the greyNode queue, if they aren't 
       
   803               // already there.
       
   804               for (NetDeviceContainer::Iterator iter = netDeviceContainer.Begin (); iter != netDeviceContainer.End (); iter++)
       
   805                 {
       
   806                   Ptr<Node> remoteNode = (*iter)->GetNode ();
       
   807 
       
   808                   // check to see if this node has been pushed before
       
   809                   // by checking to see if it has a parent
       
   810                   // if it doesn't (null or 0), then set its parent and 
       
   811                   // push to the queue
       
   812                   if (parentVector.at (remoteNode->GetId ()) == 0)
       
   813                     {
       
   814                       parentVector.at (remoteNode->GetId ()) = currNode;
       
   815                       greyNodeList.push (remoteNode);
       
   816                     }
       
   817                 }
       
   818             }
       
   819         }
       
   820 
   830 
   821       // Pop off the head grey node.  We have all its children.
   831       // Pop off the head grey node.  We have all its children.
   822       // It is now black.
   832       // It is now black.
   823       greyNodeList.pop ();
   833       greyNodeList.pop ();
   824     }
   834     }