View | Details | Raw Unified | Return to bug 779
Collapse All | Expand All

(-)a/src/routing/nix-vector-routing/ipv4-nix-vector-routing.cc (-159 / +149 lines)
 Lines 117-123   Ipv4NixVectorRouting::FlushIpv4RouteCach Link Here 
117
}
117
}
118
118
119
Ptr<NixVector>
119
Ptr<NixVector>
120
Ipv4NixVectorRouting::GetNixVector (Ptr<Node> source, Ipv4Address dest)
120
Ipv4NixVectorRouting::GetNixVector (Ptr<Node> source, Ipv4Address dest, Ptr<NetDevice> oif)
121
{
121
{
122
  NS_LOG_FUNCTION_NOARGS ();
122
  NS_LOG_FUNCTION_NOARGS ();
123
123
 Lines 146-152   Ipv4NixVectorRouting::GetNixVector (Ptr< Link Here 
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
      BFS (NodeList::GetNNodes (), source, destNode, parentVector);
149
150
      BFS (NodeList::GetNNodes (), source, destNode, parentVector, oif);
150
151
151
      if (BuildNixVector (parentVector, source->GetId (), destNode->GetId (), nixVector))
152
      if (BuildNixVector (parentVector, source->GetId (), destNode->GetId (), nixVector))
152
        {
153
        {
 Lines 495-501   Ipv4NixVectorRouting::RouteOutput (Ptr<P Link Here 
495
      NS_LOG_LOGIC ("Nix-vector not in cache, build: ");
496
      NS_LOG_LOGIC ("Nix-vector not in cache, build: ");
496
      // Build the nix-vector, given this node and the
497
      // Build the nix-vector, given this node and the
497
      // dest IP address
498
      // dest IP address
498
      nixVectorInCache = GetNixVector (m_node, header.GetDestination ());
499
      nixVectorInCache = GetNixVector (m_node, header.GetDestination (), oif);
499
500
500
      // cache it
501
      // cache it
501
      m_nixCache.insert (NixMap_t::value_type (header.GetDestination (), nixVectorInCache));
502
      m_nixCache.insert (NixMap_t::value_type (header.GetDestination (), nixVectorInCache));
 Lines 523-540   Ipv4NixVectorRouting::RouteOutput (Ptr<P Link Here 
523
      uint32_t numberOfBits = nixVectorForPacket->BitCount (m_totalNeighbors);
524
      uint32_t numberOfBits = nixVectorForPacket->BitCount (m_totalNeighbors);
524
      uint32_t nodeIndex = nixVectorForPacket->ExtractNeighborIndex (numberOfBits);
525
      uint32_t nodeIndex = nixVectorForPacket->ExtractNeighborIndex (numberOfBits);
525
526
526
      // Possibly search here in a cache for this node index 
527
      // Search here in a cache for this node index 
527
      // and look for a Ipv4Route.  If we have it, don't 
528
      // and look for a Ipv4Route
528
      // need to do the next 3 lines.
529
      rtentry = GetIpv4RouteInCache (header.GetDestination ());
529
      rtentry = GetIpv4RouteInCache (header.GetDestination ());
530
      // not in cache
530
531
      if (!rtentry)
531
      if (!rtentry || !(rtentry->GetOutputDevice () == oif))
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
533
          NS_LOG_LOGIC ("Ipv4Route not in cache, build: ");
543
          NS_LOG_LOGIC ("Ipv4Route not in cache, build: ");
534
          Ipv4Address gatewayIp;
544
          Ipv4Address gatewayIp;
535
          uint32_t index = FindNetDeviceForNixIndex (nodeIndex, gatewayIp);
545
          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
538
          Ipv4InterfaceAddress ifAddr = m_ipv4->GetAddress (interfaceIndex, 0);
559
          Ipv4InterfaceAddress ifAddr = m_ipv4->GetAddress (interfaceIndex, 0);
539
560
540
          // start filling in the Ipv4Route info
561
          // start filling in the Ipv4Route info
 Lines 543-549   Ipv4NixVectorRouting::RouteOutput (Ptr<P Link Here 
543
564
544
          rtentry->SetGateway (gatewayIp);
565
          rtentry->SetGateway (gatewayIp);
545
          rtentry->SetDestination (header.GetDestination ());
566
          rtentry->SetDestination (header.GetDestination ());
546
          rtentry->SetOutputDevice (m_ipv4->GetNetDevice (interfaceIndex));
567
568
          if (!oif)
569
            {
570
              rtentry->SetOutputDevice (m_ipv4->GetNetDevice (interfaceIndex));
571
            }
572
          else
573
            {
574
              rtentry->SetOutputDevice (oif);
575
            }
547
576
548
          sockerr = Socket::ERROR_NOTERROR;
577
          sockerr = Socket::ERROR_NOTERROR;
549
578
 Lines 582-724   Ipv4NixVectorRouting::RouteInput (Ptr<co Link Here 
582
  // Get the nix-vector from the packet
611
  // Get the nix-vector from the packet
583
  Ptr<NixVector> nixVector = p->GetNixVector();
612
  Ptr<NixVector> nixVector = p->GetNixVector();
584
613
585
  // make sure it exists, if not something
614
  // If nixVector isn't in packet, something went wrong
586
  // went wrong
615
  NS_ASSERT (nixVector);
587
  if (!nixVector)
616
617
  // Get the interface number that we go out of, by extracting
618
  // from the nix-vector
619
  if (m_totalNeighbors == 0)
588
    {
620
    {
589
      NS_LOG_ERROR ("Nix-vector wasn't in the packet! Rebuild.");
621
      m_totalNeighbors = FindTotalNeighbors ();
622
    }
623
  uint32_t numberOfBits = nixVector->BitCount (m_totalNeighbors);
624
  uint32_t nodeIndex = nixVector->ExtractNeighborIndex (numberOfBits);
590
625
591
      Ptr<NixVector> nixVectorInCache;
626
  rtentry = GetIpv4RouteInCache (header.GetDestination ());
627
  // not in cache
628
  if (!rtentry)
629
    {
630
      NS_LOG_LOGIC ("Ipv4Route not in cache, build: ");
631
      Ipv4Address gatewayIp;
632
      uint32_t index = FindNetDeviceForNixIndex (nodeIndex, gatewayIp);
633
      uint32_t interfaceIndex = (m_ipv4)->GetInterfaceForDevice(m_node->GetDevice(index));
634
      Ipv4InterfaceAddress ifAddr = m_ipv4->GetAddress (interfaceIndex, 0);
592
635
593
      NS_LOG_DEBUG ("Dest IP from header: " << header.GetDestination ());
636
      // start filling in the Ipv4Route info
637
      rtentry = Create<Ipv4Route> ();
638
      rtentry->SetSource (ifAddr.GetLocal ());
594
639
595
      // check if cache
640
      rtentry->SetGateway (gatewayIp);
596
      nixVectorInCache = GetNixVectorInCache(header.GetDestination ());
641
      rtentry->SetDestination (header.GetDestination ());
642
      rtentry->SetOutputDevice (m_ipv4->GetNetDevice (interfaceIndex));
597
643
598
      // not in cache
644
      // add rtentry to cache
599
      if (!nixVectorInCache)
645
      m_ipv4RouteCache.insert(Ipv4RouteMap_t::value_type(header.GetDestination (), rtentry));
600
        {
646
    }
601
          NS_LOG_LOGIC ("RouteInput(): Nix-vector not in cache, build: ");
602
647
603
          // Build the nix-vector, given this node and the
648
  NS_LOG_LOGIC ("At Node " << m_node->GetId() << ", Extracting " << numberOfBits << 
604
          // dest IP address
649
                       " bits from Nix-vector: " << nixVector << " : " << *nixVector);
605
          nixVectorInCache = GetNixVector (m_node, header.GetDestination ());
606
        }
607
650
608
      // path exists
651
  // call the unicast callback
609
      if (nixVectorInCache)
652
  // local deliver is handled by Ipv4StaticRoutingImpl
610
        {
653
  // so this code is never even called if the packet is
611
          NS_LOG_LOGIC ("Nix-vector contents: " << *nixVectorInCache);
654
  // destined for this node.
655
  ucb (rtentry, p, header);
612
656
613
          // cache it
657
  return true;
614
          m_nixCache.insert(NixMap_t::value_type(header.GetDestination (), nixVectorInCache));
615
616
          // create a new nix vector to be used, 
617
          // we want to keep the cached version clean
618
          Ptr<NixVector> nixVectorForPacket;
619
          nixVectorForPacket = CreateObject<NixVector> ();
620
          nixVectorForPacket = nixVectorInCache->Copy(); 
621
622
          // Get the interface number that we go out of, by extracting
623
          // from the nix-vector
624
          if (m_totalNeighbors == 0)
625
            {
626
              m_totalNeighbors = FindTotalNeighbors ();
627
            }
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
    }
722
}
658
}
723
659
724
// virtual functions from Ipv4RoutingProtocol 
660
// virtual functions from Ipv4RoutingProtocol 
 Lines 744-750   Ipv4NixVectorRouting::NotifyRemoveAddres Link Here 
744
}
680
}
745
681
746
bool
682
bool
747
Ipv4NixVectorRouting::BFS (uint32_t numberOfNodes, Ptr<Node> source, Ptr<Node> dest, std::vector< Ptr<Node> > & parentVector)
683
Ipv4NixVectorRouting::BFS (uint32_t numberOfNodes, Ptr<Node> source, 
684
                           Ptr<Node> dest, std::vector< Ptr<Node> > & parentVector,
685
                           Ptr<NetDevice> oif)
748
{
686
{
749
  NS_LOG_FUNCTION_NOARGS ();
687
  NS_LOG_FUNCTION_NOARGS ();
750
688
 Lines 772-812   Ipv4NixVectorRouting::BFS (uint32_t numb Link Here 
772
          return true;
710
          return true;
773
        }
711
        }
774
712
775
713
      // if this is the first iteration of the loop and a 
776
      // Iterate over the current node's adjacent vertices
714
      // specific output interface was given, make sure 
777
      // and push them into the queue
715
      // we go this way
778
      for (uint32_t i = 0; i < (currNode->GetNDevices ()); i++)
716
      if (currNode == source && oif)
779
        {
717
        {
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
785
          // make sure that we can go this way
718
          // make sure that we can go this way
786
          if (ipv4)
719
          if (ipv4)
787
            {
720
            {
788
              uint32_t interfaceIndex = (ipv4)->GetInterfaceForDevice(currNode->GetDevice(i));
721
              uint32_t interfaceIndex = (ipv4)->GetInterfaceForDevice(oif);
789
              if (!(ipv4->IsUp (interfaceIndex)))
722
              if (!(ipv4->IsUp (interfaceIndex)))
790
                {
723
                {
791
                  NS_LOG_LOGIC ("Ipv4Interface is down");
724
                  NS_LOG_LOGIC ("Ipv4Interface is down");
792
                  continue;
725
                  return false;
793
                }
726
                }
794
            }
727
            }
795
            if (!(localNetDevice->IsLinkUp ()))
728
          if (!(oif->IsLinkUp ()))
796
              {
729
            {
797
                NS_LOG_LOGIC ("Link is down.");
730
              NS_LOG_LOGIC ("Link is down.");
798
                continue;
731
              return false;
799
              }
732
            }
800
          Ptr<Channel> channel = localNetDevice->GetChannel ();
733
          Ptr<Channel> channel = oif->GetChannel ();
801
          if (channel == 0)
734
          if (channel == 0)
802
            { 
735
            { 
803
              continue;
736
              return false;
804
            }
737
            }
805
738
806
          // this function takes in the local net dev, and channnel, and
739
          // this function takes in the local net dev, and channnel, and
807
          // writes to the netDeviceContainer the adjacent net devs
740
          // writes to the netDeviceContainer the adjacent net devs
808
          NetDeviceContainer netDeviceContainer;
741
          NetDeviceContainer netDeviceContainer;
809
          GetAdjacentNetDevices (localNetDevice, channel, netDeviceContainer);
742
          GetAdjacentNetDevices (oif, channel, netDeviceContainer);
810
743
811
          // Finally we can get the adjacent nodes
744
          // Finally we can get the adjacent nodes
812
          // and scan through them.  We push them
745
          // and scan through them.  We push them
 Lines 827-832   Ipv4NixVectorRouting::BFS (uint32_t numb Link Here 
827
                }
760
                }
828
            }
761
            }
829
        }
762
        }
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
        }
830
820
831
      // Pop off the head grey node.  We have all its children.
821
      // Pop off the head grey node.  We have all its children.
832
      // It is now black.
822
      // It is now black.
(-)a/src/routing/nix-vector-routing/ipv4-nix-vector-routing.h (-4 / +5 lines)
 Lines 78-86   class Ipv4NixVectorRouting : public Ipv4 Link Here 
78
    void ResetTotalNeighbors (void);
78
    void ResetTotalNeighbors (void);
79
79
80
    /*  takes in the source node and dest IP and calls GetNodeByIp, 
80
    /*  takes in the source node and dest IP and calls GetNodeByIp, 
81
     *  BFS, and BuildNixVector to finally return the built 
81
     *  BFS, accounting for any output interface specified, and finally 
82
     *  nix-vector */
82
     *  BuildNixVector to return the built nix-vector */
83
    Ptr<NixVector> GetNixVector (Ptr<Node>, Ipv4Address);
83
    Ptr<NixVector> GetNixVector (Ptr<Node>, Ipv4Address, Ptr<NetDevice>);
84
84
85
    /* checks the cache based on dest IP for the nix-vector */
85
    /* checks the cache based on dest IP for the nix-vector */
86
    Ptr<NixVector> GetNixVectorInCache (Ipv4Address);
86
    Ptr<NixVector> GetNixVectorInCache (Ipv4Address);
 Lines 124-130   class Ipv4NixVectorRouting : public Ipv4 Link Here 
124
    bool BFS (uint32_t numberOfNodes, 
124
    bool BFS (uint32_t numberOfNodes, 
125
             Ptr<Node> source, 
125
             Ptr<Node> source, 
126
             Ptr<Node> dest, 
126
             Ptr<Node> dest, 
127
             std::vector< Ptr<Node> > & parentVector);
127
             std::vector< Ptr<Node> > & parentVector,
128
             Ptr<NetDevice> oif);
128
129
129
    void DoDispose (void);
130
    void DoDispose (void);
130
131

Return to bug 779