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