Bug 407 - OLSR is missing HNA support
This commit is contained in:
263
examples/routing/olsr-hna.cc
Normal file
263
examples/routing/olsr-hna.cc
Normal file
@@ -0,0 +1,263 @@
|
||||
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation;
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
|
||||
//
|
||||
// This script, adapted from examples/wireless/wifi-simple-adhoc illustrates
|
||||
// the use of OLSR HNA.
|
||||
//
|
||||
// Network Topology:
|
||||
//
|
||||
// |------ OLSR ------| |---- non-OLSR ----|
|
||||
// A )))) (((( B ------------------- C
|
||||
// 10.1.1.1 10.1.1.2 172.16.1.2 172.16.1.1
|
||||
//
|
||||
// Node A needs to send a UDP packet to node C. This can be done only after
|
||||
// A receives an HNA message from B, in which B announces 172.16.1.0/24
|
||||
// as an associated network.
|
||||
//
|
||||
// If no HNA message is generated by B, a will not be able to form a route to C.
|
||||
// This can be verified as follows:
|
||||
//
|
||||
// ./waf --run olsr-hna
|
||||
//
|
||||
// There are two ways to make a node to generate HNA messages.
|
||||
//
|
||||
// One way is to use olsr::RoutingProtocol::SetRoutingTableAssociation ()
|
||||
// to use which you may run:
|
||||
//
|
||||
// ./waf --run "olsr-hna --assocMethod1=1"
|
||||
//
|
||||
// The other way is to use olsr::RoutingProtocol::AddHostNetworkAssociation ()
|
||||
// to use which you may run:
|
||||
//
|
||||
// ./waf --run "olsr-hna --assocMethod2=1"
|
||||
//
|
||||
|
||||
#include "ns3/core-module.h"
|
||||
#include "ns3/common-module.h"
|
||||
#include "ns3/node-module.h"
|
||||
#include "ns3/helper-module.h"
|
||||
#include "ns3/mobility-module.h"
|
||||
#include "ns3/contrib-module.h"
|
||||
#include "ns3/wifi-module.h"
|
||||
#include "ns3/ipv4-list-routing.h"
|
||||
#include "ns3/olsr-routing-protocol.h"
|
||||
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
NS_LOG_COMPONENT_DEFINE ("OlsrHna");
|
||||
|
||||
using namespace ns3;
|
||||
|
||||
void ReceivePacket (Ptr<Socket> socket)
|
||||
{
|
||||
NS_LOG_UNCOND ("Received one packet!");
|
||||
}
|
||||
|
||||
static void GenerateTraffic (Ptr<Socket> socket, uint32_t pktSize,
|
||||
uint32_t pktCount, Time pktInterval )
|
||||
{
|
||||
if (pktCount > 0)
|
||||
{
|
||||
socket->Send (Create<Packet> (pktSize));
|
||||
Simulator::Schedule (pktInterval, &GenerateTraffic,
|
||||
socket, pktSize,pktCount-1, pktInterval);
|
||||
}
|
||||
else
|
||||
{
|
||||
socket->Close ();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int main (int argc, char *argv[])
|
||||
{
|
||||
std::string phyMode ("wifib-1mbs");
|
||||
double rss = -80; // -dBm
|
||||
uint32_t packetSize = 1000; // bytes
|
||||
uint32_t numPackets = 1;
|
||||
double interval = 1.0; // seconds
|
||||
bool verbose = false;
|
||||
bool assocMethod1 = false;
|
||||
bool assocMethod2 = false;
|
||||
|
||||
CommandLine cmd;
|
||||
|
||||
cmd.AddValue ("phyMode", "Wifi Phy mode", phyMode);
|
||||
cmd.AddValue ("rss", "received signal strength", rss);
|
||||
cmd.AddValue ("packetSize", "size of application packet sent", packetSize);
|
||||
cmd.AddValue ("numPackets", "number of packets generated", numPackets);
|
||||
cmd.AddValue ("interval", "interval (seconds) between packets", interval);
|
||||
cmd.AddValue ("verbose", "turn on all WifiNetDevice log components", verbose);
|
||||
cmd.AddValue ("assocMethod1", "Use SetRoutingTableAssociation () method", assocMethod1);
|
||||
cmd.AddValue ("assocMethod2", "Use AddHostNetworkAssociation () method", assocMethod2);
|
||||
|
||||
cmd.Parse (argc, argv);
|
||||
// Convert to time object
|
||||
Time interPacketInterval = Seconds (interval);
|
||||
|
||||
// disable fragmentation for frames below 2200 bytes
|
||||
Config::SetDefault ("ns3::WifiRemoteStationManager::FragmentationThreshold", StringValue ("2200"));
|
||||
// turn off RTS/CTS for frames below 2200 bytes
|
||||
Config::SetDefault ("ns3::WifiRemoteStationManager::RtsCtsThreshold", StringValue ("2200"));
|
||||
// Fix non-unicast data rate to be the same as that of unicast
|
||||
Config::SetDefault ("ns3::WifiRemoteStationManager::NonUnicastMode",
|
||||
StringValue (phyMode));
|
||||
|
||||
NodeContainer olsrNodes;
|
||||
olsrNodes.Create (2);
|
||||
|
||||
NodeContainer csmaNodes;
|
||||
csmaNodes.Create (1);
|
||||
|
||||
// The below set of helpers will help us to put together the wifi NICs we want
|
||||
WifiHelper wifi;
|
||||
if (verbose)
|
||||
{
|
||||
wifi.EnableLogComponents (); // Turn on all Wifi logging
|
||||
}
|
||||
wifi.SetStandard (WIFI_PHY_STANDARD_80211b);
|
||||
|
||||
YansWifiPhyHelper wifiPhy = YansWifiPhyHelper::Default ();
|
||||
// This is one parameter that matters when using FixedRssLossModel
|
||||
// set it to zero; otherwise, gain will be added
|
||||
wifiPhy.Set ("RxGain", DoubleValue (0) );
|
||||
// ns-3 supports RadioTap and Prism tracing extensions for 802.11b
|
||||
wifiPhy.SetPcapDataLinkType (YansWifiPhyHelper::DLT_IEEE802_11_RADIO);
|
||||
|
||||
YansWifiChannelHelper wifiChannel ;
|
||||
wifiChannel.SetPropagationDelay ("ns3::ConstantSpeedPropagationDelayModel");
|
||||
// The below FixedRssLossModel will cause the rss to be fixed regardless
|
||||
// of the distance between the two stations, and the transmit power
|
||||
wifiChannel.AddPropagationLoss ("ns3::FixedRssLossModel","Rss",DoubleValue(rss));
|
||||
wifiPhy.SetChannel (wifiChannel.Create ());
|
||||
|
||||
// Add a non-QoS upper mac, and disable rate control
|
||||
NqosWifiMacHelper wifiMac = NqosWifiMacHelper::Default ();
|
||||
wifi.SetRemoteStationManager ("ns3::ConstantRateWifiManager",
|
||||
"DataMode",StringValue(phyMode),
|
||||
"ControlMode",StringValue(phyMode));
|
||||
// Set it to adhoc mode
|
||||
wifiMac.SetType ("ns3::AdhocWifiMac");
|
||||
NetDeviceContainer devices = wifi.Install (wifiPhy, wifiMac, olsrNodes);
|
||||
|
||||
CsmaHelper csma;
|
||||
csma.SetChannelAttribute ("DataRate", DataRateValue (DataRate (5000000)));
|
||||
csma.SetChannelAttribute ("Delay", TimeValue (MilliSeconds (2)));
|
||||
NetDeviceContainer csmaDevices = csma.Install (NodeContainer (csmaNodes.Get(0), olsrNodes.Get(1)));
|
||||
|
||||
// Note that with FixedRssLossModel, the positions below are not
|
||||
// used for received signal strength.
|
||||
MobilityHelper mobility;
|
||||
Ptr<ListPositionAllocator> positionAlloc = CreateObject<ListPositionAllocator> ();
|
||||
positionAlloc->Add (Vector (0.0, 0.0, 0.0));
|
||||
positionAlloc->Add (Vector (5.0, 0.0, 0.0));
|
||||
mobility.SetPositionAllocator (positionAlloc);
|
||||
mobility.SetMobilityModel ("ns3::ConstantPositionMobilityModel");
|
||||
mobility.Install (olsrNodes);
|
||||
|
||||
OlsrHelper olsr;
|
||||
|
||||
// Specify Node B's csma device as a non-OLSR device.
|
||||
olsr.ExcludeInterface (olsrNodes.Get (1), 2);
|
||||
|
||||
Ipv4StaticRoutingHelper staticRouting;
|
||||
|
||||
Ipv4ListRoutingHelper list;
|
||||
list.Add (staticRouting, 0);
|
||||
list.Add (olsr, 10);
|
||||
|
||||
InternetStackHelper internet_olsr;
|
||||
internet_olsr.SetRoutingHelper (list);
|
||||
internet_olsr.Install (olsrNodes);
|
||||
|
||||
InternetStackHelper internet_csma;
|
||||
internet_csma.Install (csmaNodes);
|
||||
|
||||
Ipv4AddressHelper ipv4;
|
||||
NS_LOG_INFO ("Assign IP Addresses.");
|
||||
ipv4.SetBase ("10.1.1.0", "255.255.255.0");
|
||||
ipv4.Assign (devices);
|
||||
|
||||
ipv4.SetBase ("172.16.1.0", "255.255.255.0");
|
||||
ipv4.Assign (csmaDevices);
|
||||
|
||||
TypeId tid = TypeId::LookupByName ("ns3::UdpSocketFactory");
|
||||
Ptr<Socket> recvSink = Socket::CreateSocket (csmaNodes.Get(0), tid);
|
||||
InetSocketAddress local = InetSocketAddress (Ipv4Address::GetAny (), 80);
|
||||
recvSink->Bind (local);
|
||||
recvSink->SetRecvCallback (MakeCallback (&ReceivePacket));
|
||||
|
||||
Ptr<Socket> source = Socket::CreateSocket (olsrNodes.Get (0), tid);
|
||||
InetSocketAddress remote = InetSocketAddress (Ipv4Address ("172.16.1.1"), 80);
|
||||
source->Connect (remote);
|
||||
|
||||
// Obtain olsr::RoutingProtocol instance of gateway node
|
||||
// (namely, node B) and add the required association
|
||||
Ptr<Ipv4> stack = olsrNodes.Get (1) -> GetObject<Ipv4> ();
|
||||
Ptr<Ipv4RoutingProtocol> rp_Gw = (stack->GetRoutingProtocol ());
|
||||
Ptr<Ipv4ListRouting> lrp_Gw = DynamicCast<Ipv4ListRouting> (rp_Gw);
|
||||
|
||||
Ptr<olsr::RoutingProtocol> olsrrp_Gw;
|
||||
|
||||
for (uint32_t i = 0; i < lrp_Gw->GetNRoutingProtocols (); i++)
|
||||
{
|
||||
int16_t priority;
|
||||
Ptr<Ipv4RoutingProtocol> temp = lrp_Gw->GetRoutingProtocol (i, priority);
|
||||
if (DynamicCast<olsr::RoutingProtocol> (temp))
|
||||
{
|
||||
olsrrp_Gw = DynamicCast<olsr::RoutingProtocol> (temp);
|
||||
}
|
||||
}
|
||||
|
||||
// Create a special Ipv4StaticRouting instance for RoutingTableAssociation
|
||||
// Even the Ipv4StaticRouting instance added to list may be used
|
||||
Ptr<Ipv4StaticRouting> hnaEntries = Create<Ipv4StaticRouting> ();
|
||||
|
||||
if (assocMethod1)
|
||||
{
|
||||
// Add the required routes into the Ipv4StaticRouting Protocol instance
|
||||
// and have the node generate HNA messages for all these routes
|
||||
// which are associated with non-OLSR interfaces specified above.
|
||||
hnaEntries->AddNetworkRouteTo (Ipv4Address ("172.16.1.0"), Ipv4Mask ("255.255.255.0"), uint32_t(2), uint32_t(1));
|
||||
olsrrp_Gw->SetRoutingTableAssociation (hnaEntries);
|
||||
}
|
||||
|
||||
if (assocMethod2)
|
||||
{
|
||||
// Specify the required associations directly.
|
||||
olsrrp_Gw->AddHostNetworkAssociation (Ipv4Address ("172.16.1.0"), Ipv4Mask ("255.255.255.0"));
|
||||
}
|
||||
|
||||
// Tracing
|
||||
wifiPhy.EnablePcap ("olsr-hna", devices);
|
||||
csma.EnablePcap ("olsr-hna", csmaDevices, false);
|
||||
|
||||
Simulator::ScheduleWithContext (source->GetNode ()->GetId (),
|
||||
Seconds (15.0), &GenerateTraffic,
|
||||
source, packetSize, numPackets, interPacketInterval);
|
||||
|
||||
Simulator::Stop (Seconds (20.0));
|
||||
Simulator::Run ();
|
||||
Simulator::Destroy ();
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -33,6 +33,10 @@ def build(bld):
|
||||
['point-to-point', 'internet-stack', 'olsr'])
|
||||
obj.source = 'simple-point-to-point-olsr.cc'
|
||||
|
||||
obj = bld.create_ns3_program('olsr-hna',
|
||||
['core', 'simulator', 'mobility', 'wifi'])
|
||||
obj.source = 'olsr-hna.cc'
|
||||
|
||||
obj = bld.create_ns3_program('nix-simple',
|
||||
['point-to-point', 'internet-stack', 'nix-vector-routing'])
|
||||
obj.source = 'nix-simple.cc'
|
||||
|
||||
@@ -33,6 +33,7 @@ OlsrHelper::OlsrHelper ()
|
||||
OlsrHelper::OlsrHelper (const OlsrHelper &o)
|
||||
: m_agentFactory (o.m_agentFactory)
|
||||
{
|
||||
m_interfaceExclusions = o.m_interfaceExclusions;
|
||||
}
|
||||
|
||||
OlsrHelper*
|
||||
@@ -41,10 +42,36 @@ OlsrHelper::Copy (void) const
|
||||
return new OlsrHelper (*this);
|
||||
}
|
||||
|
||||
void
|
||||
OlsrHelper::ExcludeInterface (Ptr<Node> node, uint32_t interface)
|
||||
{
|
||||
std::map< Ptr<Node>, std::set<uint32_t> >::iterator it = m_interfaceExclusions.find (node);
|
||||
|
||||
if(it == m_interfaceExclusions.end ())
|
||||
{
|
||||
std::set<uint32_t> interfaces;
|
||||
interfaces.insert (interface);
|
||||
|
||||
m_interfaceExclusions.insert (std::make_pair (node, std::set<uint32_t> (interfaces) ));
|
||||
}
|
||||
else
|
||||
{
|
||||
it->second.insert (interface);
|
||||
}
|
||||
}
|
||||
|
||||
Ptr<Ipv4RoutingProtocol>
|
||||
OlsrHelper::Create (Ptr<Node> node) const
|
||||
{
|
||||
Ptr<olsr::RoutingProtocol> agent = m_agentFactory.Create<olsr::RoutingProtocol> ();
|
||||
|
||||
std::map<Ptr<Node>, std::set<uint32_t> >::const_iterator it = m_interfaceExclusions.find (node);
|
||||
|
||||
if(it != m_interfaceExclusions.end ())
|
||||
{
|
||||
agent->SetInterfaceExclusions (it->second);
|
||||
}
|
||||
|
||||
node->AggregateObject (agent);
|
||||
return agent;
|
||||
}
|
||||
|
||||
@@ -24,6 +24,8 @@
|
||||
#include "ns3/node.h"
|
||||
#include "node-container.h"
|
||||
#include "ipv4-routing-helper.h"
|
||||
#include <map>
|
||||
#include <set>
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
@@ -57,6 +59,14 @@ public:
|
||||
*/
|
||||
OlsrHelper* Copy (void) const;
|
||||
|
||||
/**
|
||||
* \param node the node for which an exception is to be defined
|
||||
* \param interface an interface of node on which OLSR is not to be installed
|
||||
*
|
||||
* This method allows the user to specify an interface on which OLSR is not to be installed on
|
||||
*/
|
||||
void ExcludeInterface (Ptr<Node> node, uint32_t interface);
|
||||
|
||||
/**
|
||||
* \param node the node on which the routing protocol will run
|
||||
* \returns a newly-created routing protocol
|
||||
@@ -72,6 +82,7 @@ public:
|
||||
* This method controls the attributes of ns3::olsr::RoutingProtocol
|
||||
*/
|
||||
void Set (std::string name, const AttributeValue &value);
|
||||
|
||||
private:
|
||||
/**
|
||||
* \internal
|
||||
@@ -80,6 +91,8 @@ private:
|
||||
*/
|
||||
OlsrHelper &operator = (const OlsrHelper &o);
|
||||
ObjectFactory m_agentFactory;
|
||||
|
||||
std::map< Ptr<Node>, std::set<uint32_t> > m_interfaceExclusions;
|
||||
};
|
||||
|
||||
} // namespace ns3
|
||||
|
||||
@@ -231,6 +231,61 @@ operator << (std::ostream &os, const TopologyTuple &tuple)
|
||||
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<Ipv4Address> MprSet; ///< MPR Set type.
|
||||
typedef std::vector<MprSelectorTuple> MprSelectorSet; ///< MPR Selector Set type.
|
||||
@@ -240,6 +295,8 @@ typedef std::vector<TwoHopNeighborTuple> TwoHopNeighborSet; ///< 2-hop Neighbor
|
||||
typedef std::vector<TopologyTuple> TopologySet; ///< Topology Set type.
|
||||
typedef std::vector<DuplicateTuple> DuplicateSet; ///< Duplicate Set type.
|
||||
typedef std::vector<IfaceAssocTuple> IfaceAssocSet; ///< Interface Association Set type.
|
||||
typedef std::vector<AssociationTuple> AssociationSet; ///< Association Set type.
|
||||
typedef std::vector<Association> Associations; ///< Association Set type.
|
||||
|
||||
|
||||
}}; // namespace ns3, olsr
|
||||
|
||||
@@ -41,6 +41,7 @@
|
||||
#include "ns3/random-variable.h"
|
||||
#include "ns3/inet-socket-address.h"
|
||||
#include "ns3/ipv4-routing-protocol.h"
|
||||
#include "ns3/ipv4-routing-table-entry.h"
|
||||
#include "ns3/ipv4-route.h"
|
||||
#include "ns3/boolean.h"
|
||||
#include "ns3/uinteger.h"
|
||||
@@ -79,7 +80,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),
|
||||
@@ -185,12 +191,16 @@ RoutingProtocol::GetTypeId (void)
|
||||
|
||||
|
||||
RoutingProtocol::RoutingProtocol ()
|
||||
: m_ipv4 (0),
|
||||
: m_routingTableAssociation (0),
|
||||
m_ipv4 (0),
|
||||
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)
|
||||
{}
|
||||
{
|
||||
m_hnaRoutingTable = Create<Ipv4StaticRouting> ();
|
||||
}
|
||||
|
||||
RoutingProtocol::~RoutingProtocol ()
|
||||
{}
|
||||
@@ -204,6 +214,7 @@ RoutingProtocol::SetIpv4 (Ptr<Ipv4> 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;
|
||||
@@ -213,11 +224,15 @@ RoutingProtocol::SetIpv4 (Ptr<Ipv4> ipv4)
|
||||
m_linkTupleTimerFirstTime = true;
|
||||
|
||||
m_ipv4 = ipv4;
|
||||
|
||||
m_hnaRoutingTable->SetIpv4 (ipv4);
|
||||
}
|
||||
|
||||
void RoutingProtocol::DoDispose ()
|
||||
{
|
||||
m_ipv4 = 0;
|
||||
m_hnaRoutingTable = 0;
|
||||
m_routingTableAssociation = 0;
|
||||
|
||||
for (std::map< Ptr<Socket>, Ipv4InterfaceAddress >::iterator iter = m_socketAddresses.begin ();
|
||||
iter != m_socketAddresses.end (); iter++)
|
||||
@@ -251,6 +266,8 @@ void RoutingProtocol::DoStart ()
|
||||
NS_LOG_DEBUG ("Starting OLSR on node " << m_mainAddress);
|
||||
|
||||
Ipv4Address loopback ("127.0.0.1");
|
||||
|
||||
bool canRunOlsr = false;
|
||||
for (uint32_t i = 0; i < m_ipv4->GetNInterfaces (); i++)
|
||||
{
|
||||
Ipv4Address addr = m_ipv4->GetAddress (i, 0).GetLocal ();
|
||||
@@ -269,6 +286,9 @@ void RoutingProtocol::DoStart ()
|
||||
NS_ASSERT (GetMainAddress (addr) == m_mainAddress);
|
||||
}
|
||||
|
||||
if(m_interfaceExclusions.find (i) != m_interfaceExclusions.end ())
|
||||
continue;
|
||||
|
||||
// Create a socket to listen only on this interface
|
||||
Ptr<Socket> socket = Socket::CreateSocket (GetObject<Node> (),
|
||||
UdpSocketFactory::GetTypeId());
|
||||
@@ -279,20 +299,30 @@ void RoutingProtocol::DoStart ()
|
||||
}
|
||||
socket->Connect (InetSocketAddress (Ipv4Address (0xffffffff), OLSR_PORT_NUMBER));
|
||||
m_socketAddresses[socket] = m_ipv4->GetAddress (i, 0);
|
||||
|
||||
canRunOlsr = true;
|
||||
}
|
||||
|
||||
if(canRunOlsr)
|
||||
{
|
||||
HelloTimerExpire ();
|
||||
TcTimerExpire ();
|
||||
MidTimerExpire ();
|
||||
HnaTimerExpire ();
|
||||
|
||||
NS_LOG_DEBUG ("OLSR on node " << m_mainAddress << " started");
|
||||
}
|
||||
}
|
||||
|
||||
void RoutingProtocol::SetMainInterface (uint32_t interface)
|
||||
{
|
||||
m_mainAddress = m_ipv4->GetAddress (interface, 0).GetLocal ();
|
||||
}
|
||||
|
||||
void RoutingProtocol::SetInterfaceExclusions (std::set<uint32_t> exceptions)
|
||||
{
|
||||
m_interfaceExclusions = exceptions;
|
||||
}
|
||||
|
||||
//
|
||||
// \brief Processes an incoming %OLSR packet following RFC 3626 specification.
|
||||
@@ -397,6 +427,12 @@ RoutingProtocol::RecvOlsr (Ptr<Socket> socket)
|
||||
<< " received MID message of size " << messageHeader.GetSerializedSize ());
|
||||
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 " <<
|
||||
@@ -1039,6 +1075,53 @@ RoutingProtocol::RoutingTableComputation ()
|
||||
}
|
||||
}
|
||||
|
||||
// 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 gatewayEntry;
|
||||
|
||||
bool gatewayEntryExists = Lookup (tuple.gatewayAddr, gatewayEntry);
|
||||
bool addRoute = false;
|
||||
|
||||
uint32_t routeIndex = 0;
|
||||
|
||||
for (routeIndex = 0; routeIndex < m_hnaRoutingTable->GetNRoutes (); routeIndex++)
|
||||
{
|
||||
Ipv4RoutingTableEntry route = m_hnaRoutingTable->GetRoute (routeIndex);
|
||||
if (route.GetDestNetwork () == tuple.networkAddr &&
|
||||
route.GetDestNetworkMask () == tuple.netmask)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (routeIndex == m_hnaRoutingTable->GetNRoutes ())
|
||||
{
|
||||
addRoute = true;
|
||||
}
|
||||
else if(gatewayEntryExists && m_hnaRoutingTable->GetMetric (routeIndex) > gatewayEntry.distance)
|
||||
{
|
||||
m_hnaRoutingTable->RemoveRoute(routeIndex);
|
||||
addRoute = true;
|
||||
}
|
||||
|
||||
if(addRoute && gatewayEntryExists)
|
||||
{
|
||||
m_hnaRoutingTable->AddNetworkRouteTo (tuple.networkAddr,
|
||||
tuple.netmask,
|
||||
gatewayEntry.nextAddr,
|
||||
gatewayEntry.interface,
|
||||
gatewayEntry.distance);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
NS_LOG_DEBUG ("Node " << m_mainAddress << ": RoutingTableComputation end.");
|
||||
m_routingTableChanged (GetSize ());
|
||||
}
|
||||
@@ -1280,6 +1363,67 @@ RoutingProtocol::ProcessMid (const olsr::MessageHeader &msg,
|
||||
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<olsr::MessageHeader::Hna::Association>::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.
|
||||
@@ -1569,6 +1713,7 @@ RoutingProtocol::SendTc ()
|
||||
|
||||
olsr::MessageHeader::Tc &tc = msg.GetTc ();
|
||||
tc.ansn = m_ansn;
|
||||
|
||||
for (MprSelectorSet::const_iterator mprsel_tuple = m_state.GetMprSelectors ().begin();
|
||||
mprsel_tuple != m_state.GetMprSelectors ().end(); mprsel_tuple++)
|
||||
{
|
||||
@@ -1621,6 +1766,94 @@ RoutingProtocol::SendMid ()
|
||||
QueueMessage (msg, JITTER);
|
||||
}
|
||||
|
||||
///
|
||||
/// \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<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 ());
|
||||
|
||||
if (ci != m_interfaceExclusions.end ())
|
||||
{
|
||||
olsr::MessageHeader::Hna::Association assoc = {route.GetDestNetwork (), route.GetDestNetworkMask ()};
|
||||
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++)
|
||||
{
|
||||
// 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);
|
||||
}
|
||||
}
|
||||
|
||||
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::AddHostNetworkAssociation (Ipv4Address networkAddr, Ipv4Mask netmask)
|
||||
{
|
||||
m_state.InsertAssociation ((Association) {networkAddr, netmask});
|
||||
}
|
||||
|
||||
///
|
||||
/// \brief Adds an Ipv4StaticRouting protocol Association
|
||||
/// can generate an HNA message for
|
||||
///
|
||||
void
|
||||
RoutingProtocol::SetRoutingTableAssociation (Ptr<Ipv4StaticRouting> routingTable)
|
||||
{
|
||||
m_routingTableAssociation = routingTable;
|
||||
}
|
||||
|
||||
///
|
||||
/// \brief Updates Link Set according to a new received HELLO message (following RFC 3626
|
||||
/// specification). Neighbor Set is also updated if needed.
|
||||
@@ -2301,6 +2534,29 @@ RoutingProtocol::RemoveIfaceAssocTuple (const IfaceAssocTuple &tuple)
|
||||
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 ()
|
||||
{
|
||||
@@ -2357,6 +2613,24 @@ RoutingProtocol::MidTimerExpire ()
|
||||
m_midTimer.Schedule (m_midInterval);
|
||||
}
|
||||
|
||||
///
|
||||
/// \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)
|
||||
{
|
||||
SendHna ();
|
||||
}
|
||||
else
|
||||
{
|
||||
NS_LOG_DEBUG ("Not sending any HNA, no associations to advertise.");
|
||||
}
|
||||
m_hnaTimer.Schedule (m_hnaInterval);
|
||||
}
|
||||
|
||||
///
|
||||
/// \brief Removes tuple if expired. Else timer is rescheduled to expire at tuple.expirationTime.
|
||||
///
|
||||
@@ -2537,6 +2811,29 @@ RoutingProtocol::IfaceAssocTupleTimerExpire (Ipv4Address ifaceAddr)
|
||||
}
|
||||
}
|
||||
|
||||
/// \brief Removes tuple_ if expired. Else timer is rescheduled to expire at tuple_->time().
|
||||
/// \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.
|
||||
///
|
||||
@@ -2612,6 +2909,8 @@ RoutingProtocol::RouteOutput (Ptr<Packet> p, const Ipv4Header &header, Ptr<NetDe
|
||||
NS_LOG_FUNCTION (this << " " << m_ipv4->GetObject<Node> ()->GetId() << " " << header.GetDestination () << " " << oif);
|
||||
Ptr<Ipv4Route> rtentry;
|
||||
RoutingTableEntry entry1, entry2;
|
||||
bool found = false;
|
||||
|
||||
if (Lookup (header.GetDestination (), entry1) != 0)
|
||||
{
|
||||
bool foundSendEntry = FindSendEntry (entry1, entry2);
|
||||
@@ -2654,9 +2953,22 @@ RoutingProtocol::RouteOutput (Ptr<Packet> p, const Ipv4Header &header, Ptr<NetDe
|
||||
NS_LOG_DEBUG ("Olsr node " << m_mainAddress
|
||||
<< ": RouteOutput for dest=" << header.GetDestination ()
|
||||
<< " --> nextHop=" << entry2.nextAddr
|
||||
<< " interface=" << entry2.interface); NS_LOG_DEBUG ("Found route to " << rtentry->GetDestination () << " via nh " << rtentry->GetGateway () << " with source addr " << rtentry->GetSource () << " and output dev " << rtentry->GetOutputDevice());
|
||||
<< " interface=" << entry2.interface);
|
||||
NS_LOG_DEBUG ("Found route to " << rtentry->GetDestination () << " via nh " << rtentry->GetGateway () << " with source addr " << rtentry->GetSource () << " and output dev " << rtentry->GetOutputDevice());
|
||||
found = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
rtentry = m_hnaRoutingTable->RouteOutput (p, header, oif, sockerr);
|
||||
|
||||
if (rtentry)
|
||||
{
|
||||
found = true;
|
||||
NS_LOG_DEBUG ("Found route to " << rtentry->GetDestination () << " via nh " << rtentry->GetGateway () << " with source addr " << rtentry->GetSource () << " and output dev " << rtentry->GetOutputDevice());
|
||||
}
|
||||
}
|
||||
|
||||
if (!found)
|
||||
{
|
||||
NS_LOG_DEBUG ("Olsr node " << m_mainAddress
|
||||
<< ": RouteOutput for dest=" << header.GetDestination ()
|
||||
@@ -2729,20 +3041,32 @@ bool RoutingProtocol::RouteInput (Ptr<const Packet> p,
|
||||
}
|
||||
else
|
||||
{
|
||||
if(m_hnaRoutingTable->RouteInput (p, header, idev, ucb, mcb, lcb, ecb))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
#ifdef NS3_LOG_ENABLE
|
||||
NS_LOG_DEBUG ("Olsr node " << m_mainAddress
|
||||
<< ": RouteInput for dest=" << header.GetDestination ()
|
||||
<< " --> NOT FOUND; ** Dumping routing table..."); for (std::map<Ipv4Address, RoutingTableEntry>::const_iterator iter = m_table.begin ();
|
||||
<< " --> NOT FOUND; ** Dumping routing table...");
|
||||
|
||||
for (std::map<Ipv4Address, RoutingTableEntry>::const_iterator iter = m_table.begin ();
|
||||
iter != m_table.end (); iter++)
|
||||
{ NS_LOG_DEBUG ("dest=" << iter->first << " --> next=" << iter->second.nextAddr
|
||||
{
|
||||
NS_LOG_DEBUG ("dest=" << iter->first << " --> next=" << iter->second.nextAddr
|
||||
<< " via interface " << iter->second.interface);
|
||||
}
|
||||
|
||||
NS_LOG_DEBUG ("** Routing table dump end.");
|
||||
#endif // NS3_LOG_ENABLE
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
void
|
||||
RoutingProtocol::NotifyInterfaceUp (uint32_t i)
|
||||
{}
|
||||
|
||||
@@ -38,6 +38,7 @@
|
||||
#include "ns3/traced-callback.h"
|
||||
#include "ns3/ipv4.h"
|
||||
#include "ns3/ipv4-routing-protocol.h"
|
||||
#include "ns3/ipv4-static-routing.h"
|
||||
|
||||
#include <vector>
|
||||
#include <map>
|
||||
@@ -105,11 +106,30 @@ public:
|
||||
**/
|
||||
std::vector<RoutingTableEntry> GetRoutingTableEntries () const;
|
||||
|
||||
private:
|
||||
std::set<uint32_t> m_interfaceExclusions;
|
||||
Ptr<Ipv4StaticRouting> m_routingTableAssociation;
|
||||
|
||||
public:
|
||||
std::set<uint32_t> GetInterfaceExclusions () const
|
||||
{
|
||||
return m_interfaceExclusions;
|
||||
}
|
||||
void SetInterfaceExclusions (std::set<uint32_t> exceptions);
|
||||
|
||||
/// Inject Association to be sent in HNA message
|
||||
void AddHostNetworkAssociation (Ipv4Address networkAddr, Ipv4Mask netmask);
|
||||
|
||||
/// Inject Associations from an Ipv4StaticRouting instance
|
||||
void SetRoutingTableAssociation (Ptr<Ipv4StaticRouting> routingTable);
|
||||
|
||||
protected:
|
||||
virtual void DoStart (void);
|
||||
private:
|
||||
std::map<Ipv4Address, RoutingTableEntry> m_table; ///< Data structure for the routing table.
|
||||
|
||||
Ptr<Ipv4StaticRouting> m_hnaRoutingTable;
|
||||
|
||||
EventGarbageCollector m_events;
|
||||
|
||||
/// Address of the routing agent.
|
||||
@@ -128,6 +148,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;
|
||||
|
||||
@@ -189,6 +211,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);
|
||||
@@ -196,6 +221,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 ();
|
||||
|
||||
@@ -212,6 +238,7 @@ private:
|
||||
void SendHello ();
|
||||
void SendTc ();
|
||||
void SendMid ();
|
||||
void SendHna ();
|
||||
|
||||
void NeighborLoss (const LinkTuple &tuple);
|
||||
void AddDuplicateTuple (const DuplicateTuple &tuple);
|
||||
@@ -229,6 +256,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,
|
||||
@@ -237,6 +266,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,
|
||||
|
||||
@@ -487,4 +487,60 @@ OlsrState::FindNeighborInterfaces (const Ipv4Address &neighborMainAddr) 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::EraseAssociation (const Association &tuple)
|
||||
{
|
||||
for (Associations::iterator it = m_associations.begin ();
|
||||
it != m_associations.end (); it++)
|
||||
{
|
||||
if (*it == tuple)
|
||||
{
|
||||
m_associations.erase (it);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
OlsrState::InsertAssociation (const Association &tuple)
|
||||
{
|
||||
m_associations.push_back(tuple);
|
||||
}
|
||||
|
||||
} // namespace ns3
|
||||
|
||||
@@ -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, section12.2). Associations obtained from HNA messages generated by other nodes.
|
||||
Associations m_associations; ///< The node's local Host Network Associations that will be advertised using HNA messages.
|
||||
|
||||
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 & GetAssociations () const // Set of associations that the node has
|
||||
{
|
||||
return m_associations;
|
||||
}
|
||||
|
||||
AssociationTuple* FindAssociationTuple (const Ipv4Address &gatewayAddr,\
|
||||
const Ipv4Address &networkAddr,\
|
||||
const Ipv4Mask &netmask);
|
||||
void EraseAssociationTuple (const AssociationTuple &tuple);
|
||||
void InsertAssociationTuple (const AssociationTuple &tuple);
|
||||
void EraseAssociation (const Association &tuple);
|
||||
void InsertAssociation (const Association &tuple);
|
||||
|
||||
// Returns a vector of all interfaces of a given neighbor, with the
|
||||
// exception of the "main" one.
|
||||
std::vector<Ipv4Address>
|
||||
|
||||
Reference in New Issue
Block a user