diff -urpN olsr/olsr-repositories.h ../../../ns-3-hna/src/routing/olsr/olsr-repositories.h --- olsr/olsr-repositories.h 2010-01-06 22:36:56.943374016 +0530 +++ ../../../ns-3-hna/src/routing/olsr/olsr-repositories.h 2010-01-24 22:09:50.958715042 +0530 @@ -231,6 +231,60 @@ operator << (std::ostream &os, const Top return os; } +/// Association +struct Association +{ + Ipv4Address networkAddr; + Ipv4Mask netmask; +}; + +static inline bool +operator == (const Association &a, const Association &b) +{ + return (a.networkAddr == b.networkAddr + && a.netmask == b.netmask); +} + +static inline std::ostream& +operator << (std::ostream &os, const Association &tuple) +{ + os << "Association(networkAddr=" << tuple.networkAddr + << ", netmask=" << tuple.netmask + << ")"; + return os; +} + +/// An Association Tuple +struct AssociationTuple +{ + /// Main address of the gateway. + Ipv4Address gatewayAddr; + /// Network Address of network reachable through gatewayAddr + Ipv4Address networkAddr; + /// Netmask of network reachable through gatewayAddr + Ipv4Mask netmask; + /// Time at which this tuple expires and must be removed + Time expirationTime; +}; + +static inline bool +operator == (const AssociationTuple &a, const AssociationTuple &b) +{ + return (a.gatewayAddr == b.gatewayAddr + && a.networkAddr == b.networkAddr + && a.netmask == b.netmask); +} + +static inline std::ostream& +operator << (std::ostream &os, const AssociationTuple &tuple) +{ + os << "AssociationTuple(gatewayAddr=" << tuple.gatewayAddr + << ", networkAddr=" << tuple.networkAddr + << ", netmask=" << tuple.netmask + << ", expirationTime=" << tuple.expirationTime + << ")"; + return os; +} typedef std::set MprSet; ///< MPR Set type. typedef std::vector MprSelectorSet; ///< MPR Selector Set type. @@ -240,6 +294,8 @@ typedef std::vector typedef std::vector TopologySet; ///< Topology Set type. typedef std::vector DuplicateSet; ///< Duplicate Set type. typedef std::vector IfaceAssocSet; ///< Interface Association Set type. +typedef std::vector AssociationSet; ///< Association Set type. +typedef std::vector Associations; ///< Association Set type. }}; // namespace ns3, olsr diff -urpN olsr/olsr-routing-protocol.cc ../../../ns-3-hna/src/routing/olsr/olsr-routing-protocol.cc --- olsr/olsr-routing-protocol.cc 2010-01-06 22:36:56.943374016 +0530 +++ ../../../ns-3-hna/src/routing/olsr/olsr-routing-protocol.cc 2010-01-26 22:59:00.915317402 +0530 @@ -79,6 +79,8 @@ #define OLSR_DUP_HOLD_TIME Seconds (30) /// MID holding time. #define OLSR_MID_HOLD_TIME (Scalar (3) * m_midInterval) +/// HNA holding time. +#define OLSR_HNA_HOLD_TIME (Scalar (3) * m_hnaInterval) /********** Link types **********/ @@ -165,6 +167,10 @@ RoutingProtocol::GetTypeId (void) TimeValue (Seconds (5)), MakeTimeAccessor (&RoutingProtocol::m_midInterval), MakeTimeChecker ()) + .AddAttribute ("HnaInterval", "HNA messages emission interval. Normally it is equal to TcInterval.", + TimeValue (Seconds (5)), + MakeTimeAccessor (&RoutingProtocol::m_hnaInterval), + MakeTimeChecker ()) .AddAttribute ("Willingness", "Willingness of a node to carry and forward traffic for other nodes.", EnumValue (OLSR_WILL_DEFAULT), MakeEnumAccessor (&RoutingProtocol::m_willingness), @@ -189,6 +195,7 @@ RoutingProtocol::RoutingProtocol () m_helloTimer (Timer::CANCEL_ON_DESTROY), m_tcTimer (Timer::CANCEL_ON_DESTROY), m_midTimer (Timer::CANCEL_ON_DESTROY), + m_hnaTimer (Timer::CANCEL_ON_DESTROY), m_queuedMessagesTimer (Timer::CANCEL_ON_DESTROY) {} @@ -204,6 +211,7 @@ RoutingProtocol::SetIpv4 (Ptr ipv4 m_helloTimer.SetFunction (&RoutingProtocol::HelloTimerExpire, this); m_tcTimer.SetFunction (&RoutingProtocol::TcTimerExpire, this); m_midTimer.SetFunction (&RoutingProtocol::MidTimerExpire, this); + m_hnaTimer.SetFunction (&RoutingProtocol::HnaTimerExpire, this); m_queuedMessagesTimer.SetFunction (&RoutingProtocol::SendQueuedMessages, this); m_packetSequenceNumber = OLSR_MAX_SEQ_NUM; @@ -284,6 +292,7 @@ void RoutingProtocol::DoStart () HelloTimerExpire (); TcTimerExpire (); MidTimerExpire (); + HnaTimerExpire (); NS_LOG_DEBUG ("OLSR on node " << m_mainAddress << " started"); } @@ -398,6 +407,12 @@ RoutingProtocol::RecvOlsr (Ptr s ProcessMid (messageHeader, senderIfaceAddr); break; + case olsr::MessageHeader::HNA_MESSAGE: + NS_LOG_DEBUG (Simulator::Now ().GetSeconds () + << "s OLSR node " << m_mainAddress + << " received HNA message of size " << messageHeader.GetSerializedSize ()); + ProcessHna (messageHeader, senderIfaceAddr); + break; default: NS_LOG_DEBUG ("OLSR message type " << int (messageHeader.GetMessageType ()) << @@ -1038,6 +1053,40 @@ RoutingProtocol::RoutingTableComputation entry1.distance); } } + + // 5. For each tuple in the association set, + // If there is no entry in the routing table with: + // R_dest_addr == A_network_addr/A_netmask + // then a new routing entry is created. + const AssociationSet &associationSet = m_state.GetAssociationSet (); + for (AssociationSet::const_iterator it = associationSet.begin (); + it != associationSet.end (); it++) + { + AssociationTuple const &tuple = *it; + RoutingTableEntry entry1, entry2; + + bool have_entry1 = Lookup (tuple.networkAddr.CombineMask (tuple.netmask), entry1); + bool have_entry2 = Lookup (tuple.gatewayAddr, entry2); + bool to_add = false; + + if (!have_entry1) + { + to_add = true; + } + else if(have_entry2 && entry1.distance > entry2.distance) + { + RemoveEntry(tuple.networkAddr.CombineMask (tuple.netmask)); + to_add = true; + } + + if(to_add == true) + { + AddEntry (tuple.networkAddr.CombineMask (tuple.netmask), + entry2.nextAddr, + entry2.interface, + entry2.distance); + } + } NS_LOG_DEBUG ("Node " << m_mainAddress << ": RoutingTableComputation end."); m_routingTableChanged (GetSize ()); @@ -1280,6 +1329,68 @@ RoutingProtocol::ProcessMid (const olsr: NS_LOG_DEBUG ("Node " << m_mainAddress << " ProcessMid from " << senderIface << " -> END."); } +/// +/// \brief Processes a HNA message following RFC 3626 specification. +/// +/// The Host Network Association Set is updated (if needed) with the information +/// of the received HNA message. +/// +/// \param msg the %OLSR message which contains the HNA message. +/// \param sender_iface the address of the interface where the message was sent from. +/// +void +RoutingProtocol::ProcessHna (const olsr::MessageHeader &msg, + const Ipv4Address &senderIface) +{ + const olsr::MessageHeader::Hna &hna = msg.GetHna (); + Time now = Simulator::Now (); + + // 1. If the sender interface of this message is not in the symmetric + // 1-hop neighborhood of this node, the message MUST be discarded. + const LinkTuple *link_tuple = m_state.FindSymLinkTuple (senderIface, now); + if (link_tuple == NULL) + return; + + // 2. Otherwise, for each (network address, netmask) pair in the + // message: + + for (std::vector::const_iterator it = hna.associations.begin(); + it != hna.associations.end() ; it++) + { + AssociationTuple *tuple = m_state.FindAssociationTuple(msg.GetOriginatorAddress(),it->address,it->mask); + + // 2.1 if an entry in the association set already exists, where: + // A_gateway_addr == originator address + // A_network_addr == network address + // A_netmask == netmask + // then the holding time for that tuple MUST be set to: + // A_time = current time + validity time + + if(tuple != NULL) + { + tuple->expirationTime = now + msg.GetVTime (); + } + + // 2.2 otherwise, a new tuple MUST be recorded with: + // A_gateway_addr = originator address + // A_network_addr = network address + // A_netmask = netmask + // A_time = current time + validity time + + else + { + const AssociationTuple &assocTuple = (AssociationTuple){msg.GetOriginatorAddress(),it->address,it->mask,now + msg.GetVTime ()}; + + AddAssociationTuple (assocTuple); + + //Schedule Association Tuple deletion + Simulator::Schedule (DELAY (assocTuple.expirationTime), + &RoutingProtocol::AssociationTupleTimerExpire, this, + assocTuple.gatewayAddr,assocTuple.networkAddr,assocTuple.netmask); + } + + } +} /// /// \brief OLSR's default forwarding algorithm. @@ -1622,6 +1733,47 @@ RoutingProtocol::SendMid () } /// +/// \brief Creates a new %OLSR HNA message which is buffered for being sent later on. +/// +void +RoutingProtocol::SendHna () +{ + olsr::MessageHeader msg; + + msg.SetVTime (OLSR_HNA_HOLD_TIME); + msg.SetOriginatorAddress (m_mainAddress); + msg.SetTimeToLive (255); + msg.SetHopCount (0); + msg.SetMessageSequenceNumber (GetMessageSequenceNumber ()); + olsr::MessageHeader::Hna &hna = msg.GetHna (); + + std::vector + &associations = hna.associations; + + // Pack all host-network associations into the packet's associations vector + for (Associations::const_iterator it = m_state.GetHostNetAssocSet ().begin (); + it != m_state.GetHostNetAssocSet ().end (); it++) + { + associations.push_back((olsr::MessageHeader::Hna::Association){it->networkAddr,it->netmask}); + } + + if(associations.size () == 0) + return; + + QueueMessage (msg, JITTER); +} + +/// +/// \brief Injects a (networkAddr, netmask) tuple for which the node +/// can generate an HNA message for +/// +void +RoutingProtocol::InjectRoute (Ipv4Address networkAddr, Ipv4Mask netmask) +{ + m_state.InsertHostNetAssociation ((Association) {networkAddr, netmask}); +} + +/// /// \brief Updates Link Set according to a new received HELLO message (following RFC 3626 /// specification). Neighbor Set is also updated if needed. void @@ -2301,6 +2453,28 @@ RoutingProtocol::RemoveIfaceAssocTuple ( m_state.EraseIfaceAssocTuple (tuple); } +/// +/// \brief Adds a host network association tuple to the Association Set. +/// +/// \param tuple the host network association tuple to be added. +/// +void +RoutingProtocol::AddAssociationTuple (const AssociationTuple &tuple) +{ + m_state.InsertAssociationTuple (tuple); +} + +/// +/// \brief Removes a host network association tuple from the Association Set. +/// +/// \param tuple the host network association tuple to be removed. +/// +void +RoutingProtocol::RemoveAssociationTuple (const AssociationTuple &tuple) +{ + m_state.EraseAssociationTuple (tuple); +} + uint16_t RoutingProtocol::GetPacketSequenceNumber () { @@ -2347,7 +2521,6 @@ RoutingProtocol::TcTimerExpire () /// /// \brief Sends a MID message (if the node has more than one interface) and resets the MID timer. -/// \warning Currently it does nothing because there is no support for multiple interfaces. /// \param e The event which has expired. /// void @@ -2358,6 +2531,18 @@ RoutingProtocol::MidTimerExpire () } /// +/// \brief Sends an HNA message (if the node implements support for non-OLSR interfaces). +/// \warning Currently it does nothing because there is no support for mixed interfaces. +/// \param e The event which has expired. +/// +void +RoutingProtocol::HnaTimerExpire () +{ + SendHna (); + m_hnaTimer.Schedule (m_hnaInterval); +} + +/// /// \brief Removes tuple if expired. Else timer is rescheduled to expire at tuple.expirationTime. /// /// The task of actually removing the tuple is left to the OLSR agent. @@ -2538,6 +2723,31 @@ RoutingProtocol::IfaceAssocTupleTimerExp } /// +/// \brief Removes tuple_ if expired. Else timer is rescheduled to expire at tuple_->time(). +/// \warning Actually this is never invoked because there is no support for mixed interfaces. +/// \param e The event which has expired. +/// +void +RoutingProtocol::AssociationTupleTimerExpire (Ipv4Address gatewayAddr, Ipv4Address networkAddr, Ipv4Mask netmask) +{ + AssociationTuple *tuple = m_state.FindAssociationTuple (gatewayAddr, networkAddr, netmask); + if (tuple == NULL) + { + return; + } + if (tuple->expirationTime < Simulator::Now ()) + { + RemoveAssociationTuple (*tuple); + } + else + { + m_events.Track (Simulator::Schedule (DELAY (tuple->expirationTime), + &RoutingProtocol::AssociationTupleTimerExpire, + this, gatewayAddr, networkAddr, netmask)); + } +} + +/// /// \brief Clears the routing table and frees the memory assigned to each one of its entries. /// void Binary files olsr/.olsr-routing-protocol.cc.swp and ../../../ns-3-hna/src/routing/olsr/.olsr-routing-protocol.cc.swp differ diff -urpN olsr/olsr-routing-protocol.h ../../../ns-3-hna/src/routing/olsr/olsr-routing-protocol.h --- olsr/olsr-routing-protocol.h 2010-01-06 22:36:56.943374016 +0530 +++ ../../../ns-3-hna/src/routing/olsr/olsr-routing-protocol.h 2010-01-26 18:29:44.295354538 +0530 @@ -123,6 +123,8 @@ private: Time m_tcInterval; /// MID messages' emission interval. Time m_midInterval; + /// HNA messages' emission interval. + Time m_hnaInterval; /// Willingness for forwarding packets on behalf of other nodes. uint8_t m_willingness; @@ -185,6 +187,9 @@ private: Timer m_midTimer; void MidTimerExpire (); + Timer m_hnaTimer; + void HnaTimerExpire (); + void DupTupleTimerExpire (Ipv4Address address, uint16_t sequenceNumber); bool m_linkTupleTimerFirstTime; void LinkTupleTimerExpire (Ipv4Address neighborIfaceAddr); @@ -192,6 +197,7 @@ private: void MprSelTupleTimerExpire (Ipv4Address mainAddr); void TopologyTupleTimerExpire (Ipv4Address destAddr, Ipv4Address lastAddr); void IfaceAssocTupleTimerExpire (Ipv4Address ifaceAddr); + void AssociationTupleTimerExpire (Ipv4Address gatewayAddr, Ipv4Address networkAddr, Ipv4Mask netmask); void IncrementAnsn (); @@ -208,6 +214,7 @@ private: void SendHello (); void SendTc (); void SendMid (); + void SendHna (); void NeighborLoss (const LinkTuple &tuple); void AddDuplicateTuple (const DuplicateTuple &tuple); @@ -225,6 +232,8 @@ private: void RemoveTopologyTuple (const TopologyTuple &tuple); void AddIfaceAssocTuple (const IfaceAssocTuple &tuple); void RemoveIfaceAssocTuple (const IfaceAssocTuple &tuple); + void AddAssociationTuple (const AssociationTuple &tuple); + void RemoveAssociationTuple (const AssociationTuple &tuple); void ProcessHello (const olsr::MessageHeader &msg, const Ipv4Address &receiverIface, @@ -233,6 +242,8 @@ private: const Ipv4Address &senderIface); void ProcessMid (const olsr::MessageHeader &msg, const Ipv4Address &senderIface); + void ProcessHna (const olsr::MessageHeader &msg, + const Ipv4Address &senderIface); void LinkSensing (const olsr::MessageHeader &msg, const olsr::MessageHeader::Hello &hello, @@ -246,6 +257,11 @@ private: const olsr::MessageHeader::Hello &hello); int Degree (NeighborTuple const &tuple); + + /// Inject Route to be sent in HNA message + + void InjectRoute (Ipv4Address networkAddr, Ipv4Mask netmask); + /// Check that address is one of my interfaces bool IsMyOwnAddress (const Ipv4Address & a) const; diff -urpN olsr/olsr-state.cc ../../../ns-3-hna/src/routing/olsr/olsr-state.cc --- olsr/olsr-state.cc 2010-01-06 22:36:56.971354387 +0530 +++ ../../../ns-3-hna/src/routing/olsr/olsr-state.cc 2010-01-26 09:27:50.091632679 +0530 @@ -487,4 +487,61 @@ OlsrState::FindNeighborInterfaces (const return retval; } +/********** Host-Network Association Set Manipulation **********/ + +AssociationTuple* +OlsrState::FindAssociationTuple (const Ipv4Address &gatewayAddr, const Ipv4Address &networkAddr, const Ipv4Mask &netmask) +{ + for (AssociationSet::iterator it = m_associationSet.begin (); + it != m_associationSet.end (); it++) + { + if (it->gatewayAddr == gatewayAddr and it->networkAddr == networkAddr and it->netmask == netmask) + { + return &(*it); + } + } + return NULL; +} + +void +OlsrState::EraseAssociationTuple (const AssociationTuple &tuple) +{ + for (AssociationSet::iterator it = m_associationSet.begin (); + it != m_associationSet.end (); it++) + { + if (*it == tuple) + { + m_associationSet.erase (it); + break; + } + } +} + +void +OlsrState::InsertAssociationTuple (const AssociationTuple &tuple) +{ + m_associationSet.push_back (tuple); +} + + +void +OlsrState::EraseHostNetAssociation (const Association &tuple) +{ + for (Associations::iterator it = m_hostNetAssocSet.begin (); + it != m_hostNetAssocSet.end (); it++) + { + if (*it == tuple) + { + m_hostNetAssocSet.erase (it); + break; + } + } +} + +void +OlsrState::InsertHostNetAssociation (const Association &tuple) +{ + m_hostNetAssocSet.push_back(tuple); +} + } // namespace ns3 diff -urpN olsr/olsr-state.h ../../../ns-3-hna/src/routing/olsr/olsr-state.h --- olsr/olsr-state.h 2010-01-06 22:36:56.923374549 +0530 +++ ../../../ns-3-hna/src/routing/olsr/olsr-state.h 2010-01-26 18:23:57.603208944 +0530 @@ -45,6 +45,8 @@ protected: MprSelectorSet m_mprSelectorSet; ///< MPR Selector Set (RFC 3626, section 4.3.4). DuplicateSet m_duplicateSet; ///< Duplicate Set (RFC 3626, section 3.4). IfaceAssocSet m_ifaceAssocSet; ///< Interface Association Set (RFC 3626, section 4.1). + AssociationSet m_associationSet; ///< Association Set (RFC 3626, section 12.2) + Associations m_hostNetAssocSet; ///< The set of associations a node has public: @@ -147,6 +149,25 @@ public: void EraseIfaceAssocTuple (const IfaceAssocTuple &tuple); void InsertIfaceAssocTuple (const IfaceAssocTuple &tuple); + // Host-Network Association + const AssociationSet & GetAssociationSet () const // Associations known to the node + { + return m_associationSet; + } + + const Associations & GetHostNetAssocSet () const // Set of associations that the node has + { + return m_hostNetAssocSet; + } + + AssociationTuple* FindAssociationTuple (const Ipv4Address &gatewayAddr,\ + const Ipv4Address &networkAddr,\ + const Ipv4Mask &netmask); + void EraseAssociationTuple (const AssociationTuple &tuple); + void InsertAssociationTuple (const AssociationTuple &tuple); + void EraseHostNetAssociation (const Association &tuple); + void InsertHostNetAssociation (const Association &tuple); + // Returns a vector of all interfaces of a given neighbor, with the // exception of the "main" one. std::vector