A Discrete-Event Network Simulator
API
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
aodv-rtable.cc
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2009 IITP RAS
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License version 2 as
7  * published by the Free Software Foundation;
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17  *
18  * Based on
19  * NS-2 AODV model developed by the CMU/MONARCH group and optimized and
20  * tuned by Samir Das and Mahesh Marina, University of Cincinnati;
21  *
22  * AODV-UU implementation by Erik Nordström of Uppsala University
23  * http://core.it.uu.se/core/index.php/AODV-UU
24  *
25  * Authors: Elena Buchatskaia <borovkovaes@iitp.ru>
26  * Pavel Boyko <boyko@iitp.ru>
27  */
28 
29 #include "aodv-rtable.h"
30 #include <algorithm>
31 #include <iomanip>
32 #include "ns3/simulator.h"
33 #include "ns3/log.h"
34 
35 NS_LOG_COMPONENT_DEFINE ("AodvRoutingTable");
36 
37 namespace ns3
38 {
39 namespace aodv
40 {
41 
42 /*
43  The Routing Table
44  */
45 
46 RoutingTableEntry::RoutingTableEntry (Ptr<NetDevice> dev, Ipv4Address dst, bool vSeqNo, uint32_t seqNo,
47  Ipv4InterfaceAddress iface, uint16_t hops, Ipv4Address nextHop, Time lifetime) :
48  m_ackTimer (Timer::CANCEL_ON_DESTROY),
49  m_validSeqNo (vSeqNo), m_seqNo (seqNo), m_hops (hops),
50  m_lifeTime (lifetime + Simulator::Now ()), m_iface (iface), m_flag (VALID),
51  m_reqCount (0), m_blackListState (false), m_blackListTimeout (Simulator::Now ())
52 {
53  m_ipv4Route = Create<Ipv4Route> ();
55  m_ipv4Route->SetGateway (nextHop);
58 }
59 
61 {
62 }
63 
64 bool
66 {
67  NS_LOG_FUNCTION (this << id);
68  if (!LookupPrecursor (id))
69  {
70  m_precursorList.push_back (id);
71  return true;
72  }
73  else
74  return false;
75 }
76 
77 bool
79 {
80  NS_LOG_FUNCTION (this << id);
81  for (std::vector<Ipv4Address>::const_iterator i = m_precursorList.begin (); i
82  != m_precursorList.end (); ++i)
83  {
84  if (*i == id)
85  {
86  NS_LOG_LOGIC ("Precursor " << id << " found");
87  return true;
88  }
89  }
90  NS_LOG_LOGIC ("Precursor " << id << " not found");
91  return false;
92 }
93 
94 bool
96 {
97  NS_LOG_FUNCTION (this << id);
98  std::vector<Ipv4Address>::iterator i = std::remove (m_precursorList.begin (),
99  m_precursorList.end (), id);
100  if (i == m_precursorList.end ())
101  {
102  NS_LOG_LOGIC ("Precursor " << id << " not found");
103  return false;
104  }
105  else
106  {
107  NS_LOG_LOGIC ("Precursor " << id << " found");
108  m_precursorList.erase (i, m_precursorList.end ());
109  }
110  return true;
111 }
112 
113 void
115 {
116  NS_LOG_FUNCTION (this);
117  m_precursorList.clear ();
118 }
119 
120 bool
122 {
123  return m_precursorList.empty ();
124 }
125 
126 void
127 RoutingTableEntry::GetPrecursors (std::vector<Ipv4Address> & prec) const
128 {
129  NS_LOG_FUNCTION (this);
130  if (IsPrecursorListEmpty ())
131  return;
132  for (std::vector<Ipv4Address>::const_iterator i = m_precursorList.begin (); i
133  != m_precursorList.end (); ++i)
134  {
135  bool result = true;
136  for (std::vector<Ipv4Address>::const_iterator j = prec.begin (); j
137  != prec.end (); ++j)
138  {
139  if (*j == *i)
140  result = false;
141  }
142  if (result)
143  prec.push_back (*i);
144  }
145 }
146 
147 void
149 {
150  NS_LOG_FUNCTION (this << badLinkLifetime.GetSeconds ());
151  if (m_flag == INVALID)
152  return;
153  m_flag = INVALID;
154  m_reqCount = 0;
155  m_lifeTime = badLinkLifetime + Simulator::Now ();
156 }
157 
158 void
160 {
161  std::ostream* os = stream->GetStream ();
162  *os << m_ipv4Route->GetDestination () << "\t" << m_ipv4Route->GetGateway ()
163  << "\t" << m_iface.GetLocal () << "\t";
164  switch (m_flag)
165  {
166  case VALID:
167  {
168  *os << "UP";
169  break;
170  }
171  case INVALID:
172  {
173  *os << "DOWN";
174  break;
175  }
176  case IN_SEARCH:
177  {
178  *os << "IN_SEARCH";
179  break;
180  }
181  }
182  *os << "\t";
183  *os << std::setiosflags (std::ios::fixed) <<
184  std::setiosflags (std::ios::left) << std::setprecision (2) <<
185  std::setw (14) << (m_lifeTime - Simulator::Now ()).GetSeconds ();
186  *os << "\t" << m_hops << "\n";
187 }
188 
189 /*
190  The Routing Table
191  */
192 
194  m_badLinkLifetime (t)
195 {
196 }
197 
198 bool
200 {
201  NS_LOG_FUNCTION (this << id);
202  Purge ();
203  if (m_ipv4AddressEntry.empty ())
204  {
205  NS_LOG_LOGIC ("Route to " << id << " not found; m_ipv4AddressEntry is empty");
206  return false;
207  }
208  std::map<Ipv4Address, RoutingTableEntry>::const_iterator i =
209  m_ipv4AddressEntry.find (id);
210  if (i == m_ipv4AddressEntry.end ())
211  {
212  NS_LOG_LOGIC ("Route to " << id << " not found");
213  return false;
214  }
215  rt = i->second;
216  NS_LOG_LOGIC ("Route to " << id << " found");
217  return true;
218 }
219 
220 bool
222 {
223  NS_LOG_FUNCTION (this << id);
224  if (!LookupRoute (id, rt))
225  {
226  NS_LOG_LOGIC ("Route to " << id << " not found");
227  return false;
228  }
229  NS_LOG_LOGIC ("Route to " << id << " flag is " << ((rt.GetFlag () == VALID) ? "valid" : "not valid"));
230  return (rt.GetFlag () == VALID);
231 }
232 
233 bool
235 {
236  NS_LOG_FUNCTION (this << dst);
237  Purge ();
238  if (m_ipv4AddressEntry.erase (dst) != 0)
239  {
240  NS_LOG_LOGIC ("Route deletion to " << dst << " successful");
241  return true;
242  }
243  NS_LOG_LOGIC ("Route deletion to " << dst << " not successful");
244  return false;
245 }
246 
247 bool
249 {
250  NS_LOG_FUNCTION (this);
251  Purge ();
252  if (rt.GetFlag () != IN_SEARCH)
253  rt.SetRreqCnt (0);
254  std::pair<std::map<Ipv4Address, RoutingTableEntry>::iterator, bool> result =
255  m_ipv4AddressEntry.insert (std::make_pair (rt.GetDestination (), rt));
256  return result.second;
257 }
258 
259 bool
261 {
262  NS_LOG_FUNCTION (this);
263  std::map<Ipv4Address, RoutingTableEntry>::iterator i =
264  m_ipv4AddressEntry.find (rt.GetDestination ());
265  if (i == m_ipv4AddressEntry.end ())
266  {
267  NS_LOG_LOGIC ("Route update to " << rt.GetDestination () << " fails; not found");
268  return false;
269  }
270  i->second = rt;
271  if (i->second.GetFlag () != IN_SEARCH)
272  {
273  NS_LOG_LOGIC ("Route update to " << rt.GetDestination () << " set RreqCnt to 0");
274  i->second.SetRreqCnt (0);
275  }
276  return true;
277 }
278 
279 bool
281 {
282  NS_LOG_FUNCTION (this);
283  std::map<Ipv4Address, RoutingTableEntry>::iterator i =
284  m_ipv4AddressEntry.find (id);
285  if (i == m_ipv4AddressEntry.end ())
286  {
287  NS_LOG_LOGIC ("Route set entry state to " << id << " fails; not found");
288  return false;
289  }
290  i->second.SetFlag (state);
291  i->second.SetRreqCnt (0);
292  NS_LOG_LOGIC ("Route set entry state to " << id << ": new state is " << state);
293  return true;
294 }
295 
296 void
297 RoutingTable::GetListOfDestinationWithNextHop (Ipv4Address nextHop, std::map<Ipv4Address, uint32_t> & unreachable )
298 {
299  NS_LOG_FUNCTION (this);
300  Purge ();
301  unreachable.clear ();
302  for (std::map<Ipv4Address, RoutingTableEntry>::const_iterator i =
303  m_ipv4AddressEntry.begin (); i != m_ipv4AddressEntry.end (); ++i)
304  {
305  if (i->second.GetNextHop () == nextHop)
306  {
307  NS_LOG_LOGIC ("Unreachable insert " << i->first << " " << i->second.GetSeqNo ());
308  unreachable.insert (std::make_pair (i->first, i->second.GetSeqNo ()));
309  }
310  }
311 }
312 
313 void
314 RoutingTable::InvalidateRoutesWithDst (const std::map<Ipv4Address, uint32_t> & unreachable)
315 {
316  NS_LOG_FUNCTION (this);
317  Purge ();
318  for (std::map<Ipv4Address, RoutingTableEntry>::iterator i =
319  m_ipv4AddressEntry.begin (); i != m_ipv4AddressEntry.end (); ++i)
320  {
321  for (std::map<Ipv4Address, uint32_t>::const_iterator j =
322  unreachable.begin (); j != unreachable.end (); ++j)
323  {
324  if ((i->first == j->first) && (i->second.GetFlag () == VALID))
325  {
326  NS_LOG_LOGIC ("Invalidate route with destination address " << i->first);
327  i->second.Invalidate (m_badLinkLifetime);
328  }
329  }
330  }
331 }
332 
333 void
335 {
336  NS_LOG_FUNCTION (this);
337  if (m_ipv4AddressEntry.empty ())
338  return;
339  for (std::map<Ipv4Address, RoutingTableEntry>::iterator i =
340  m_ipv4AddressEntry.begin (); i != m_ipv4AddressEntry.end ();)
341  {
342  if (i->second.GetInterface () == iface)
343  {
344  std::map<Ipv4Address, RoutingTableEntry>::iterator tmp = i;
345  ++i;
346  m_ipv4AddressEntry.erase (tmp);
347  }
348  else
349  ++i;
350  }
351 }
352 
353 void
355 {
356  NS_LOG_FUNCTION (this);
357  if (m_ipv4AddressEntry.empty ())
358  return;
359  for (std::map<Ipv4Address, RoutingTableEntry>::iterator i =
360  m_ipv4AddressEntry.begin (); i != m_ipv4AddressEntry.end ();)
361  {
362  if (i->second.GetLifeTime () < Seconds (0))
363  {
364  if (i->second.GetFlag () == INVALID)
365  {
366  std::map<Ipv4Address, RoutingTableEntry>::iterator tmp = i;
367  ++i;
368  m_ipv4AddressEntry.erase (tmp);
369  }
370  else if (i->second.GetFlag () == VALID)
371  {
372  NS_LOG_LOGIC ("Invalidate route with destination address " << i->first);
373  i->second.Invalidate (m_badLinkLifetime);
374  ++i;
375  }
376  else
377  ++i;
378  }
379  else
380  {
381  ++i;
382  }
383  }
384 }
385 
386 void
387 RoutingTable::Purge (std::map<Ipv4Address, RoutingTableEntry> &table) const
388 {
389  NS_LOG_FUNCTION (this);
390  if (table.empty ())
391  return;
392  for (std::map<Ipv4Address, RoutingTableEntry>::iterator i =
393  table.begin (); i != table.end ();)
394  {
395  if (i->second.GetLifeTime () < Seconds (0))
396  {
397  if (i->second.GetFlag () == INVALID)
398  {
399  std::map<Ipv4Address, RoutingTableEntry>::iterator tmp = i;
400  ++i;
401  table.erase (tmp);
402  }
403  else if (i->second.GetFlag () == VALID)
404  {
405  NS_LOG_LOGIC ("Invalidate route with destination address " << i->first);
406  i->second.Invalidate (m_badLinkLifetime);
407  ++i;
408  }
409  else
410  ++i;
411  }
412  else
413  {
414  ++i;
415  }
416  }
417 }
418 
419 bool
421 {
422  NS_LOG_FUNCTION (this << neighbor << blacklistTimeout.GetSeconds ());
423  std::map<Ipv4Address, RoutingTableEntry>::iterator i =
424  m_ipv4AddressEntry.find (neighbor);
425  if (i == m_ipv4AddressEntry.end ())
426  {
427  NS_LOG_LOGIC ("Mark link unidirectional to " << neighbor << " fails; not found");
428  return false;
429  }
430  i->second.SetUnidirectional (true);
431  i->second.SetBalcklistTimeout (blacklistTimeout);
432  i->second.SetRreqCnt (0);
433  NS_LOG_LOGIC ("Set link to " << neighbor << " to unidirectional");
434  return true;
435 }
436 
437 void
439 {
440  std::map<Ipv4Address, RoutingTableEntry> table = m_ipv4AddressEntry;
441  Purge (table);
442  *stream->GetStream () << "\nAODV Routing table\n"
443  << "Destination\tGateway\t\tInterface\tFlag\tExpire\t\tHops\n";
444  for (std::map<Ipv4Address, RoutingTableEntry>::const_iterator i =
445  table.begin (); i != table.end (); ++i)
446  {
447  i->second.Print (stream);
448  }
449  *stream->GetStream () << "\n";
450 }
451 
452 }
453 }
void InvalidateRoutesWithDst(std::map< Ipv4Address, uint32_t > const &unreachable)
Update routing entries with this destinations as follows:
Definition: aodv-rtable.cc:314
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:79
bool MarkLinkAsUnidirectional(Ipv4Address neighbor, Time blacklistTimeout)
Mark entry as unidirectional (e.g.
Definition: aodv-rtable.cc:420
smart pointer class similar to boost::intrusive_ptr
Definition: ptr.h:60
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by "...
Control the scheduling of simulation events.
Definition: simulator.h:63
bool LookupRoute(Ipv4Address dst, RoutingTableEntry &rt)
Lookup routing table entry with destination address dst.
Definition: aodv-rtable.cc:199
a simple Timer class
Definition: timer.h:45
Ipv4Address GetLocal(void) const
Get the local address.
Routing table entry.
Definition: aodv-rtable.h:59
bool Update(RoutingTableEntry &rt)
Update routing table.
Definition: aodv-rtable.cc:260
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:170
void GetPrecursors(std::vector< Ipv4Address > &prec) const
Inserts precursors in vector prec if they does not yet exist in vector.
Definition: aodv-rtable.cc:127
~RoutingTableEntry()
Definition: aodv-rtable.cc:60
void SetSource(Ipv4Address src)
Definition: ipv4-route.cc:49
bool InsertPrecursor(Ipv4Address id)
Insert precursor in precursor list if it doesn't yet exist in the list.
Definition: aodv-rtable.cc:65
double GetSeconds(void) const
Definition: nstime.h:272
void Print(Ptr< OutputStreamWrapper > stream) const
Print routing table.
Definition: aodv-rtable.cc:438
void SetRreqCnt(uint8_t n)
RREP_ACK timer.
Definition: aodv-rtable.h:125
bool IsPrecursorListEmpty() const
Check that precursor list empty.
Definition: aodv-rtable.cc:121
RouteFlags m_flag
Routing flags: valid, invalid or in search.
Definition: aodv-rtable.h:170
void DeleteAllRoutesFromInterface(Ipv4InterfaceAddress iface)
Delete all route from interface with address iface.
Definition: aodv-rtable.cc:334
bool SetEntryState(Ipv4Address dst, RouteFlags state)
Set routing table entry flags.
Definition: aodv-rtable.cc:280
bool LookupPrecursor(Ipv4Address id)
Lookup precursor by address.
Definition: aodv-rtable.cc:78
void SetGateway(Ipv4Address gw)
Definition: ipv4-route.cc:63
uint8_t m_reqCount
Number of route requests.
Definition: aodv-rtable.h:177
Time m_badLinkLifetime
Deletion time for invalid routes.
Definition: aodv-rtable.h:251
bool DeletePrecursor(Ipv4Address id)
Delete precursor.
Definition: aodv-rtable.cc:95
Ptr< Ipv4Route > m_ipv4Route
Ip route, include.
Definition: aodv-rtable.h:166
std::vector< Ipv4Address > m_precursorList
List of precursors.
Definition: aodv-rtable.h:173
#define NS_LOG_LOGIC(msg)
Use NS_LOG to output a message of level LOG_LOGIC.
Definition: log.h:233
void DeleteAllPrecursors()
Delete all precursors.
Definition: aodv-rtable.cc:114
Ipv4Address GetGateway(void) const
Definition: ipv4-route.cc:70
void GetListOfDestinationWithNextHop(Ipv4Address nextHop, std::map< Ipv4Address, uint32_t > &unreachable)
Lookup routing entries with next hop Address dst and not empty list of precursors.
Definition: aodv-rtable.cc:297
void Invalidate(Time badLinkLifetime)
Mark entry as "down" (i.e. disable it)
Definition: aodv-rtable.cc:148
static Time Now(void)
Return the "current simulation time".
Definition: simulator.cc:180
void SetOutputDevice(Ptr< NetDevice > outputDevice)
Equivalent in Linux to dst_entry.dev.
Definition: ipv4-route.cc:77
Ipv4InterfaceAddress m_iface
Output interface address.
Definition: aodv-rtable.h:168
RoutingTable(Time t)
c-tor
Definition: aodv-rtable.cc:193
Time m_lifeTime
Expiration or deletion time of the route Lifetime field in the routing table plays dual role – for a...
Definition: aodv-rtable.h:159
Ipv4Address GetDestination(void) const
Definition: ipv4-route.cc:42
Ipv4 addresses are stored in host order in this class.
Definition: ipv4-address.h:38
a class to store IPv4 address information on an interface
Time Now(void)
create an ns3::Time instance which contains the current simulation time.
Definition: simulator.cc:287
bool AddRoute(RoutingTableEntry &r)
Add routing table entry if it doesn't yet exist in routing table.
Definition: aodv-rtable.cc:248
uint16_t m_hops
Hop Count (number of hops needed to reach destination)
Definition: aodv-rtable.h:152
bool LookupValidRoute(Ipv4Address dst, RoutingTableEntry &rt)
Lookup route in VALID state.
Definition: aodv-rtable.cc:221
bool DeleteRoute(Ipv4Address dst)
Delete routing table entry with destination address dst, if it exists.
Definition: aodv-rtable.cc:234
void Purge()
Delete all outdated entries and invalidate valid entry if Lifetime is expired.
Definition: aodv-rtable.cc:354
std::map< Ipv4Address, RoutingTableEntry > m_ipv4AddressEntry
Definition: aodv-rtable.h:249
RouteFlags GetFlag() const
RREP_ACK timer.
Definition: aodv-rtable.h:124
Ipv4Address GetDestination() const
RREP_ACK timer.
Definition: aodv-rtable.h:106
std::ostream * GetStream(void)
Return a pointer to an ostream previously set in the wrapper.
void SetDestination(Ipv4Address dest)
Definition: ipv4-route.cc:35
void Print(Ptr< OutputStreamWrapper > stream) const
Definition: aodv-rtable.cc:159
RouteFlags
Route record states.
Definition: aodv-rtable.h:48
RoutingTableEntry(Ptr< NetDevice > dev=0, Ipv4Address dst=Ipv4Address(), bool vSeqNo=false, uint32_t m_seqNo=0, Ipv4InterfaceAddress iface=Ipv4InterfaceAddress(), uint16_t hops=0, Ipv4Address nextHop=Ipv4Address(), Time lifetime=Simulator::Now())
c-to
Definition: aodv-rtable.cc:46