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