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 <algorithm>
24#include <iomanip>
25
26namespace ns3
27{
28
29NS_LOG_COMPONENT_DEFINE("SixLowPanNdBindingTable");
30
32
33/// Duration before an entry transitions to STALE state, in hours (RFC 8929).
34static const uint8_t STALE_DURATION = 24; // hours
35
38{
39 static TypeId tid =
40 TypeId("ns3::SixLowPanNdBindingTable")
42 .SetGroupName("SixLowPan")
43 .AddConstructor<SixLowPanNdBindingTable>()
44 .AddAttribute("StaleDuration",
45 "The duration (in hours) an entry remains in STALE state before "
46 "being removed from the binding table.",
49 MakeTimeChecker(Time(0), Hours(0xffff)));
50 return tid;
51}
52
58
64
65void
67{
68 NS_LOG_FUNCTION(this);
69
70 // Clean up all entries
71 for (auto& entry : m_sixLowPanNdBindingTable)
72 {
73 delete entry.second;
74 }
76
77 m_device = nullptr;
78 m_interface = nullptr;
79 m_icmpv6 = nullptr;
80
82}
83
86{
87 NS_LOG_FUNCTION(this);
88 return m_device;
89}
90
91void
93 Ptr<Ipv6Interface> interface,
95{
96 NS_LOG_FUNCTION(this << device << interface << icmpv6);
97 m_interface = interface;
98 m_icmpv6 = icmpv6;
99
100 if (device == nullptr)
101 {
102 NS_LOG_ERROR("Device is null, cannot set device for SixLowPanNdBindingTable");
103 return;
104 }
105 m_device = device;
106}
107
113
116{
117 NS_LOG_FUNCTION(this << dst);
118
119 auto it = m_sixLowPanNdBindingTable.find(dst);
120 return it != m_sixLowPanNdBindingTable.end() ? it->second : nullptr;
121}
122
125{
126 NS_LOG_FUNCTION(this << to);
127
128 auto [it, inserted] = m_sixLowPanNdBindingTable.emplace(to, nullptr);
129 if (!inserted)
130 {
131 NS_LOG_DEBUG("Entry for " << to << " already exists");
132 return it->second;
133 }
134
136 it->second = entry;
137 entry->SetIpv6Address(to);
138
139 NS_LOG_DEBUG("Added new binding table entry for " << to);
140 return entry;
141}
142
143void
145{
146 NS_LOG_FUNCTION(this << entry);
147
148 auto it = m_sixLowPanNdBindingTable.find(entry->GetIpv6Address());
149 if (it == m_sixLowPanNdBindingTable.end())
150 {
151 NS_LOG_WARN("Entry not found in binding table");
152 return;
153 }
154 NS_LOG_DEBUG("Removing binding table entry for " << it->first);
155 delete it->second;
157}
158
159void
161{
162 NS_LOG_FUNCTION(this << stream);
163
164 std::ostream* os = stream->GetStream();
165
166 // Collect entries in a vector for sorting
167 std::vector<std::pair<Ipv6Address, SixLowPanNdBindingTableEntry*>> entries;
168 for (const auto& i : m_sixLowPanNdBindingTable)
169 {
170 entries.emplace_back(i.first, i.second);
171 }
172
173 // Sort by IPv6 address
174 std::sort(entries.begin(), entries.end(), [](const auto& a, const auto& b) {
175 return a.first < b.first;
176 });
177
178 // Print sorted entries
179 for (const auto& entry : entries)
180 {
181 entry.second->Print(*os);
182 *os << std::endl;
183 }
184}
185
186// SixLowPanNdBindingTableEntry Implementation
187
190 : m_rovr(16, 0),
191 m_type(STALE), // Default state; MarkReachable() must be called after Add()
192 m_reachableTimer(Timer::CANCEL_ON_DESTROY),
193 m_staleTimer(Timer::CANCEL_ON_DESTROY),
195{
196 NS_LOG_FUNCTION(this << bt);
197}
198
199void
201{
202 NS_LOG_FUNCTION(this << &os);
203
204 os << m_ipv6Address;
205
206 switch (m_type)
207 {
208 case REACHABLE:
209 os << " REACHABLE";
210 break;
211 case STALE:
212 os << " STALE";
213 break;
214 }
215
216 os << std::dec;
217}
218
219void
221{
222 NS_LOG_FUNCTION(this << time);
223
225
226 // Cancel existing timers
227 if (m_reachableTimer.IsRunning())
228 {
229 m_reachableTimer.Cancel();
230 }
231
232 if (m_staleTimer.IsRunning())
233 {
234 m_staleTimer.Cancel();
235 }
236
237 if (time > 0)
238 {
239 // Start reachable timer (time is in units of 60 seconds from ARO)
240 m_reachableTimer.SetFunction(
242 this);
243 m_reachableTimer.SetDelay(Minutes(time));
244 m_reachableTimer.Schedule();
245
246 NS_LOG_DEBUG("Entry marked REACHABLE with lifetime " << time << " minutes");
247 }
248}
249
250void
252{
253 NS_LOG_FUNCTION(this);
254
255 m_type = STALE;
256
257 // Cancel any running timers
258 if (m_reachableTimer.IsRunning())
259 {
260 m_reachableTimer.Cancel();
261 }
262
263 if (m_staleTimer.IsRunning())
264 {
265 m_staleTimer.Cancel();
266 }
267
268 // Use the binding table's configurable stale duration
269 m_staleTimer.SetFunction(
271 this);
272 m_staleTimer.SetDelay(m_bindingTable->m_staleDuration); // Use configurable value
273 m_staleTimer.Schedule();
274
275 NS_LOG_DEBUG("Entry marked STALE with duration " << m_bindingTable->m_staleDuration.GetSeconds()
276 << " seconds");
277}
278
279bool
285
286bool
292
293void
295{
296 NS_LOG_FUNCTION(this);
297
298 if (m_type == REACHABLE)
299 {
300 NS_LOG_DEBUG("Registered timer expired, marking entry as STALE");
301 MarkStale();
302 }
303 else if (m_type == STALE)
304 {
305 NS_LOG_DEBUG("STALE timer expired, removing entry");
306
307 Ptr<NetDevice> device = m_bindingTable->GetDevice();
308 Ptr<Node> node = device ? device->GetNode() : nullptr;
309 Ptr<Ipv6L3Protocol> ipv6l3Protocol = node ? node->GetObject<Ipv6L3Protocol>() : nullptr;
310
311 if (ipv6l3Protocol)
312 {
313 ipv6l3Protocol->GetRoutingProtocol()->NotifyRemoveRoute(
315 Ipv6Prefix(128),
317 ipv6l3Protocol->GetInterfaceForDevice(device));
318 }
319
320 m_bindingTable->Remove(this);
321 }
322}
323
324void
330
331std::vector<uint8_t>
337
338void
340{
341 NS_LOG_FUNCTION(this << &rovr);
342 // We expect ROVR to be 16 bytes. If caller provides more, truncate; if less, pad with zeros.
343 if (rovr.size() >= 16)
344 {
345 m_rovr.assign(rovr.begin(), rovr.begin() + 16);
346 }
347 else
348 {
349 m_rovr = rovr;
350 m_rovr.resize(16, 0);
351 }
352}
353
360
367
368// Stream operator implementation
369std::ostream&
371{
372 entry.Print(os);
373 return os;
374}
375
376} // 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).