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) |
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 } |