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
78}
79
82{
83 NS_LOG_FUNCTION(this);
84 return m_device;
85}
86
87void
89 Ptr<Ipv6Interface> interface,
91{
92 NS_LOG_FUNCTION(this << device << interface << icmpv6);
93 m_interface = interface;
94 m_icmpv6 = icmpv6;
95
96 if (device == nullptr)
97 {
98 NS_LOG_ERROR("Device is null, cannot set device for SixLowPanNdBindingTable");
99 return;
100 }
101 m_device = device;
102}
103
109
112{
113 NS_LOG_FUNCTION(this << dst);
114
115 auto it = m_sixLowPanNdBindingTable.find(dst);
116 return it != m_sixLowPanNdBindingTable.end() ? it->second : nullptr;
117}
118
121{
122 NS_LOG_FUNCTION(this << to);
123
124 auto [it, inserted] = m_sixLowPanNdBindingTable.emplace(to, nullptr);
125 if (!inserted)
126 {
127 NS_LOG_DEBUG("Entry for " << to << " already exists");
128 return it->second;
129 }
130
132 it->second = entry;
133 entry->SetIpv6Address(to);
134
135 NS_LOG_DEBUG("Added new binding table entry for " << to);
136 return entry;
137}
138
139void
141{
142 NS_LOG_FUNCTION(this << entry);
143
144 auto it = m_sixLowPanNdBindingTable.find(entry->GetIpv6Address());
145 if (it == m_sixLowPanNdBindingTable.end())
146 {
147 NS_LOG_WARN("Entry not found in binding table");
148 return;
149 }
150 NS_LOG_DEBUG("Removing binding table entry for " << it->first);
151 delete it->second;
153}
154
155void
157{
158 NS_LOG_FUNCTION(this << stream);
159
160 std::ostream* os = stream->GetStream();
161
162 // Collect entries in a vector for sorting
163 std::vector<std::pair<Ipv6Address, SixLowPanNdBindingTableEntry*>> entries;
164 for (const auto& i : m_sixLowPanNdBindingTable)
165 {
166 entries.emplace_back(i.first, i.second);
167 }
168
169 // Sort by IPv6 address
170 std::sort(entries.begin(), entries.end(), [](const auto& a, const auto& b) {
171 return a.first < b.first;
172 });
173
174 // Print sorted entries
175 for (const auto& entry : entries)
176 {
177 entry.second->Print(*os);
178 *os << std::endl;
179 }
180}
181
182// SixLowPanNdBindingTableEntry Implementation
183
186 : m_rovr(16, 0),
187 m_type(STALE), // Default state; MarkReachable() must be called after Add()
188 m_reachableTimer(Timer::CANCEL_ON_DESTROY),
189 m_staleTimer(Timer::CANCEL_ON_DESTROY),
191{
192 NS_LOG_FUNCTION(this << bt);
193}
194
195void
197{
198 NS_LOG_FUNCTION(this << &os);
199
200 os << m_ipv6Address;
201
202 switch (m_type)
203 {
204 case REACHABLE:
205 os << " REACHABLE";
206 break;
207 case STALE:
208 os << " STALE";
209 break;
210 }
211
212 os << std::dec;
213}
214
215void
217{
218 NS_LOG_FUNCTION(this << time);
219
221
222 // Cancel existing timers
223 if (m_reachableTimer.IsRunning())
224 {
225 m_reachableTimer.Cancel();
226 }
227
228 if (m_staleTimer.IsRunning())
229 {
230 m_staleTimer.Cancel();
231 }
232
233 if (time > 0)
234 {
235 // Start reachable timer (time is in units of 60 seconds from ARO)
236 m_reachableTimer.SetFunction(
238 this);
239 m_reachableTimer.SetDelay(Minutes(time));
240 m_reachableTimer.Schedule();
241
242 NS_LOG_DEBUG("Entry marked REACHABLE with lifetime " << time << " minutes");
243 }
244}
245
246void
248{
249 NS_LOG_FUNCTION(this);
250
251 m_type = STALE;
252
253 // Cancel any running timers
254 if (m_reachableTimer.IsRunning())
255 {
256 m_reachableTimer.Cancel();
257 }
258
259 if (m_staleTimer.IsRunning())
260 {
261 m_staleTimer.Cancel();
262 }
263
264 // Use the binding table's configurable stale duration
265 m_staleTimer.SetFunction(
267 this);
268 m_staleTimer.SetDelay(m_bindingTable->m_staleDuration); // Use configurable value
269 m_staleTimer.Schedule();
270
271 NS_LOG_DEBUG("Entry marked STALE with duration " << m_bindingTable->m_staleDuration.GetSeconds()
272 << " seconds");
273}
274
275bool
281
282bool
288
289void
291{
292 NS_LOG_FUNCTION(this);
293
294 if (m_type == REACHABLE)
295 {
296 NS_LOG_DEBUG("Registered timer expired, marking entry as STALE");
297 MarkStale();
298 }
299 else if (m_type == STALE)
300 {
301 NS_LOG_DEBUG("STALE timer expired, removing entry");
302
303 Ptr<NetDevice> device = m_bindingTable->GetDevice();
304 Ptr<Node> node = device ? device->GetNode() : nullptr;
305 Ptr<Ipv6L3Protocol> ipv6l3Protocol = node ? node->GetObject<Ipv6L3Protocol>() : nullptr;
306
307 if (ipv6l3Protocol)
308 {
309 ipv6l3Protocol->GetRoutingProtocol()->NotifyRemoveRoute(
311 Ipv6Prefix(128),
313 ipv6l3Protocol->GetInterfaceForDevice(device));
314 }
315
316 m_bindingTable->Remove(this);
317 }
318}
319
320void
326
327std::vector<uint8_t>
333
334void
336{
337 NS_LOG_FUNCTION(this << &rovr);
338 // We expect ROVR to be 16 bytes. If caller provides more, truncate; if less, pad with zeros.
339 if (rovr.size() >= 16)
340 {
341 m_rovr.assign(rovr.begin(), rovr.begin() + 16);
342 }
343 else
344 {
345 m_rovr = rovr;
346 m_rovr.resize(16, 0);
347 }
348}
349
356
363
364// Stream operator implementation
365std::ostream&
367{
368 entry.Print(os);
369 return os;
370}
371
372} // 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).