|
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, if output device, |
| 528 |
// need to do the next 3 lines. |
529 |
// oif, is not specified |
| 529 |
rtentry = GetIpv4RouteInCache (header.GetDestination ()); |
530 |
if (!oif) |
| 530 |
// not in cache |
531 |
{ |
|
|
532 |
rtentry = GetIpv4RouteInCache (header.GetDestination ()); |
| 533 |
} |
| 534 |
// not in cache or a specified output |
| 535 |
// device is to be used |
| 531 |
if (!rtentry) |
536 |
if (!rtentry) |
| 532 |
{ |
537 |
{ |
| 533 |
NS_LOG_LOGIC ("Ipv4Route not in cache, build: "); |
538 |
NS_LOG_LOGIC ("Ipv4Route not in cache, build: "); |
| 534 |
Ipv4Address gatewayIp; |
539 |
Ipv4Address gatewayIp; |
| 535 |
uint32_t index = FindNetDeviceForNixIndex (nodeIndex, gatewayIp); |
540 |
uint32_t index = FindNetDeviceForNixIndex (nodeIndex, gatewayIp); |
|
|
541 |
int32_t interfaceIndex = 0; |
| 536 |
|
542 |
|
| 537 |
uint32_t interfaceIndex = (m_ipv4)->GetInterfaceForDevice(m_node->GetDevice(index)); |
543 |
if (!oif) |
|
|
544 |
{ |
| 545 |
interfaceIndex = (m_ipv4)->GetInterfaceForDevice(m_node->GetDevice(index)); |
| 546 |
} |
| 547 |
else |
| 548 |
{ |
| 549 |
interfaceIndex = (m_ipv4)->GetInterfaceForDevice(oif); |
| 550 |
} |
| 551 |
|
| 552 |
NS_ASSERT_MSG (interfaceIndex != -1, "Interface index not found for device"); |
| 553 |
|
| 538 |
Ipv4InterfaceAddress ifAddr = m_ipv4->GetAddress (interfaceIndex, 0); |
554 |
Ipv4InterfaceAddress ifAddr = m_ipv4->GetAddress (interfaceIndex, 0); |
| 539 |
|
555 |
|
| 540 |
// start filling in the Ipv4Route info |
556 |
// start filling in the Ipv4Route info |
|
Lines 543-549
Ipv4NixVectorRouting::RouteOutput (Ptr<P
|
Link Here
|
|---|
|
| 543 |
|
559 |
|
| 544 |
rtentry->SetGateway (gatewayIp); |
560 |
rtentry->SetGateway (gatewayIp); |
| 545 |
rtentry->SetDestination (header.GetDestination ()); |
561 |
rtentry->SetDestination (header.GetDestination ()); |
| 546 |
rtentry->SetOutputDevice (m_ipv4->GetNetDevice (interfaceIndex)); |
562 |
|
|
|
563 |
if (!oif) |
| 564 |
{ |
| 565 |
rtentry->SetOutputDevice (m_ipv4->GetNetDevice (interfaceIndex)); |
| 566 |
} |
| 567 |
else |
| 568 |
{ |
| 569 |
rtentry->SetOutputDevice (oif); |
| 570 |
} |
| 547 |
|
571 |
|
| 548 |
sockerr = Socket::ERROR_NOTERROR; |
572 |
sockerr = Socket::ERROR_NOTERROR; |
| 549 |
|
573 |
|
|
Lines 582-724
Ipv4NixVectorRouting::RouteInput (Ptr<co
|
Link Here
|
|---|
|
| 582 |
// Get the nix-vector from the packet |
606 |
// Get the nix-vector from the packet |
| 583 |
Ptr<NixVector> nixVector = p->GetNixVector(); |
607 |
Ptr<NixVector> nixVector = p->GetNixVector(); |
| 584 |
|
608 |
|
| 585 |
// make sure it exists, if not something |
609 |
// If nixVector isn't in packet, something went wrong |
| 586 |
// went wrong |
610 |
NS_ASSERT (nixVector); |
| 587 |
if (!nixVector) |
611 |
|
|
|
612 |
// Get the interface number that we go out of, by extracting |
| 613 |
// from the nix-vector |
| 614 |
if (m_totalNeighbors == 0) |
| 588 |
{ |
615 |
{ |
| 589 |
NS_LOG_ERROR ("Nix-vector wasn't in the packet! Rebuild."); |
616 |
m_totalNeighbors = FindTotalNeighbors (); |
|
|
617 |
} |
| 618 |
uint32_t numberOfBits = nixVector->BitCount (m_totalNeighbors); |
| 619 |
uint32_t nodeIndex = nixVector->ExtractNeighborIndex (numberOfBits); |
| 590 |
|
620 |
|
| 591 |
Ptr<NixVector> nixVectorInCache; |
621 |
rtentry = GetIpv4RouteInCache (header.GetDestination ()); |
|
|
622 |
// not in cache |
| 623 |
if (!rtentry) |
| 624 |
{ |
| 625 |
NS_LOG_LOGIC ("Ipv4Route not in cache, build: "); |
| 626 |
Ipv4Address gatewayIp; |
| 627 |
uint32_t index = FindNetDeviceForNixIndex (nodeIndex, gatewayIp); |
| 628 |
uint32_t interfaceIndex = (m_ipv4)->GetInterfaceForDevice(m_node->GetDevice(index)); |
| 629 |
Ipv4InterfaceAddress ifAddr = m_ipv4->GetAddress (interfaceIndex, 0); |
| 592 |
|
630 |
|
| 593 |
NS_LOG_DEBUG ("Dest IP from header: " << header.GetDestination ()); |
631 |
// start filling in the Ipv4Route info |
|
|
632 |
rtentry = Create<Ipv4Route> (); |
| 633 |
rtentry->SetSource (ifAddr.GetLocal ()); |
| 594 |
|
634 |
|
| 595 |
// check if cache |
635 |
rtentry->SetGateway (gatewayIp); |
| 596 |
nixVectorInCache = GetNixVectorInCache(header.GetDestination ()); |
636 |
rtentry->SetDestination (header.GetDestination ()); |
|
|
637 |
rtentry->SetOutputDevice (m_ipv4->GetNetDevice (interfaceIndex)); |
| 597 |
|
638 |
|
| 598 |
// not in cache |
639 |
// add rtentry to cache |
| 599 |
if (!nixVectorInCache) |
640 |
m_ipv4RouteCache.insert(Ipv4RouteMap_t::value_type(header.GetDestination (), rtentry)); |
| 600 |
{ |
641 |
} |
| 601 |
NS_LOG_LOGIC ("RouteInput(): Nix-vector not in cache, build: "); |
|
|
| 602 |
|
642 |
|
| 603 |
// Build the nix-vector, given this node and the |
643 |
NS_LOG_LOGIC ("At Node " << m_node->GetId() << ", Extracting " << numberOfBits << |
| 604 |
// dest IP address |
644 |
" bits from Nix-vector: " << nixVector << " : " << *nixVector); |
| 605 |
nixVectorInCache = GetNixVector (m_node, header.GetDestination ()); |
|
|
| 606 |
} |
| 607 |
|
645 |
|
| 608 |
// path exists |
646 |
// call the unicast callback |
| 609 |
if (nixVectorInCache) |
647 |
// local deliver is handled by Ipv4StaticRoutingImpl |
| 610 |
{ |
648 |
// so this code is never even called if the packet is |
| 611 |
NS_LOG_LOGIC ("Nix-vector contents: " << *nixVectorInCache); |
649 |
// destined for this node. |
|
|
650 |
ucb (rtentry, p, header); |
| 612 |
|
651 |
|
| 613 |
// cache it |
652 |
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 |
} |
653 |
} |
| 723 |
|
654 |
|
| 724 |
// virtual functions from Ipv4RoutingProtocol |
655 |
// virtual functions from Ipv4RoutingProtocol |
|
Lines 744-750
Ipv4NixVectorRouting::NotifyRemoveAddres
|
Link Here
|
|---|
|
| 744 |
} |
675 |
} |
| 745 |
|
676 |
|
| 746 |
bool |
677 |
bool |
| 747 |
Ipv4NixVectorRouting::BFS (uint32_t numberOfNodes, Ptr<Node> source, Ptr<Node> dest, std::vector< Ptr<Node> > & parentVector) |
678 |
Ipv4NixVectorRouting::BFS (uint32_t numberOfNodes, Ptr<Node> source, |
|
|
679 |
Ptr<Node> dest, std::vector< Ptr<Node> > & parentVector, |
| 680 |
Ptr<NetDevice> oif) |
| 748 |
{ |
681 |
{ |
| 749 |
NS_LOG_FUNCTION_NOARGS (); |
682 |
NS_LOG_FUNCTION_NOARGS (); |
| 750 |
|
683 |
|
|
Lines 772-812
Ipv4NixVectorRouting::BFS (uint32_t numb
|
Link Here
|
|---|
|
| 772 |
return true; |
705 |
return true; |
| 773 |
} |
706 |
} |
| 774 |
|
707 |
|
| 775 |
|
708 |
// if this is the first iteration of the loop and a |
| 776 |
// Iterate over the current node's adjacent vertices |
709 |
// specific output interface was given, make sure |
| 777 |
// and push them into the queue |
710 |
// we go this way |
| 778 |
for (uint32_t i = 0; i < (currNode->GetNDevices ()); i++) |
711 |
if (currNode == source && oif) |
| 779 |
{ |
712 |
{ |
| 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 |
713 |
// make sure that we can go this way |
| 786 |
if (ipv4) |
714 |
if (ipv4) |
| 787 |
{ |
715 |
{ |
| 788 |
uint32_t interfaceIndex = (ipv4)->GetInterfaceForDevice(currNode->GetDevice(i)); |
716 |
uint32_t interfaceIndex = (ipv4)->GetInterfaceForDevice(oif); |
| 789 |
if (!(ipv4->IsUp (interfaceIndex))) |
717 |
if (!(ipv4->IsUp (interfaceIndex))) |
| 790 |
{ |
718 |
{ |
| 791 |
NS_LOG_LOGIC ("Ipv4Interface is down"); |
719 |
NS_LOG_LOGIC ("Ipv4Interface is down"); |
| 792 |
continue; |
720 |
return false; |
| 793 |
} |
721 |
} |
| 794 |
} |
722 |
} |
| 795 |
if (!(localNetDevice->IsLinkUp ())) |
723 |
if (!(oif->IsLinkUp ())) |
| 796 |
{ |
724 |
{ |
| 797 |
NS_LOG_LOGIC ("Link is down."); |
725 |
NS_LOG_LOGIC ("Link is down."); |
| 798 |
continue; |
726 |
return false; |
| 799 |
} |
727 |
} |
| 800 |
Ptr<Channel> channel = localNetDevice->GetChannel (); |
728 |
Ptr<Channel> channel = oif->GetChannel (); |
| 801 |
if (channel == 0) |
729 |
if (channel == 0) |
| 802 |
{ |
730 |
{ |
| 803 |
continue; |
731 |
return false; |
| 804 |
} |
732 |
} |
| 805 |
|
733 |
|
| 806 |
// this function takes in the local net dev, and channnel, and |
734 |
// this function takes in the local net dev, and channnel, and |
| 807 |
// writes to the netDeviceContainer the adjacent net devs |
735 |
// writes to the netDeviceContainer the adjacent net devs |
| 808 |
NetDeviceContainer netDeviceContainer; |
736 |
NetDeviceContainer netDeviceContainer; |
| 809 |
GetAdjacentNetDevices (localNetDevice, channel, netDeviceContainer); |
737 |
GetAdjacentNetDevices (oif, channel, netDeviceContainer); |
| 810 |
|
738 |
|
| 811 |
// Finally we can get the adjacent nodes |
739 |
// Finally we can get the adjacent nodes |
| 812 |
// and scan through them. We push them |
740 |
// and scan through them. We push them |
|
Lines 827-832
Ipv4NixVectorRouting::BFS (uint32_t numb
|
Link Here
|
|---|
|
| 827 |
} |
755 |
} |
| 828 |
} |
756 |
} |
| 829 |
} |
757 |
} |
|
|
758 |
else |
| 759 |
{ |
| 760 |
// Iterate over the current node's adjacent vertices |
| 761 |
// and push them into the queue |
| 762 |
for (uint32_t i = 0; i < (currNode->GetNDevices ()); i++) |
| 763 |
{ |
| 764 |
// Get a net device from the node |
| 765 |
// as well as the channel, and figure |
| 766 |
// out the adjacent net device |
| 767 |
Ptr<NetDevice> localNetDevice = currNode->GetDevice (i); |
| 768 |
|
| 769 |
// make sure that we can go this way |
| 770 |
if (ipv4) |
| 771 |
{ |
| 772 |
uint32_t interfaceIndex = (ipv4)->GetInterfaceForDevice(currNode->GetDevice(i)); |
| 773 |
if (!(ipv4->IsUp (interfaceIndex))) |
| 774 |
{ |
| 775 |
NS_LOG_LOGIC ("Ipv4Interface is down"); |
| 776 |
continue; |
| 777 |
} |
| 778 |
} |
| 779 |
if (!(localNetDevice->IsLinkUp ())) |
| 780 |
{ |
| 781 |
NS_LOG_LOGIC ("Link is down."); |
| 782 |
continue; |
| 783 |
} |
| 784 |
Ptr<Channel> channel = localNetDevice->GetChannel (); |
| 785 |
if (channel == 0) |
| 786 |
{ |
| 787 |
continue; |
| 788 |
} |
| 789 |
|
| 790 |
// this function takes in the local net dev, and channnel, and |
| 791 |
// writes to the netDeviceContainer the adjacent net devs |
| 792 |
NetDeviceContainer netDeviceContainer; |
| 793 |
GetAdjacentNetDevices (localNetDevice, channel, netDeviceContainer); |
| 794 |
|
| 795 |
// Finally we can get the adjacent nodes |
| 796 |
// and scan through them. We push them |
| 797 |
// to the greyNode queue, if they aren't |
| 798 |
// already there. |
| 799 |
for (NetDeviceContainer::Iterator iter = netDeviceContainer.Begin (); iter != netDeviceContainer.End (); iter++) |
| 800 |
{ |
| 801 |
Ptr<Node> remoteNode = (*iter)->GetNode (); |
| 802 |
|
| 803 |
// check to see if this node has been pushed before |
| 804 |
// by checking to see if it has a parent |
| 805 |
// if it doesn't (null or 0), then set its parent and |
| 806 |
// push to the queue |
| 807 |
if (parentVector.at (remoteNode->GetId ()) == 0) |
| 808 |
{ |
| 809 |
parentVector.at (remoteNode->GetId ()) = currNode; |
| 810 |
greyNodeList.push (remoteNode); |
| 811 |
} |
| 812 |
} |
| 813 |
} |
| 814 |
} |
| 830 |
|
815 |
|
| 831 |
// Pop off the head grey node. We have all its children. |
816 |
// Pop off the head grey node. We have all its children. |
| 832 |
// It is now black. |
817 |
// It is now black. |