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