A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
ipv6-interface.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2007-2009 Strasbourg University
3 *
4 * SPDX-License-Identifier: GPL-2.0-only
5 *
6 * Author: Sebastien Vincent <vincent@clarinet.u-strasbg.fr>
7 */
8
9#include "ipv6-interface.h"
10
11#include "icmpv6-l4-protocol.h"
12#include "ipv6-header.h"
13#include "ipv6-l3-protocol.h"
15#include "loopback-net-device.h"
16#include "ndisc-cache.h"
17
18#include "ns3/log.h"
19#include "ns3/mac16-address.h"
20#include "ns3/mac64-address.h"
21#include "ns3/net-device.h"
22#include "ns3/node.h"
23#include "ns3/packet.h"
24#include "ns3/traffic-control-layer.h"
25
26namespace ns3
27{
28
29NS_LOG_COMPONENT_DEFINE("Ipv6Interface");
30
31NS_OBJECT_ENSURE_REGISTERED(Ipv6Interface);
32
33TypeId
35{
36 static TypeId tid = TypeId("ns3::Ipv6Interface").SetParent<Object>().SetGroupName("Internet");
37 return tid;
38}
39
41 : m_ifup(false),
42 m_forwarding(true),
43 m_metric(1),
44 m_node(nullptr),
45 m_device(nullptr),
46 m_tc(nullptr),
47 m_ndCache(nullptr),
48 m_curHopLimit(0),
49 m_baseReachableTime(0),
50 m_reachableTime(0),
51 m_retransTimer(0)
52{
53 NS_LOG_FUNCTION(this);
54}
55
59
60void
62{
63 NS_LOG_FUNCTION(this);
64 m_node = nullptr;
65 m_device = nullptr;
66 m_tc = nullptr;
67 m_ndCache = nullptr;
69}
70
71void
73{
74 NS_LOG_FUNCTION(this);
75
76 if (!m_node || !m_device)
77 {
78 return;
79 }
80
81 /* set up link-local address */
82 if (!DynamicCast<LoopbackNetDevice>(m_device)) /* no autoconf for ip6-localhost */
83 {
84 Address addr = GetDevice()->GetAddress();
87 Ipv6Prefix(64));
90 }
91 else
92 {
93 return; /* no NDISC cache for ip6-localhost */
94 }
95 int32_t interfaceId = m_node->GetObject<Ipv6>()->GetInterfaceForDevice(m_device);
99
100 if (icmpv6 && !m_ndCache)
101 {
102 m_ndCache = icmpv6->CreateCache(m_device, this);
103 }
104}
105
106void
108{
109 NS_LOG_FUNCTION(this << node);
110 m_node = node;
111}
112
113void
115{
116 NS_LOG_FUNCTION(this << device);
117 m_device = device;
118}
119
120void
126
129{
130 NS_LOG_FUNCTION(this);
131 return m_device;
132}
133
134void
136{
137 NS_LOG_FUNCTION(this << metric);
138 m_metric = metric;
139}
140
141uint16_t
143{
144 NS_LOG_FUNCTION(this);
145 return m_metric;
146}
147
148bool
150{
151 NS_LOG_FUNCTION(this);
152 return m_ifup;
153}
154
155bool
157{
158 NS_LOG_FUNCTION(this);
159 return !m_ifup;
160}
161
162void
164{
165 NS_LOG_FUNCTION(this);
166
167 if (m_ifup)
168 {
169 return;
170 }
171 DoSetup();
172 m_ifup = true;
173}
174
175void
177{
178 NS_LOG_FUNCTION(this);
179 m_ifup = false;
180 m_addresses.clear();
181 m_ndCache->Flush();
182}
183
184bool
186{
187 NS_LOG_FUNCTION(this);
188 return m_forwarding;
189}
190
191void
193{
194 NS_LOG_FUNCTION(this << forwarding);
195 m_forwarding = forwarding;
196}
197
198bool
200{
201 NS_LOG_FUNCTION(this << iface);
202 Ipv6Address addr = iface.GetAddress();
203
204 /* DAD handling */
205 if (!addr.IsAny())
206 {
207 for (auto it = m_addresses.begin(); it != m_addresses.end(); ++it)
208 {
209 if (it->first.GetAddress() == addr)
210 {
211 return false;
212 }
213 }
214
216 m_addresses.emplace_back(iface, solicited);
217 if (!m_addAddressCallback.IsNull())
218 {
219 m_addAddressCallback(this, addr);
220 }
221
222 if (!addr.IsAny() || !addr.IsLocalhost())
223 {
224 /* DAD handling */
225
226 int32_t interfaceId = m_node->GetObject<Ipv6>()->GetInterfaceForDevice(m_device);
229 interfaceId));
230
231 if (icmpv6)
232 {
233 if (icmpv6->IsAlwaysDad())
234 {
235 Simulator::Schedule(Seconds(0.), &Icmpv6L4Protocol::DoDAD, icmpv6, addr, this);
236 Simulator::Schedule(icmpv6->GetDadTimeout(),
238 icmpv6,
239 this,
240 addr);
241 }
242 else
243 {
246 icmpv6,
247 this,
248 addr);
249 }
250 }
251 }
252 return true;
253 }
254
255 /* bad address */
256 return false;
257}
258
261{
262 /* IPv6 interface has always at least one IPv6 link-local address */
263 NS_LOG_FUNCTION(this);
264
265 return m_linkLocalAddress;
266}
267
268bool
270{
271 /* IPv6 interface has always at least one IPv6 Solicited Multicast address */
272 NS_LOG_FUNCTION(this << address);
273
274 for (auto it = m_addresses.begin(); it != m_addresses.end(); ++it)
275 {
276 if (it->second == address)
277 {
278 return true;
279 }
280 }
281
282 return false;
283}
284
287{
288 NS_LOG_FUNCTION(this << index);
289 uint32_t i = 0;
290
291 if (m_addresses.size() > index)
292 {
293 for (auto it = m_addresses.begin(); it != m_addresses.end(); ++it)
294 {
295 if (i == index)
296 {
297 return it->first;
298 }
299 i++;
300 }
301 }
302 else
303 {
304 NS_FATAL_ERROR("index " << index << " out of bounds");
305 }
307 return addr; /* quiet compiler */
308}
309
312{
313 NS_LOG_FUNCTION(this);
314 return m_addresses.size();
315}
316
319{
320 NS_LOG_FUNCTION(this << index);
321 uint32_t i = 0;
322
323 if (m_addresses.size() < index)
324 {
325 NS_FATAL_ERROR("Removing index that does not exist in Ipv6Interface::RemoveAddress");
326 }
327
328 for (auto it = m_addresses.begin(); it != m_addresses.end(); ++it)
329 {
330 if (i == index)
331 {
332 Ipv6InterfaceAddress iface = it->first;
333 m_addresses.erase(it);
334 if (!m_removeAddressCallback.IsNull())
335 {
336 m_removeAddressCallback(this, iface);
337 }
338 return iface;
339 }
340
341 i++;
342 }
343 NS_FATAL_ERROR("Address " << index << " not found");
345 return addr; /* quiet compiler */
346}
347
350{
351 NS_LOG_FUNCTION(this << address);
352
353 if (address == Ipv6Address::GetLoopback())
354 {
355 NS_LOG_WARN("Cannot remove loopback address.");
356 return Ipv6InterfaceAddress();
357 }
358
359 for (auto it = m_addresses.begin(); it != m_addresses.end(); ++it)
360 {
361 if (it->first.GetAddress() == address)
362 {
363 Ipv6InterfaceAddress iface = it->first;
364 m_addresses.erase(it);
365 if (!m_removeAddressCallback.IsNull())
366 {
367 m_removeAddressCallback(this, iface);
368 }
369 return iface;
370 }
371 }
372 return Ipv6InterfaceAddress();
373}
374
377{
378 NS_LOG_FUNCTION(this << dst);
379
380 for (auto it = m_addresses.begin(); it != m_addresses.end(); ++it)
381 {
383
384 if (ifaddr.GetPrefix().IsMatch(ifaddr.GetAddress(), dst))
385 {
386 return ifaddr;
387 }
388 }
389
390 /* NS_ASSERT_MSG (false, "Not matching address."); */
392 return ret; /* quiet compiler */
393}
394
395void
397{
398 NS_LOG_FUNCTION(this << p << dest);
399
400 if (!IsUp())
401 {
402 return;
403 }
404
406
407 /* check if destination is localhost (::1), if yes we don't pass through
408 * traffic control layer */
410 {
411 /** @todo additional checks needed here (such as whether multicast
412 * goes to loopback)?
413 */
414 p->AddHeader(hdr);
415 m_device->Send(p, m_device->GetBroadcast(), Ipv6L3Protocol::PROT_NUMBER);
416 return;
417 }
418
420
421 /* check if destination is for one of our interface */
422 for (auto it = m_addresses.begin(); it != m_addresses.end(); ++it)
423 {
424 if (dest == it->first.GetAddress())
425 {
426 p->AddHeader(hdr);
428 m_tc,
429 m_device,
430 p,
432 m_device->GetBroadcast(),
433 m_device->GetBroadcast(),
435 return;
436 }
437 }
438
439 /* other address */
440 if (m_device->NeedsArp())
441 {
442 NS_LOG_LOGIC("Needs NDISC " << dest);
443
444 int32_t interfaceId = m_node->GetObject<Ipv6>()->GetInterfaceForDevice(m_device);
447 interfaceId));
448
450 bool found = false;
451
452 NS_ASSERT(icmpv6);
453
454 if (dest.IsMulticast())
455 {
456 NS_LOG_LOGIC("IsMulticast");
458 m_device->IsMulticast(),
459 "Ipv6Interface::SendTo (): Sending multicast packet over non-multicast device");
460
461 hardwareDestination = m_device->GetMulticast(dest);
462 found = true;
463 }
464 else
465 {
466 NS_LOG_LOGIC("NDISC Lookup");
467 found = icmpv6->Lookup(p, hdr, dest, GetDevice(), m_ndCache, &hardwareDestination);
468 }
469
470 if (found)
471 {
472 NS_LOG_LOGIC("Address Resolved. Send.");
473 m_tc->Send(m_device,
477 hdr));
478 }
479 }
480 else
481 {
482 NS_LOG_LOGIC("Doesn't need NDISC");
483 m_tc->Send(m_device,
485 m_device->GetBroadcast(),
487 hdr));
488 }
489}
490
491void
497
498uint8_t
500{
501 NS_LOG_FUNCTION(this);
502 return m_curHopLimit;
503}
504
505void
511
512uint16_t
518
519void
525
526uint16_t
528{
529 NS_LOG_FUNCTION(this);
530 return m_reachableTime;
531}
532
533void
539
540uint16_t
542{
543 NS_LOG_FUNCTION(this);
544 return m_retransTimer;
545}
546
547void
549{
550 NS_LOG_FUNCTION(this << address << state);
551
552 for (auto it = m_addresses.begin(); it != m_addresses.end(); ++it)
553 {
554 if (it->first.GetAddress() == address)
555 {
556 it->first.SetState(state);
557 return;
558 }
559 }
560 /* not found, maybe address has expired */
561}
562
563void
565{
566 NS_LOG_FUNCTION(this << address << uid);
567
568 for (auto it = m_addresses.begin(); it != m_addresses.end(); ++it)
569 {
570 if (it->first.GetAddress() == address)
571 {
572 it->first.SetNsDadUid(uid);
573 return;
574 }
575 }
576 /* not found, maybe address has expired */
577}
578
581{
582 NS_LOG_FUNCTION(this);
583 return m_ndCache;
584}
585
586void
593
594void
601
602} /* namespace ns3 */
a polymophic address class
Definition address.h:90
Callback template class.
Definition callback.h:422
virtual void FunctionDadTimeout(Ipv6Interface *interface, Ipv6Address addr)
Function called when DAD timeout.
void DoDAD(Ipv6Address target, Ptr< Ipv6Interface > interface)
Do the Duplication Address Detection (DAD).
static uint16_t GetStaticProtocolNumber()
Get ICMPv6 protocol number.
Describes an IPv6 address.
static Ipv6Address MakeSolicitedAddress(Ipv6Address addr)
Make the solicited IPv6 address.
bool IsAny() const
If the IPv6 address is the "Any" address.
bool IsLocalhost() const
If the IPv6 address is localhost (::1).
static Ipv6Address MakeAutoconfiguredLinkLocalAddress(Address mac)
Make the autoconfigured link-local IPv6 address from a Mac address.
static Ipv6Address GetLoopback()
Get the loopback address.
Packet header for IPv6.
Definition ipv6-header.h:24
Access to the IPv6 forwarding table, interfaces, and configuration.
Definition ipv6.h:71
virtual Ptr< IpL4Protocol > GetProtocol(int protocolNumber) const =0
Get L4 protocol by protocol number.
IPv6 address associated with an interface.
Ipv6Address GetAddress() const
Get the IPv6 address.
State_e
State of an address associated with an interface.
Ipv6InterfaceAddress RemoveAddress(uint32_t index)
Remove an address from interface.
uint16_t GetBaseReachableTime() const
Get the base reachable time.
uint8_t m_curHopLimit
Current hop limit.
Ptr< NetDevice > m_device
NetDevice associated with this interface.
bool IsDown() const
Is the interface DOWN ?
Ptr< NdiscCache > m_ndCache
Neighbor cache.
Ipv6InterfaceAddress GetLinkLocalAddress() const
Get link-local address from IPv6 interface.
bool m_ifup
The state of this interface.
uint8_t GetCurHopLimit() const
Get the current hop limit value.
static TypeId GetTypeId()
Get the type ID.
Ipv6Interface()
Constructs an Ipv6Interface.
void SetRetransTimer(uint16_t retransTimer)
Set the retransmission timer.
void DoSetup()
Initialize interface.
void SetForwarding(bool forward)
Set forwarding enabled or not.
void SetReachableTime(uint16_t reachableTime)
Set the reachable time.
Ipv6InterfaceAddress GetAddressMatchingDestination(Ipv6Address dst)
Get an address which is in the same network prefix as destination.
void SetNode(Ptr< Node > node)
Set node associated with interface.
void SetDown()
Disable this interface.
bool IsForwarding() const
If the interface allows forwarding packets.
void RemoveAddressCallback(Callback< void, Ptr< Ipv6Interface >, Ipv6InterfaceAddress > removeAddressCallback)
This callback is set when an address is removed from an interface with auto-generated Ndisc cache and...
uint16_t GetReachableTime() const
Get the reachable time.
bool IsUp() const
Is the interface UP ?
bool m_forwarding
Forwarding state.
uint16_t m_metric
The metric.
uint16_t m_reachableTime
Reachable time (in millisecond).
uint32_t GetNAddresses() const
Get number of addresses on this IPv6 interface.
void DoDispose() override
Dispose this object.
Callback< void, Ptr< Ipv6Interface >, Ipv6InterfaceAddress > m_removeAddressCallback
remove address callback
bool IsSolicitedMulticastAddress(Ipv6Address address) const
Checks if the address is a Solicited Multicast address for this interface.
void SetCurHopLimit(uint8_t curHopLimit)
Set the current hop limit.
Ipv6InterfaceAddress GetAddress(uint32_t index) const
Get an address from IPv6 interface.
~Ipv6Interface() override
Destructor.
bool AddAddress(Ipv6InterfaceAddress iface)
Add an IPv6 address.
void SetUp()
Enable this interface.
void SetNsDadUid(Ipv6Address address, uint32_t uid)
Update NS DAD packet UID of an interface address.
uint16_t m_retransTimer
Retransmission timer (in millisecond).
void Send(Ptr< Packet > p, const Ipv6Header &hdr, Ipv6Address dest)
Send a packet through this interface.
Ipv6InterfaceAddressList m_addresses
The addresses assigned to this interface.
uint16_t GetRetransTimer() const
Get the retransmission timer.
uint16_t GetMetric() const
Get the metric.
void SetBaseReachableTime(uint16_t baseReachableTime)
Set the base reachable time.
Ptr< NdiscCache > GetNdiscCache() const
Ipv6InterfaceAddress m_linkLocalAddress
The link-local addresses assigned to this interface.
Ptr< Node > m_node
Node associated with this interface.
Callback< void, Ptr< Ipv6Interface >, Ipv6InterfaceAddress > m_addAddressCallback
add address callback
void SetTrafficControl(Ptr< TrafficControlLayer > tc)
Set the TrafficControlLayer.
void SetMetric(uint16_t metric)
Set the metric.
uint16_t m_baseReachableTime
Base value used for computing the random reachable time value (in millisecond).
Ptr< TrafficControlLayer > m_tc
TrafficControlLayer associated with this interface.
void AddAddressCallback(Callback< void, Ptr< Ipv6Interface >, Ipv6InterfaceAddress > addAddressCallback)
This callback is set when an address is added from an interface with auto-generated Ndisc cache and i...
void SetDevice(Ptr< NetDevice > device)
Set the NetDevice.
virtual Ptr< NetDevice > GetDevice() const
Get the NetDevice.
void SetState(Ipv6Address address, Ipv6InterfaceAddress::State_e state)
Update state of an interface address.
IPv6 layer implementation.
static constexpr uint16_t PROT_NUMBER
The protocol number for IPv6 (0x86DD).
Describes an IPv6 prefix.
void Flush()
Flush the cache.
@ PACKET_HOST
Packet addressed to us.
Definition net-device.h:290
A base class which provides memory management and object aggregation.
Definition object.h:78
Ptr< T > GetObject() const
Get a pointer to the requested aggregated Object.
Definition object.h:511
virtual void DoDispose()
Destructor implementation.
Definition object.cc:433
Smart pointer class similar to boost::intrusive_ptr.
Definition ptr.h:66
static EventId Schedule(const Time &delay, FUNC f, Ts &&... args)
Schedule an event to expire after delay.
Definition simulator.h:560
static EventId ScheduleNow(FUNC f, Ts &&... args)
Schedule an event to expire Now.
Definition simulator.h:594
virtual void Receive(Ptr< NetDevice > device, Ptr< const Packet > p, uint16_t protocol, const Address &from, const Address &to, NetDevice::PacketType packetType)
Called by NetDevices, incoming packet.
a unique identifier for an interface.
Definition type-id.h:49
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition type-id.cc:1001
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file,...
Definition assert.h:55
#define NS_ASSERT_MSG(condition, message)
At runtime, in debugging builds, if this condition is not true, the program prints the message to out...
Definition assert.h:75
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
#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 ",...
#define NS_LOG_WARN(msg)
Use NS_LOG to output a message of level LOG_WARN.
Definition log.h:250
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition object-base.h:35
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 Seconds(double value)
Construct a Time in the indicated unit.
Definition nstime.h:1344
Every class exported by the ns3 library is enclosed in the ns3 namespace.