--- a/src/routing/olsr/model/olsr-routing-protocol.cc Wed Feb 09 16:16:39 2011 +0000
+++ b/src/routing/olsr/model/olsr-routing-protocol.cc Tue Feb 15 17:19:13 2011 +0000
@@ -248,14 +248,14 @@
void
RoutingProtocol::PrintRoutingTable (Ptr<OutputStreamWrapper> stream) const
{
- std::ostream* os = stream->GetStream();
- *os << "Destination\tNextHop\t\tInterface\tDistance\n";
+ std::ostream* os = stream->GetStream ();
+ *os << "Destination\t\tNextHop\t\tInterface\tDistance\n";
for (std::map<Ipv4Address, RoutingTableEntry>::const_iterator iter = m_table.begin ();
iter != m_table.end (); iter++)
{
- *os << iter->first << "\t";
- *os << iter->second.nextAddr << "\t";
+ *os << iter->first << "\t\t";
+ *os << iter->second.nextAddr << "\t\t";
if (Names::FindName (m_ipv4->GetNetDevice (iter->second.interface)) != "")
{
*os << Names::FindName (m_ipv4->GetNetDevice (iter->second.interface)) << "\t\t";
@@ -264,10 +264,12 @@
{
*os << iter->second.interface << "\t\t";
}
-
*os << iter->second.distance << "\t";
*os << "\n";
}
+ // Also print the HNA routing table
+ *os << " HNA Routing Table:\n";
+ m_hnaRoutingTable->PrintRoutingTable (stream);
}
void RoutingProtocol::DoStart ()
@@ -1105,12 +1107,36 @@
// 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
+ // and if the announced network is not announced by the node itself,
// 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;
+
+ // Test if HNA associations received from other gateways
+ // are also announced by this node. In such a case, no route
+ // is created for this association tuple (go to the next one).
+ bool goToNextAssociationTuple = false;
+ const Associations &localHnaAssociations = m_state.GetAssociations ();
+ NS_LOG_DEBUG ("Nb local associations: " << localHnaAssociations.size ());
+ for (Associations::const_iterator assocIterator = localHnaAssociations.begin ();
+ assocIterator != localHnaAssociations.end (); assocIterator++)
+ {
+ Association const &localHnaAssoc = *assocIterator;
+ if (localHnaAssoc.networkAddr == tuple.networkAddr && localHnaAssoc.netmask == tuple.netmask)
+ {
+ NS_LOG_DEBUG ("HNA association received from another GW is part of local HNA associations: no route added for network "
+ << tuple.networkAddr << "/" << tuple.netmask);
+ goToNextAssociationTuple = true;
+ }
+ }
+ if (goToNextAssociationTuple)
+ {
+ continue;
+ }
+
RoutingTableEntry gatewayEntry;
bool gatewayEntryExists = Lookup (tuple.gatewayAddr, gatewayEntry);
@@ -1820,76 +1846,132 @@
msg.SetMessageSequenceNumber (GetMessageSequenceNumber ());
olsr::MessageHeader::Hna &hna = msg.GetHna ();
- std::vector<olsr::MessageHeader::Hna::Association>
- &associations = hna.associations;
-
- if (m_routingTableAssociation != 0)
- {
- // Add (NetworkAddr, Netmask) entries from Associated Routing Table to HNA message.
- for (uint32_t i = 0; i < m_routingTableAssociation->GetNRoutes (); i++)
- {
- Ipv4RoutingTableEntry route = m_routingTableAssociation->GetRoute (i);
-
- std::set<uint32_t>::const_iterator ci = m_interfaceExclusions.find (route.GetInterface ());
+ std::vector<olsr::MessageHeader::Hna::Association> &associations = hna.associations;
- if (ci != m_interfaceExclusions.end ())
+ // Add all local HNA associations to the HNA message
+ const Associations &localHnaAssociations = m_state.GetAssociations ();
+ for (Associations::const_iterator it = localHnaAssociations.begin ();
+ it != localHnaAssociations.end (); it++)
{
- olsr::MessageHeader::Hna::Association assoc = {route.GetDestNetwork (), route.GetDestNetworkMask ()};
- associations.push_back(assoc);
- }
- }
+ olsr::MessageHeader::Hna::Association assoc = {it->networkAddr, it->netmask};
+ associations.push_back (assoc);
}
-
- int size = associations.size ();
-
- // Add (NetworkAddr, Netmask) entries specified using AddHostNetworkAssociation () to HNA message.
- for (Associations::const_iterator it = m_state.GetAssociations ().begin ();
- it != m_state.GetAssociations ().end (); it++)
+ // If there is no HNA associations to send, return without queuing the message
+ if (associations.size () == 0)
{
- // Check if the entry has already been added from the Associated Routing Table
- std::vector<olsr::MessageHeader::Hna::Association>::const_iterator ci = associations.begin ();
- bool found = false;
- for (int i = 0; i < size; i++)
- {
- if (it->networkAddr == ci->address && it->netmask == ci->mask)
- {
- found = true;
- break;
- }
- ci++;
- }
-
- if(!found)
- {
- olsr::MessageHeader::Hna::Association assoc = {it->networkAddr,it->netmask};
- associations.push_back(assoc);
- }
+ return;
}
-
- if(associations.size () == 0)
- return;
+ // Else, queue the message to be sent later on
QueueMessage (msg, JITTER);
}
///
-/// \brief Injects a (networkAddr, netmask) tuple for which the node
-/// can generate an HNA message for
+/// \brief Injects the specified (networkAddr, netmask) tuple in the list of
+/// local HNA associations to be sent by the node via HNA messages.
+/// If this tuple already exists, nothing is done.
///
void
RoutingProtocol::AddHostNetworkAssociation (Ipv4Address networkAddr, Ipv4Mask netmask)
{
- m_state.InsertAssociation ((Association) {networkAddr, netmask});
+ // Check if the (networkAddr, netmask) tuple already exist
+ // in the list of local HNA associations
+ const Associations &localHnaAssociations = m_state.GetAssociations ();
+ for (Associations::const_iterator assocIterator = localHnaAssociations.begin ();
+ assocIterator != localHnaAssociations.end (); assocIterator++)
+ {
+ Association const &localHnaAssoc = *assocIterator;
+ if (localHnaAssoc.networkAddr == networkAddr && localHnaAssoc.netmask == netmask)
+ {
+ NS_LOG_INFO ("HNA association for network " << networkAddr << "/" << netmask << " already exists.");
+ return;
+ }
+ }
+ // If the tuple does not already exist, add it to the list of local HNA associations.
+ NS_LOG_INFO ("Adding HNA association for network " << networkAddr << "/" << netmask << ".");
+ m_state.InsertAssociation ( (Association) {networkAddr, netmask} );
}
///
-/// \brief Adds an Ipv4StaticRouting protocol Association
-/// can generate an HNA message for
+/// \brief Removes the specified (networkAddr, netmask) tuple from the list of
+/// local HNA associations to be sent by the node via HNA messages.
+/// If this tuple does not exist, nothing is done (see "OlsrState::EraseAssociation()").
+///
+void
+RoutingProtocol::RemoveHostNetworkAssociation (Ipv4Address networkAddr, Ipv4Mask netmask)
+{
+ NS_LOG_INFO ("Removing HNA association for network " << networkAddr << "/" << netmask << ".");
+ m_state.EraseAssociation ( (Association) {networkAddr, netmask} );
+}
+
+///
+/// \brief Associates the specified Ipv4StaticRouting routing table
+/// to the OLSR routing protocol. Entries from this associated
+/// routing table that use non-olsr outgoing interfaces are added
+/// to the list of local HNA associations so that they are included
+/// in HNA messages sent by the node.
+/// If this method is called more than once, entries from the old
+/// association are deleted before entries from the new one are added.
+/// \param the Ipv4StaticRouting routing table to be associated.
///
void
RoutingProtocol::SetRoutingTableAssociation (Ptr<Ipv4StaticRouting> routingTable)
{
+ // If a routing table has already been associated, remove
+ // corresponding entries from the list of local HNA associations
+ if (m_routingTableAssociation != 0)
+ {
+ NS_LOG_INFO ("Removing HNA entries coming from the old routing table association.");
+ for (uint32_t i = 0; i < m_routingTableAssociation->GetNRoutes (); i++)
+ {
+ Ipv4RoutingTableEntry route = m_routingTableAssociation->GetRoute (i);
+ // If the outgoing interface for this route is a non-olsr interface
+ if (UsesNonOlsrOutgoingInterface (route))
+ {
+ // remove the corresponding entry
+ RemoveHostNetworkAssociation (route.GetDestNetwork (), route.GetDestNetworkMask ());
+ }
+ }
+ }
+
+ // Sets the routingTableAssociation to its new value
m_routingTableAssociation = routingTable;
+
+ // Iterate over entries of the associated routing table and
+ // add the routes using non-olsr outgoing interfaces to the list
+ // of local HNA associations
+ const Associations &localHnaAssociations = m_state.GetAssociations (); // Just for logging
+ NS_LOG_DEBUG ("Nb local associations before adding some entries from"
+ " the associated routing table: " << localHnaAssociations.size ());
+ for (uint32_t i = 0; i < m_routingTableAssociation->GetNRoutes (); i++)
+ {
+ Ipv4RoutingTableEntry route = m_routingTableAssociation->GetRoute (i);
+ Ipv4Address destNetworkAddress = route.GetDestNetwork ();
+ Ipv4Mask destNetmask = route.GetDestNetworkMask ();
+
+ // If the outgoing interface for this route is a non-olsr interface,
+ if (UsesNonOlsrOutgoingInterface (route))
+ {
+ // Add this entry's network address and netmask to the list of local HNA entries
+ AddHostNetworkAssociation (destNetworkAddress, destNetmask);
+ }
+ }
+ NS_LOG_DEBUG ("Nb local associations after having added some entries from "
+ "the associated routing table: " << localHnaAssociations.size ());
+}
+
+///
+/// \brief Tests whether or not the specified route uses a non-OLSR outgoing interface.
+/// Returns true if the outgoing interface of the specified route is a non-OLSR interface.
+/// Returns false otherwise.
+///
+bool
+RoutingProtocol::UsesNonOlsrOutgoingInterface (const Ipv4RoutingTableEntry &route)
+{
+ std::set<uint32_t>::const_iterator ci = m_interfaceExclusions.find (route.GetInterface ());
+ // The outgoing interface is a non-OLSR interface if a match is found
+ // before reaching the end of the list of excluded interfaces
+ return ci != m_interfaceExclusions.end ();
}
///
@@ -2652,12 +2734,11 @@
///
/// \brief Sends an HNA message (if the node has associated hosts/networks) and reschedules the HNA timer.
-/// \param e The event which has expired.
///
void
RoutingProtocol::HnaTimerExpire ()
{
- if (m_state.GetAssociations ().size () > 0 || m_routingTableAssociation !=0)
+ if (m_state.GetAssociations ().size () > 0)
{
SendHna ();
}
--- a/src/routing/olsr/model/olsr-routing-protocol.h Wed Feb 09 16:16:39 2011 +0000
+++ b/src/routing/olsr/model/olsr-routing-protocol.h Tue Feb 15 17:19:13 2011 +0000
@@ -1,6 +1,6 @@
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
/*
- * Copyright (c) 2004 Francisco J. Ros
+ * Copyright (c) 2004 Francisco J. Ros
* Copyright (c) 2007 INESC Porto
*
* This program is free software; you can redistribute it and/or modify
@@ -89,16 +89,16 @@
///
/// \brief Set the OLSR main address to the first address on the indicated
- /// interface
+ /// interface
/// \param interface IPv4 interface index
///
void SetMainInterface (uint32_t interface);
- ///
+ ///
/// Dump the neighbor table, two-hop neighbor table, and routing table
/// to logging output (NS_LOG_DEBUG log level). If logging is disabled,
/// this function does nothing.
- ///
+ ///
void Dump (void);
/**
@@ -119,6 +119,8 @@
/// Inject Association to be sent in HNA message
void AddHostNetworkAssociation (Ipv4Address networkAddr, Ipv4Mask netmask);
+ /// Removes Association sent in HNA message
+ void RemoveHostNetworkAssociation (Ipv4Address networkAddr, Ipv4Mask netmask);
/// Inject Associations from an Ipv4StaticRouting instance
void SetRoutingTableAssociation (Ptr<Ipv4StaticRouting> routingTable);
@@ -149,12 +151,12 @@
Time m_hnaInterval;
/// Willingness for forwarding packets on behalf of other nodes.
uint8_t m_willingness;
-
+
/// Internal state with all needed data structs.
OlsrState m_state;
Ptr<Ipv4> m_ipv4;
-
+
void Clear ();
uint32_t GetSize () const { return m_table.size (); }
void RemoveEntry (const Ipv4Address &dest);
@@ -172,10 +174,17 @@
RoutingTableEntry &outEntry) const;
// From Ipv4RoutingProtocol
- virtual Ptr<Ipv4Route> RouteOutput (Ptr<Packet> p, const Ipv4Header &header, Ptr<NetDevice> oif, Socket::SocketErrno &sockerr);
- virtual bool RouteInput (Ptr<const Packet> p, const Ipv4Header &header, Ptr<const NetDevice> idev,
- UnicastForwardCallback ucb, MulticastForwardCallback mcb,
- LocalDeliverCallback lcb, ErrorCallback ecb);
+ virtual Ptr<Ipv4Route> RouteOutput (Ptr<Packet> p,
+ const Ipv4Header &header,
+ Ptr<NetDevice> oif,
+ Socket::SocketErrno &sockerr);
+ virtual bool RouteInput (Ptr<const Packet> p,
+ const Ipv4Header &header,
+ Ptr<const NetDevice> idev,
+ UnicastForwardCallback ucb,
+ MulticastForwardCallback mcb,
+ LocalDeliverCallback lcb,
+ ErrorCallback ecb);
virtual void NotifyInterfaceUp (uint32_t interface);
virtual void NotifyInterfaceDown (uint32_t interface);
virtual void NotifyAddAddress (uint32_t interface, Ipv4InterfaceAddress address);
@@ -183,26 +192,26 @@
virtual void SetIpv4 (Ptr<Ipv4> ipv4);
virtual void PrintRoutingTable (Ptr<OutputStreamWrapper> stream) const;
-
void DoDispose ();
void SendPacket (Ptr<Packet> packet, const MessageList &containedMessages);
-
+
/// Increments packet sequence number and returns the new value.
inline uint16_t GetPacketSequenceNumber ();
/// Increments message sequence number and returns the new value.
inline uint16_t GetMessageSequenceNumber ();
-
+
void RecvOlsr (Ptr<Socket> socket);
void MprComputation ();
void RoutingTableComputation ();
Ipv4Address GetMainAddress (Ipv4Address iface_addr) const;
+ bool UsesNonOlsrOutgoingInterface (const Ipv4RoutingTableEntry &route);
// Timer handlers
Timer m_helloTimer;
void HelloTimerExpire ();
-
+
Timer m_tcTimer;
void TcTimerExpire ();