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
35namespace ns3 {
36
37NS_LOG_COMPONENT_DEFINE ("AodvRoutingTable");
38
39namespace aodv {
40
41/*
42 The Routing Table
43 */
44
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
69bool
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
84bool
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
101bool
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
120void
122{
123 NS_LOG_FUNCTION (this);
124 m_precursorList.clear ();
125}
126
127bool
129{
130 return m_precursorList.empty ();
131}
132
133void
134RoutingTableEntry::GetPrecursors (std::vector<Ipv4Address> & prec) const
135{
136 NS_LOG_FUNCTION (this);
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
160void
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
173void
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
226bool
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
248bool
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
261bool
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
275bool
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
289bool
291{
292 NS_LOG_FUNCTION (this);
293 std::map<Ipv4Address, RoutingTableEntry>::iterator i =
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
309bool
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
326void
327RoutingTable::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
343void
344RoutingTable::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
363void
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
387void
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
424void
425RoutingTable::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
461bool
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
479void
480RoutingTable::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:432
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.