A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
sixlowpan-nd-binding-table.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2025
3 *
4 * SPDX-License-Identifier: GPL-2.0-only
5 *
6 * Author: Boh Jie Qi <jieqiboh5836@gmail.com>
7 */
8
10
12
13#include "ns3/ipv6-address.h"
14#include "ns3/ipv6-interface.h"
15#include "ns3/ipv6-l3-protocol.h"
16#include "ns3/ipv6-routing-protocol.h"
17#include "ns3/log.h"
18#include "ns3/names.h"
19#include "ns3/node.h"
20#include "ns3/simulator.h"
21#include "ns3/uinteger.h"
22
23#include <iomanip>
24
25namespace ns3
26{
27
28NS_LOG_COMPONENT_DEFINE("SixLowPanNdBindingTable");
29
31
32/// Duration before an entry transitions to STALE state, in hours (RFC 8929).
33static const uint8_t STALE_DURATION = 24; // hours
34
37{
38 static TypeId tid =
39 TypeId("ns3::SixLowPanNdBindingTable")
41 .SetGroupName("SixLowPan")
42 .AddConstructor<SixLowPanNdBindingTable>()
43 .AddAttribute("StaleDuration",
44 "The duration (in hours) an entry remains in STALE state before "
45 "being removed from the binding table.",
48 MakeTimeChecker(Time(0), Hours(0xffff)));
49 return tid;
50}
51
57
63
64void
66{
67 NS_LOG_FUNCTION(this);
68
69 // Clean up all entries
70 for (auto& entry : m_sixLowPanNdBindingTable)
71 {
72 delete entry.second;
73 }
75
77}
78
81{
82 NS_LOG_FUNCTION(this);
83 return m_device;
84}
85
86void
88 Ptr<Ipv6Interface> interface,
90{
91 NS_LOG_FUNCTION(this << device << interface << icmpv6);
92 m_interface = interface;
93 m_icmpv6 = icmpv6;
94
95 if (device == nullptr)
96 {
97 NS_LOG_ERROR("Device is null, cannot set device for SixLowPanNdBindingTable");
98 return;
99 }
100 m_device = device;
101}
102
108
111{
112 NS_LOG_FUNCTION(this << dst);
113
114 auto it = m_sixLowPanNdBindingTable.find(dst);
115 return it != m_sixLowPanNdBindingTable.end() ? it->second : nullptr;
116}
117
120{
121 NS_LOG_FUNCTION(this << to);
122
123 auto [it, inserted] = m_sixLowPanNdBindingTable.emplace(to, nullptr);
124 if (!inserted)
125 {
126 NS_LOG_DEBUG("Entry for " << to << " already exists");
127 return it->second;
128 }
129
131 it->second = entry;
132 entry->SetIpv6Address(to);
133
134 NS_LOG_DEBUG("Added new binding table entry for " << to);
135 return entry;
136}
137
138void
140{
141 NS_LOG_FUNCTION(this << entry);
142
143 auto it = m_sixLowPanNdBindingTable.find(entry->GetIpv6Address());
144 if (it == m_sixLowPanNdBindingTable.end())
145 {
146 NS_LOG_WARN("Entry not found in binding table");
147 return;
148 }
149 NS_LOG_DEBUG("Removing binding table entry for " << it->first);
150 delete it->second;
152}
153
154void
156{
157 NS_LOG_FUNCTION(this << stream);
158
159 std::ostream* os = stream->GetStream();
160
161 // Collect entries in a vector for sorting
162 std::vector<std::pair<Ipv6Address, SixLowPanNdBindingTableEntry*>> entries;
163 for (const auto& i : m_sixLowPanNdBindingTable)
164 {
165 entries.emplace_back(i.first, i.second);
166 }
167
168 // Sort by IPv6 address
169 std::sort(entries.begin(), entries.end(), [](const auto& a, const auto& b) {
170 return a.first < b.first;
171 });
172
173 // Print sorted entries
174 for (const auto& entry : entries)
175 {
176 entry.second->Print(*os);
177 *os << std::endl;
178 }
179}
180
181// SixLowPanNdBindingTableEntry Implementation
182
185 : m_rovr(16, 0),
186 m_type(STALE), // Default state; MarkReachable() must be called after Add()
187 m_reachableTimer(Timer::CANCEL_ON_DESTROY),
188 m_staleTimer(Timer::CANCEL_ON_DESTROY),
190{
191 NS_LOG_FUNCTION(this << bt);
192}
193
194void
196{
197 NS_LOG_FUNCTION(this << &os);
198
199 os << m_ipv6Address;
200
201 switch (m_type)
202 {
203 case REACHABLE:
204 os << " REACHABLE";
205 break;
206 case STALE:
207 os << " STALE";
208 break;
209 }
210
211 os << std::dec;
212}
213
214void
216{
217 NS_LOG_FUNCTION(this << time);
218
220
221 // Cancel existing timers
222 if (m_reachableTimer.IsRunning())
223 {
224 m_reachableTimer.Cancel();
225 }
226
227 if (m_staleTimer.IsRunning())
228 {
229 m_staleTimer.Cancel();
230 }
231
232 if (time > 0)
233 {
234 // Start reachable timer (time is in units of 60 seconds from ARO)
235 m_reachableTimer.SetFunction(
237 this);
238 m_reachableTimer.SetDelay(Minutes(time));
239 m_reachableTimer.Schedule();
240
241 NS_LOG_DEBUG("Entry marked REACHABLE with lifetime " << time << " minutes");
242 }
243}
244
245void
247{
248 NS_LOG_FUNCTION(this);
249
250 m_type = STALE;
251
252 // Cancel any running timers
253 if (m_reachableTimer.IsRunning())
254 {
255 m_reachableTimer.Cancel();
256 }
257
258 if (m_staleTimer.IsRunning())
259 {
260 m_staleTimer.Cancel();
261 }
262
263 // Use the binding table's configurable stale duration
264 m_staleTimer.SetFunction(
266 this);
267 m_staleTimer.SetDelay(m_bindingTable->m_staleDuration); // Use configurable value
268 m_staleTimer.Schedule();
269
270 NS_LOG_DEBUG("Entry marked STALE with duration " << m_bindingTable->m_staleDuration.GetSeconds()
271 << " seconds");
272}
273
274bool
280
281bool
287
288void
290{
291 NS_LOG_FUNCTION(this);
292
293 if (m_type == REACHABLE)
294 {
295 NS_LOG_DEBUG("Registered timer expired, marking entry as STALE");
296 MarkStale();
297 }
298 else if (m_type == STALE)
299 {
300 NS_LOG_DEBUG("STALE timer expired, removing entry");
301
302 Ptr<NetDevice> device = m_bindingTable->GetDevice();
303 Ptr<Node> node = device ? device->GetNode() : nullptr;
304 Ptr<Ipv6L3Protocol> ipv6l3Protocol = node ? node->GetObject<Ipv6L3Protocol>() : nullptr;
305
306 if (ipv6l3Protocol)
307 {
308 ipv6l3Protocol->GetRoutingProtocol()->NotifyRemoveRoute(
310 Ipv6Prefix(128),
312 ipv6l3Protocol->GetInterfaceForDevice(device));
313 }
314
315 m_bindingTable->Remove(this);
316 }
317}
318
319void
325
326std::vector<uint8_t>
332
333void
335{
336 NS_LOG_FUNCTION(this << &rovr);
337 // We expect ROVR to be 16 bytes. If caller provides more, truncate; if less, pad with zeros.
338 if (rovr.size() >= 16)
339 {
340 m_rovr.assign(rovr.begin(), rovr.begin() + 16);
341 }
342 else
343 {
344 m_rovr = rovr;
345 m_rovr.resize(16, 0);
346 }
347}
348
355
362
363// Stream operator implementation
364std::ostream&
366{
367 entry.Print(os);
368 return os;
369}
370
371} // namespace ns3
Describes an IPv6 address.
static Ipv6Address GetAny()
Get the "any" (::) Ipv6Address.
IPv6 layer implementation.
Describes an IPv6 prefix.
Object()
Caller graph was not generated because of its size.
Definition object.cc:93
virtual void DoDispose()
Destructor implementation.
Definition object.cc:430
Smart pointer class similar to boost::intrusive_ptr.
Definition ptr.h:70
A record that holds information about an SixLowPanNdBindingTable entry.
std::vector< uint8_t > m_rovr
The ROVR value.
void MarkStale()
Change the state to this entry to STALE.
void MarkReachable(uint16_t time)
Changes the state to this entry to REACHABLE.
Timer m_staleTimer
Timer (used for STALE entries).
void SetIpv6Address(Ipv6Address ipv6Address)
Set the IPv6 address for this entry.
Timer m_reachableTimer
Timer (used for REACHABLE entries).
SixLowPanNdBindingTableEntryType_e m_type
The state of the entry.
Ipv6Address m_ipv6Address
The IPv6 address for this entry.
Ipv6Address GetIpv6Address() const
Get the IPv6 address for this entry.
SixLowPanNdBindingTable * m_bindingTable
The binding table this entry belongs to.
bool IsStale() const
Is the entry STALE.
SixLowPanNdBindingTable * GetBindingTable() const
Get the binding table this entry belongs to.
std::vector< uint8_t > GetRovr() const
Get the ROVR field.
void FunctionTimeout()
Function called when timer timeout.
void Print(std::ostream &os) const
Print the binding table entry to an output stream.
bool IsReachable() const
Is the entry REACHABLE.
SixLowPanNdBindingTableEntry(SixLowPanNdBindingTable *bt)
Constructor.
@ REACHABLE
Active registration.
@ STALE
Registration expired; entry pending removal.
void SetRovr(const std::vector< uint8_t > &rovr)
Set the ROVR field.
A binding table for 6LoWPAN ND.
Ptr< NetDevice > m_device
The NetDevice associated with this binding table.
Ptr< Ipv6Interface > GetInterface() const
Get the IPv6 interface associated with this binding table.
Time m_staleDuration
The duration (in hours) an entry remains in STALE state before being removed from the binding table.
void SetDevice(Ptr< NetDevice > device, Ptr< Ipv6Interface > interface, Ptr< Icmpv6L4Protocol > icmpv6)
Set the device and interface.
void Remove(SixLowPanNdBindingTable::SixLowPanNdBindingTableEntry *entry)
Remove an entry from the binding table.
SixLowPanNdBindingTable::SixLowPanNdBindingTableEntry * Add(Ipv6Address to)
Add an entry.
void PrintBindingTable(Ptr< OutputStreamWrapper > stream)
Print the SixLowPanNdBindingTable entries.
Ptr< Icmpv6L4Protocol > m_icmpv6
The ICMPv6 protocol associated with this binding table.
Ptr< NetDevice > GetDevice() const
Get the NetDevice associated with this cache.
Ptr< Ipv6Interface > m_interface
The IPv6 interface associated with this binding table.
SixLowPanNdBindingTable::SixLowPanNdBindingTableEntry * Lookup(Ipv6Address dst)
Lookup in the binding table.
void DoDispose() override
Dispose this object.
SixLowPanTable m_sixLowPanNdBindingTable
The actual binding table.
static TypeId GetTypeId()
Get the type ID.
Simulation virtual time values and global simulation resolution.
Definition nstime.h:95
AttributeValue implementation for Time.
Definition nstime.h:1375
A simple virtual Timer class.
Definition timer.h:67
a unique identifier for an interface.
Definition type-id.h:50
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition type-id.cc:999
Ptr< const AttributeAccessor > MakeTimeAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method.
Definition nstime.h:1376
Ptr< const AttributeChecker > MakeTimeChecker()
Helper to make an unbounded Time checker.
Definition nstime.h:1396
#define NS_LOG_ERROR(msg)
Use NS_LOG to output a message of level LOG_ERROR.
Definition log.h:246
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition log.h:194
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition log.h:260
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
#define NS_LOG_WARN(msg)
Use NS_LOG to output a message of level LOG_WARN.
Definition log.h:253
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition object-base.h:35
Time Hours(double value)
Construct a Time in the indicated unit.
Definition nstime.h:1244
Time Minutes(double value)
Construct a Time in the indicated unit.
Definition nstime.h:1256
Every class exported by the ns3 library is enclosed in the ns3 namespace.
std::ostream & operator<<(std::ostream &os, const Angles &a)
Definition angles.cc:148
static const uint8_t STALE_DURATION
Duration before an entry transitions to STALE state, in hours (RFC 8929).