A Discrete-Event Network Simulator
API
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 namespace ns3
36 {
37 
38 NS_LOG_COMPONENT_DEFINE ("AodvRoutingTable");
39 
40 namespace aodv
41 {
42 
43 /*
44  The Routing Table
45  */
46 
47 RoutingTableEntry::RoutingTableEntry (Ptr<NetDevice> dev, Ipv4Address dst, bool vSeqNo, uint32_t seqNo,
48  Ipv4InterfaceAddress iface, uint16_t hops, Ipv4Address nextHop, Time lifetime) :
49  m_ackTimer (Timer::CANCEL_ON_DESTROY),
50  m_validSeqNo (vSeqNo), m_seqNo (seqNo), m_hops (hops),
51  m_lifeTime (lifetime + Simulator::Now ()), m_iface (iface), m_flag (VALID),
52  m_reqCount (0), m_blackListState (false), m_blackListTimeout (Simulator::Now ())
53 {
54  m_ipv4Route = Create<Ipv4Route> ();
56  m_ipv4Route->SetGateway (nextHop);
59 }
60 
62 {
63 }
64 
65 bool
67 {
68  NS_LOG_FUNCTION (this << id);
69  if (!LookupPrecursor (id))
70  {
71  m_precursorList.push_back (id);
72  return true;
73  }
74  else
75  return false;
76 }
77 
78 bool
80 {
81  NS_LOG_FUNCTION (this << id);
82  for (std::vector<Ipv4Address>::const_iterator i = m_precursorList.begin (); i
83  != m_precursorList.end (); ++i)
84  {
85  if (*i == id)
86  {
87  NS_LOG_LOGIC ("Precursor " << id << " found");
88  return true;
89  }
90  }
91  NS_LOG_LOGIC ("Precursor " << id << " not found");
92  return false;
93 }
94 
95 bool
97 {
98  NS_LOG_FUNCTION (this << id);
99  std::vector<Ipv4Address>::iterator i = std::remove (m_precursorList.begin (),
100  m_precursorList.end (), id);
101  if (i == m_precursorList.end ())
102  {
103  NS_LOG_LOGIC ("Precursor " << id << " not found");
104  return false;
105  }
106  else
107  {
108  NS_LOG_LOGIC ("Precursor " << id << " found");
109  m_precursorList.erase (i, m_precursorList.end ());
110  }
111  return true;
112 }
113 
114 void
116 {
117  NS_LOG_FUNCTION (this);
118  m_precursorList.clear ();
119 }
120 
121 bool
123 {
124  return m_precursorList.empty ();
125 }
126 
127 void
128 RoutingTableEntry::GetPrecursors (std::vector<Ipv4Address> & prec) const
129 {
130  NS_LOG_FUNCTION (this);
131  if (IsPrecursorListEmpty ())
132  return;
133  for (std::vector<Ipv4Address>::const_iterator i = m_precursorList.begin (); i
134  != m_precursorList.end (); ++i)
135  {
136  bool result = true;
137  for (std::vector<Ipv4Address>::const_iterator j = prec.begin (); j
138  != prec.end (); ++j)
139  {
140  if (*j == *i)
141  result = false;
142  }
143  if (result)
144  prec.push_back (*i);
145  }
146 }
147 
148 void
150 {
151  NS_LOG_FUNCTION (this << badLinkLifetime.GetSeconds ());
152  if (m_flag == INVALID)
153  return;
154  m_flag = INVALID;
155  m_reqCount = 0;
156  m_lifeTime = badLinkLifetime + Simulator::Now ();
157 }
158 
159 void
161 {
162  std::ostream* os = stream->GetStream ();
163  *os << m_ipv4Route->GetDestination () << "\t" << m_ipv4Route->GetGateway ()
164  << "\t" << m_iface.GetLocal () << "\t";
165  switch (m_flag)
166  {
167  case VALID:
168  {
169  *os << "UP";
170  break;
171  }
172  case INVALID:
173  {
174  *os << "DOWN";
175  break;
176  }
177  case IN_SEARCH:
178  {
179  *os << "IN_SEARCH";
180  break;
181  }
182  }
183  *os << "\t";
184  *os << std::setiosflags (std::ios::fixed) <<
185  std::setiosflags (std::ios::left) << std::setprecision (2) <<
186  std::setw (14) << (m_lifeTime - Simulator::Now ()).GetSeconds ();
187  *os << "\t" << m_hops << "\n";
188 }
189 
190 /*
191  The Routing Table
192  */
193 
195  m_badLinkLifetime (t)
196 {
197 }
198 
199 bool
201 {
202  NS_LOG_FUNCTION (this << id);
203  Purge ();
204  if (m_ipv4AddressEntry.empty ())
205  {
206  NS_LOG_LOGIC ("Route to " << id << " not found; m_ipv4AddressEntry is empty");
207  return false;
208  }
209  std::map<Ipv4Address, RoutingTableEntry>::const_iterator i =
210  m_ipv4AddressEntry.find (id);
211  if (i == m_ipv4AddressEntry.end ())
212  {
213  NS_LOG_LOGIC ("Route to " << id << " not found");
214  return false;
215  }
216  rt = i->second;
217  NS_LOG_LOGIC ("Route to " << id << " found");
218  return true;
219 }
220 
221 bool
223 {
224  NS_LOG_FUNCTION (this << id);
225  if (!LookupRoute (id, rt))
226  {
227  NS_LOG_LOGIC ("Route to " << id << " not found");
228  return false;
229  }
230  NS_LOG_LOGIC ("Route to " << id << " flag is " << ((rt.GetFlag () == VALID) ? "valid" : "not valid"));
231  return (rt.GetFlag () == VALID);
232 }
233 
234 bool
236 {
237  NS_LOG_FUNCTION (this << dst);
238  Purge ();
239  if (m_ipv4AddressEntry.erase (dst) != 0)
240  {
241  NS_LOG_LOGIC ("Route deletion to " << dst << " successful");
242  return true;
243  }
244  NS_LOG_LOGIC ("Route deletion to " << dst << " not successful");
245  return false;
246 }
247 
248 bool
250 {
251  NS_LOG_FUNCTION (this);
252  Purge ();
253  if (rt.GetFlag () != IN_SEARCH)
254  rt.SetRreqCnt (0);
255  std::pair<std::map<Ipv4Address, RoutingTableEntry>::iterator, bool> result =
256  m_ipv4AddressEntry.insert (std::make_pair (rt.GetDestination (), rt));
257  return result.second;
258 }
259 
260 bool
262 {
263  NS_LOG_FUNCTION (this);
264  std::map<Ipv4Address, RoutingTableEntry>::iterator i =
265  m_ipv4AddressEntry.find (rt.GetDestination ());
266  if (i == m_ipv4AddressEntry.end ())
267  {
268  NS_LOG_LOGIC ("Route update to " << rt.GetDestination () << " fails; not found");
269  return false;
270  }
271  i->second = rt;
272  if (i->second.GetFlag () != IN_SEARCH)
273  {
274  NS_LOG_LOGIC ("Route update to " << rt.GetDestination () << " set RreqCnt to 0");
275  i->second.SetRreqCnt (0);
276  }
277  return true;
278 }
279 
280 bool
282 {
283  NS_LOG_FUNCTION (this);
284  std::map<Ipv4Address, RoutingTableEntry>::iterator i =
285  m_ipv4AddressEntry.find (id);
286  if (i == m_ipv4AddressEntry.end ())
287  {
288  NS_LOG_LOGIC ("Route set entry state to " << id << " fails; not found");
289  return false;
290  }
291  i->second.SetFlag (state);
292  i->second.SetRreqCnt (0);
293  NS_LOG_LOGIC ("Route set entry state to " << id << ": new state is " << state);
294  return true;
295 }
296 
297 void
298 RoutingTable::GetListOfDestinationWithNextHop (Ipv4Address nextHop, std::map<Ipv4Address, uint32_t> & unreachable )
299 {
300  NS_LOG_FUNCTION (this);
301  Purge ();
302  unreachable.clear ();
303  for (std::map<Ipv4Address, RoutingTableEntry>::const_iterator i =
304  m_ipv4AddressEntry.begin (); i != m_ipv4AddressEntry.end (); ++i)
305  {
306  if (i->second.GetNextHop () == nextHop)
307  {
308  NS_LOG_LOGIC ("Unreachable insert " << i->first << " " << i->second.GetSeqNo ());
309  unreachable.insert (std::make_pair (i->first, i->second.GetSeqNo ()));
310  }
311  }
312 }
313 
314 void
315 RoutingTable::InvalidateRoutesWithDst (const std::map<Ipv4Address, uint32_t> & unreachable)
316 {
317  NS_LOG_FUNCTION (this);
318  Purge ();
319  for (std::map<Ipv4Address, RoutingTableEntry>::iterator i =
320  m_ipv4AddressEntry.begin (); i != m_ipv4AddressEntry.end (); ++i)
321  {
322  for (std::map<Ipv4Address, uint32_t>::const_iterator j =
323  unreachable.begin (); j != unreachable.end (); ++j)
324  {
325  if ((i->first == j->first) && (i->second.GetFlag () == VALID))
326  {
327  NS_LOG_LOGIC ("Invalidate route with destination address " << i->first);
328  i->second.Invalidate (m_badLinkLifetime);
329  }
330  }
331  }
332 }
333 
334 void
336 {
337  NS_LOG_FUNCTION (this);
338  if (m_ipv4AddressEntry.empty ())
339  return;
340  for (std::map<Ipv4Address, RoutingTableEntry>::iterator i =
341  m_ipv4AddressEntry.begin (); i != m_ipv4AddressEntry.end ();)
342  {
343  if (i->second.GetInterface () == iface)
344  {
345  std::map<Ipv4Address, RoutingTableEntry>::iterator tmp = i;
346  ++i;
347  m_ipv4AddressEntry.erase (tmp);
348  }
349  else
350  ++i;
351  }
352 }
353 
354 void
356 {
357  NS_LOG_FUNCTION (this);
358  if (m_ipv4AddressEntry.empty ())
359  return;
360  for (std::map<Ipv4Address, RoutingTableEntry>::iterator i =
361  m_ipv4AddressEntry.begin (); i != m_ipv4AddressEntry.end ();)
362  {
363  if (i->second.GetLifeTime () < Seconds (0))
364  {
365  if (i->second.GetFlag () == INVALID)
366  {
367  std::map<Ipv4Address, RoutingTableEntry>::iterator tmp = i;
368  ++i;
369  m_ipv4AddressEntry.erase (tmp);
370  }
371  else if (i->second.GetFlag () == VALID)
372  {
373  NS_LOG_LOGIC ("Invalidate route with destination address " << i->first);
374  i->second.Invalidate (m_badLinkLifetime);
375  ++i;
376  }
377  else
378  ++i;
379  }
380  else
381  {
382  ++i;
383  }
384  }
385 }
386 
387 void
388 RoutingTable::Purge (std::map<Ipv4Address, RoutingTableEntry> &table) const
389 {
390  NS_LOG_FUNCTION (this);
391  if (table.empty ())
392  return;
393  for (std::map<Ipv4Address, RoutingTableEntry>::iterator i =
394  table.begin (); i != table.end ();)
395  {
396  if (i->second.GetLifeTime () < Seconds (0))
397  {
398  if (i->second.GetFlag () == INVALID)
399  {
400  std::map<Ipv4Address, RoutingTableEntry>::iterator tmp = i;
401  ++i;
402  table.erase (tmp);
403  }
404  else if (i->second.GetFlag () == VALID)
405  {
406  NS_LOG_LOGIC ("Invalidate route with destination address " << i->first);
407  i->second.Invalidate (m_badLinkLifetime);
408  ++i;
409  }
410  else
411  ++i;
412  }
413  else
414  {
415  ++i;
416  }
417  }
418 }
419 
420 bool
422 {
423  NS_LOG_FUNCTION (this << neighbor << blacklistTimeout.GetSeconds ());
424  std::map<Ipv4Address, RoutingTableEntry>::iterator i =
425  m_ipv4AddressEntry.find (neighbor);
426  if (i == m_ipv4AddressEntry.end ())
427  {
428  NS_LOG_LOGIC ("Mark link unidirectional to " << neighbor << " fails; not found");
429  return false;
430  }
431  i->second.SetUnidirectional (true);
432  i->second.SetBalcklistTimeout (blacklistTimeout);
433  i->second.SetRreqCnt (0);
434  NS_LOG_LOGIC ("Set link to " << neighbor << " to unidirectional");
435  return true;
436 }
437 
438 void
440 {
441  std::map<Ipv4Address, RoutingTableEntry> table = m_ipv4AddressEntry;
442  Purge (table);
443  *stream->GetStream () << "\nAODV Routing table\n"
444  << "Destination\tGateway\t\tInterface\tFlag\tExpire\t\tHops\n";
445  for (std::map<Ipv4Address, RoutingTableEntry>::const_iterator i =
446  table.begin (); i != table.end (); ++i)
447  {
448  i->second.Print (stream);
449  }
450  *stream->GetStream () << "\n";
451 }
452 
453 }
454 }
void InvalidateRoutesWithDst(std::map< Ipv4Address, uint32_t > const &unreachable)
Update routing entries with this destinations as follows:
Definition: aodv-rtable.cc:315
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:102
bool MarkLinkAsUnidirectional(Ipv4Address neighbor, Time blacklistTimeout)
Mark entry as unidirectional (e.g.
Definition: aodv-rtable.cc:421
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:73
#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:68
bool LookupRoute(Ipv4Address dst, RoutingTableEntry &rt)
Lookup routing table entry with destination address dst.
Definition: aodv-rtable.cc:200
A simple Timer class.
Definition: timer.h:73
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:261
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:201
void GetPrecursors(std::vector< Ipv4Address > &prec) const
Inserts precursors in vector prec if they does not yet exist in vector.
Definition: aodv-rtable.cc:128
~RoutingTableEntry()
Definition: aodv-rtable.cc:61
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:66
double GetSeconds(void) const
Get an approximation of the time stored in this instance in the indicated unit.
Definition: nstime.h:341
void Print(Ptr< OutputStreamWrapper > stream) const
Print routing table.
Definition: aodv-rtable.cc:439
void SetRreqCnt(uint8_t n)
Definition: aodv-rtable.h:125
bool IsPrecursorListEmpty() const
Check that precursor list empty.
Definition: aodv-rtable.cc:122
RouteFlags m_flag
Routing flags: valid, invalid or in search.
Definition: aodv-rtable.h:169
void DeleteAllRoutesFromInterface(Ipv4InterfaceAddress iface)
Delete all route from interface with address iface.
Definition: aodv-rtable.cc:335
bool SetEntryState(Ipv4Address dst, RouteFlags state)
Set routing table entry flags.
Definition: aodv-rtable.cc:281
bool LookupPrecursor(Ipv4Address id)
Lookup precursor by address.
Definition: aodv-rtable.cc:79
void SetGateway(Ipv4Address gw)
Definition: ipv4-route.cc:63
uint8_t m_reqCount
Number of route requests.
Definition: aodv-rtable.h:176
Time m_badLinkLifetime
Deletion time for invalid routes.
Definition: aodv-rtable.h:250
bool DeletePrecursor(Ipv4Address id)
Delete precursor.
Definition: aodv-rtable.cc:96
Ptr< Ipv4Route > m_ipv4Route
Ip route, include.
Definition: aodv-rtable.h:165
std::vector< Ipv4Address > m_precursorList
List of precursors.
Definition: aodv-rtable.h:172
#define NS_LOG_LOGIC(msg)
Use NS_LOG to output a message of level LOG_LOGIC.
Definition: log.h:252
void DeleteAllPrecursors()
Delete all precursors.
Definition: aodv-rtable.cc:115
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:298
Every class exported by the ns3 library is enclosed in the ns3 namespace.
void Invalidate(Time badLinkLifetime)
Mark entry as "down" (i.e. disable it)
Definition: aodv-rtable.cc:149
static Time Now(void)
Return the current simulation virtual time.
Definition: simulator.cc:224
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:167
RoutingTable(Time t)
c-tor
Definition: aodv-rtable.cc:194
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:158
Ipv4Address GetDestination(void) const
Definition: ipv4-route.cc:42
Ipv4 addresses are stored in host order in this class.
Definition: ipv4-address.h:40
a class to store IPv4 address information on an interface
bool AddRoute(RoutingTableEntry &r)
Add routing table entry if it doesn't yet exist in routing table.
Definition: aodv-rtable.cc:249
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:895
uint16_t m_hops
Hop Count (number of hops needed to reach destination)
Definition: aodv-rtable.h:151
Time Now(void)
create an ns3::Time instance which contains the current simulation time.
Definition: simulator.cc:340
bool LookupValidRoute(Ipv4Address dst, RoutingTableEntry &rt)
Lookup route in VALID state.
Definition: aodv-rtable.cc:222
bool DeleteRoute(Ipv4Address dst)
Delete routing table entry with destination address dst, if it exists.
Definition: aodv-rtable.cc:235
void Purge()
Delete all outdated entries and invalidate valid entry if Lifetime is expired.
Definition: aodv-rtable.cc:355
std::map< Ipv4Address, RoutingTableEntry > m_ipv4AddressEntry
Definition: aodv-rtable.h:248
RouteFlags GetFlag() const
Definition: aodv-rtable.h:124
Ipv4Address GetDestination() const
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:160
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:47