A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
neighbor-cache-helper.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2022 ZHIHENG DONG
3 *
4 * SPDX-License-Identifier: GPL-2.0-only
5 *
6 * Author: Zhiheng Dong <dzh2077@gmail.com>
7 */
8
10
11#include "ns3/assert.h"
12#include "ns3/channel-list.h"
13#include "ns3/ipv4.h"
14#include "ns3/ipv6.h"
15#include "ns3/log.h"
16#include "ns3/net-device.h"
17#include "ns3/node.h"
18#include "ns3/ptr.h"
19#include "ns3/simulator.h"
20
21namespace ns3
22{
23
24NS_LOG_COMPONENT_DEFINE("NeighborCacheHelper");
25
30
35
36void
47
48void
50{
51 NS_LOG_FUNCTION(this << channel);
52 for (std::size_t i = 0; i < channel->GetNDevices(); ++i)
53 {
54 Ptr<NetDevice> netDevice = channel->GetDevice(i);
55 Ptr<Node> node = netDevice->GetNode();
56
58 if (node->GetObject<Ipv4>())
59 {
60 ipv4InterfaceIndex = node->GetObject<Ipv4>()->GetInterfaceForDevice(netDevice);
61 }
63 if (node->GetObject<Ipv6>())
64 {
65 ipv6InterfaceIndex = node->GetObject<Ipv6>()->GetInterfaceForDevice(netDevice);
66 }
67
68 for (std::size_t j = 0; j < channel->GetNDevices(); ++j)
69 {
70 Ptr<NetDevice> neighborDevice = channel->GetDevice(j);
72
74 if (neighborNode->GetObject<Ipv4>())
75 {
77 neighborNode->GetObject<Ipv4>()->GetInterfaceForDevice(neighborDevice);
78 }
80 if (neighborNode->GetObject<Ipv6>())
81 {
83 neighborNode->GetObject<Ipv6>()->GetInterfaceForDevice(neighborDevice);
84 }
85
87 {
88 if (ipv4InterfaceIndex != -1)
89 {
91 node->GetObject<Ipv4L3Protocol>()->GetInterface(ipv4InterfaceIndex);
93 {
95 neighborNode->GetObject<Ipv4L3Protocol>()->GetInterface(
98 }
99 }
100 if (ipv6InterfaceIndex != -1)
101 {
103 node->GetObject<Ipv6L3Protocol>()->GetInterface(ipv6InterfaceIndex);
105 {
107 neighborNode->GetObject<Ipv6L3Protocol>()->GetInterface(
110 }
111 }
112 }
113 }
114 }
115}
116
117void
119{
120 NS_LOG_FUNCTION(this);
121 for (uint32_t i = 0; i < c.GetN(); ++i)
122 {
124 Ptr<Channel> channel = netDevice->GetChannel();
125 Ptr<Node> node = netDevice->GetNode();
126
128 if (node->GetObject<Ipv4>())
129 {
130 ipv4InterfaceIndex = node->GetObject<Ipv4>()->GetInterfaceForDevice(netDevice);
131 }
133 if (node->GetObject<Ipv6>())
134 {
135 ipv6InterfaceIndex = node->GetObject<Ipv6>()->GetInterfaceForDevice(netDevice);
136 }
137
138 for (std::size_t j = 0; j < channel->GetNDevices(); ++j)
139 {
140 Ptr<NetDevice> neighborDevice = channel->GetDevice(j);
142
144 if (neighborNode->GetObject<Ipv4>())
145 {
147 neighborNode->GetObject<Ipv4>()->GetInterfaceForDevice(neighborDevice);
148 }
150 if (neighborNode->GetObject<Ipv6>())
151 {
153 neighborNode->GetObject<Ipv6>()->GetInterfaceForDevice(neighborDevice);
154 }
155
157 {
158 if (ipv4InterfaceIndex != -1)
159 {
161 node->GetObject<Ipv4L3Protocol>()->GetInterface(ipv4InterfaceIndex);
163 {
165 neighborNode->GetObject<Ipv4L3Protocol>()->GetInterface(
168 }
169 }
170 if (ipv6InterfaceIndex != -1)
171 {
173 node->GetObject<Ipv6L3Protocol>()->GetInterface(ipv6InterfaceIndex);
175 {
177 neighborNode->GetObject<Ipv6L3Protocol>()->GetInterface(
180 }
181 }
182 }
183 }
184 }
185}
186
187void
189{
190 NS_LOG_FUNCTION(this);
191 for (uint32_t i = 0; i < c.GetN(); ++i)
192 {
193 std::pair<Ptr<Ipv4>, uint32_t> returnValue = c.Get(i);
194 Ptr<Ipv4> ipv4 = returnValue.first;
195 uint32_t index = returnValue.second;
197 if (ipv4Interface)
198 {
200 Ptr<Channel> channel = netDevice->GetChannel();
201 for (std::size_t j = 0; j < channel->GetNDevices(); ++j)
202 {
203 Ptr<NetDevice> neighborDevice = channel->GetDevice(j);
205 {
208 neighborNode->GetObject<Ipv4>()->GetInterfaceForDevice(neighborDevice);
210 {
212 neighborNode->GetObject<Ipv4L3Protocol>()->GetInterface(
215 }
216 }
217 }
218 }
219 }
220}
221
222void
224{
225 NS_LOG_FUNCTION(this);
226 for (uint32_t i = 0; i < c.GetN(); ++i)
227 {
228 std::pair<Ptr<Ipv6>, uint32_t> returnValue = c.Get(i);
229 Ptr<Ipv6> ipv6 = returnValue.first;
230 uint32_t index = returnValue.second;
232 if (ipv6Interface)
233 {
235 Ptr<Channel> channel = netDevice->GetChannel();
236 for (std::size_t j = 0; j < channel->GetNDevices(); ++j)
237 {
238 Ptr<NetDevice> neighborDevice = channel->GetDevice(j);
240 {
243 neighborNode->GetObject<Ipv6>()->GetInterfaceForDevice(neighborDevice);
245 {
247 neighborNode->GetObject<Ipv6L3Protocol>()->GetInterface(
250 }
251 }
252 }
253 }
254 }
255}
256
257void
260{
261 uint32_t netDeviceAddresses = ipv4Interface->GetNAddresses();
264 {
265 ipv4Interface->RemoveAddressCallback(
268 {
269 ipv4Interface->AddAddressCallback(
271 }
272 }
273 for (uint32_t n = 0; n < netDeviceAddresses; ++n)
274 {
276 for (uint32_t m = 0; m < neighborDeviceAddresses; ++m)
277 {
279 if (netDeviceIfAddr.IsInSameSubnet(neighborDeviceIfAddr.GetLocal()))
280 {
282 // Add Arp entry of neighbor interface to current interface's Arp cache
284 neighborDeviceIfAddr.GetAddress(),
285 neighborDevice->GetAddress());
286 }
287 }
288 }
289}
290
291void
294{
295 uint32_t netDeviceAddresses = ipv6Interface->GetNAddresses();
298 {
299 ipv6Interface->RemoveAddressCallback(
302 {
303 ipv6Interface->AddAddressCallback(
305 }
306 }
307 for (uint32_t n = 0; n < netDeviceAddresses; ++n)
308 {
310 // Ignore if it is a linklocal address, which will be added along with the global address
313 {
314 NS_LOG_LOGIC("Skip the LINKLOCAL or LOCALHOST interface " << netDeviceIfAddr);
315 continue;
316 }
317 for (uint32_t m = 0; m < neighborDeviceAddresses; ++m)
318 {
319 // Ignore if it is a linklocal address, which will be added along with the global
320 // address
324 {
325 NS_LOG_LOGIC("Skip the LINKLOCAL or LOCALHOST interface " << neighborDeviceIfAddr);
326 continue;
327 }
328 if (netDeviceIfAddr.IsInSameSubnet(neighborDeviceIfAddr.GetAddress()))
329 {
331 // Add neighbor's Ndisc entries of global address and linklocal address to current
332 // interface's Ndisc cache
334 neighborDeviceIfAddr.GetAddress(),
335 neighborDevice->GetAddress());
337 neighborDeviceInterface->GetLinkLocalAddress();
339 neighborlinkLocalAddr.GetAddress(),
340 neighborDevice->GetAddress());
341 }
342 }
343 }
344}
345
346void
349 Address macAddress) const
350{
353 if (!arpCache)
354 {
356 "ArpCache doesn't exist, might be a point-to-point NetDevice without ArpCache");
357 return;
358 }
360 if (!entry)
361 {
362 NS_LOG_FUNCTION("ADD an ARP entry");
363 entry = arpCache->Add(ipv4Address);
364 }
365 entry->SetMacAddress(macAddress);
366 entry->MarkAutoGenerated();
367}
368
369void
372 Address macAddress) const
373{
376 if (!ndiscCache)
377 {
379 "NdiscCache doesn't exist, might be a point-to-point NetDevice without NdiscCache");
380 return;
381 }
383 if (!entry)
384 {
385 NS_LOG_FUNCTION("ADD a NDISC entry");
387 }
388 entry->SetMacAddress(macAddress);
389 entry->MarkAutoGenerated();
390}
391
392void
394{
395 NS_LOG_FUNCTION(this);
396 for (uint32_t i = 0; i < NodeList::GetNNodes(); ++i)
397 {
399 for (uint32_t j = 0; j < node->GetNDevices(); ++j)
400 {
401 Ptr<NetDevice> netDevice = node->GetDevice(j);
402 int32_t ipv4InterfaceIndex = node->GetObject<Ipv4>()->GetInterfaceForDevice(netDevice);
403 int32_t ipv6InterfaceIndex = node->GetObject<Ipv6>()->GetInterfaceForDevice(netDevice);
404 if (ipv4InterfaceIndex != -1)
405 {
407 node->GetObject<Ipv4L3Protocol>()->GetInterface(ipv4InterfaceIndex);
408 Ptr<ArpCache> arpCache = ipv4Interface->GetArpCache();
409 if (arpCache)
410 {
411 NS_LOG_FUNCTION("Remove an ARP entry");
412 arpCache->RemoveAutoGeneratedEntries();
413 }
414 }
415 if (ipv6InterfaceIndex != -1)
416 {
418 node->GetObject<Ipv6L3Protocol>()->GetInterface(ipv6InterfaceIndex);
419 Ptr<NdiscCache> ndiscCache = ipv6Interface->GetNdiscCache();
420 if (ndiscCache)
421 {
422 NS_LOG_FUNCTION("Remove a NDISC entry");
423 ndiscCache->RemoveAutoGeneratedEntries();
424 }
425 }
426 }
427 }
428}
429
430void
432 const Ipv4InterfaceAddress ifAddr) const
433{
434 NS_LOG_FUNCTION(this);
435 Ptr<NetDevice> netDevice = interface->GetDevice();
436 Ptr<Channel> channel = netDevice->GetChannel();
437 for (std::size_t i = 0; i < channel->GetNDevices(); ++i)
438 {
439 Ptr<NetDevice> neighborDevice = channel->GetDevice(i);
442 neighborNode->GetObject<Ipv4>()->GetInterfaceForDevice(neighborDevice);
443 if (neighborInterfaceIndex != -1)
444 {
446 neighborNode->GetObject<Ipv4L3Protocol>()->GetInterface(neighborInterfaceIndex);
448 if (!arpCache)
449 {
450 NS_LOG_LOGIC("ArpCache doesn't exist");
451 return;
452 }
453 ArpCache::Entry* entry = arpCache->Lookup(ifAddr.GetLocal());
454 if (entry)
455 {
456 arpCache->Remove(entry);
457 }
458 }
459 }
460}
461
462void
464 const Ipv4InterfaceAddress ifAddr) const
465{
466 NS_LOG_FUNCTION(this);
467 Ptr<NetDevice> netDevice = interface->GetDevice();
468 Ptr<Channel> channel = netDevice->GetChannel();
469 for (std::size_t i = 0; i < channel->GetNDevices(); ++i)
470 {
471 Ptr<NetDevice> neighborDevice = channel->GetDevice(i);
473 {
476 neighborNode->GetObject<Ipv4>()->GetInterfaceForDevice(neighborDevice);
477 if (neighborInterfaceIndex != -1)
478 {
480 neighborNode->GetObject<Ipv4L3Protocol>()->GetInterface(neighborInterfaceIndex);
482 for (uint32_t m = 0; m < neighborDeviceAddresses; ++m)
483 {
485 if (ifAddr.IsInSameSubnet(neighborDeviceIfAddr.GetLocal()))
486 {
487 // Add Arp entity of current interface to its neighbor's Arp cache
488 AddEntry(neighborInterface, ifAddr.GetAddress(), netDevice->GetAddress());
489 }
490 }
491 }
492 }
493 }
494}
495
496void
498 const Ipv6InterfaceAddress ifAddr) const
499{
500 NS_LOG_FUNCTION(this);
501 Ptr<NetDevice> netDevice = interface->GetDevice();
502 Ptr<Channel> channel = netDevice->GetChannel();
503 for (std::size_t i = 0; i < channel->GetNDevices(); ++i)
504 {
505 Ptr<NetDevice> neighborDevice = channel->GetDevice(i);
508 neighborNode->GetObject<Ipv6>()->GetInterfaceForDevice(neighborDevice);
509 if (neighborInterfaceIndex != -1)
510 {
512 neighborNode->GetObject<Ipv6L3Protocol>()->GetInterface(neighborInterfaceIndex);
514 if (!ndiscCache)
515 {
516 NS_LOG_LOGIC("ndiscCache doesn't exist");
517 return;
518 }
519 NdiscCache::Entry* entry = ndiscCache->Lookup(ifAddr.GetAddress());
520 if (entry)
521 {
522 ndiscCache->Remove(entry);
523 }
524 }
525 }
526}
527
528void
530 const Ipv6InterfaceAddress ifAddr) const
531{
532 NS_LOG_FUNCTION(this);
533 Ptr<NetDevice> netDevice = interface->GetDevice();
534 Ptr<Channel> channel = netDevice->GetChannel();
535 for (std::size_t i = 0; i < channel->GetNDevices(); ++i)
536 {
537 Ptr<NetDevice> neighborDevice = channel->GetDevice(i);
539 {
542 neighborNode->GetObject<Ipv6>()->GetInterfaceForDevice(neighborDevice);
543 if (neighborInterfaceIndex != -1)
544 {
546 neighborNode->GetObject<Ipv6L3Protocol>()->GetInterface(neighborInterfaceIndex);
548 for (uint32_t m = 0; m < neighborDeviceAddresses; ++m)
549 {
551 if (ifAddr.IsInSameSubnet(neighborDeviceIfAddr.GetAddress()))
552 {
553 // Add Arp entity of current interface to its neighbor's Arp cache
554 AddEntry(neighborInterface, ifAddr.GetAddress(), netDevice->GetAddress());
555 }
556 }
557 }
558 }
559 }
560}
561
562void
568
569} // namespace ns3
a polymophic address class
Definition address.h:90
A record that that holds information about an ArpCache entry.
Definition arp-cache.h:173
static Ptr< Channel > GetChannel(uint32_t n)
static uint32_t GetNChannels()
Ipv4 addresses are stored in host order in this class.
Access to the IPv4 forwarding table, interfaces, and configuration.
Definition ipv4.h:69
a class to store IPv4 address information on an interface
Ipv4Address GetAddress() const
Get the local address.
holds a vector of std::pair of Ptr<Ipv4> and interface index.
Implement the IPv4 layer.
Describes an IPv6 address.
Access to the IPv6 forwarding table, interfaces, and configuration.
Definition ipv6.h:71
IPv6 address associated with an interface.
Ipv6Address GetAddress() const
Get the IPv6 address.
@ LINKLOCAL
Link-local address (fe80::/64)
Keep track of a set of IPv6 interfaces.
IPv6 layer implementation.
A record that holds information about a NdiscCache entry.
bool m_globalNeighborCache
flag will set true if neighbor caches were generated for all devices
void UpdateCacheByIpv6AddressAdded(const Ptr< Ipv6Interface > interface, const Ipv6InterfaceAddress ifAddr) const
Update neighbor cache when an address is added to a Ipv6Interface with auto generated neighbor cache.
void AddEntry(Ptr< Ipv4Interface > netDeviceInterface, Ipv4Address ipv4Address, Address macAddress) const
Add an auto_generated entry to the ARP cache of an interface.
void PopulateNeighborCache()
Populate neighbor ARP and NDISC caches for all devices.
bool m_dynamicNeighborCache
flag will set true if dynamic neighbor cache is enabled.
NeighborCacheHelper()
Construct a helper class to make life easier while creating neighbor cache.
void PopulateNeighborEntriesIpv4(Ptr< Ipv4Interface > ipv4Interface, Ptr< Ipv4Interface > neighborDeviceInterface) const
Populate neighbor ARP entries for given IPv4 interface.
void SetDynamicNeighborCache(bool enable)
Enable/disable dynamic neighbor cache, auto-generated neighbor cache will update by IP addresses chan...
void PopulateNeighborEntriesIpv6(Ptr< Ipv6Interface > ipv6Interface, Ptr< Ipv6Interface > neighborDeviceInterface) const
Populate neighbor NDISC entries for given IPv6 interface.
void UpdateCacheByIpv6AddressRemoved(const Ptr< Ipv6Interface > interface, const Ipv6InterfaceAddress ifAddr) const
Update neighbor caches when an address is removed from a Ipv6Interface with auto generated neighbor c...
void FlushAutoGenerated() const
Remove entries generated from NeighborCacheHelper from ARP cache and NDISC cache.
void UpdateCacheByIpv4AddressAdded(const Ptr< Ipv4Interface > interface, const Ipv4InterfaceAddress ifAddr) const
Update neighbor caches when an address is added to a Ipv4Interface with auto generated neighbor cache...
void UpdateCacheByIpv4AddressRemoved(const Ptr< Ipv4Interface > interface, const Ipv4InterfaceAddress ifAddr) const
Update neighbor caches when an address is removed from a Ipv4Interface with auto generated neighbor c...
holds a vector of ns3::NetDevice pointers
static uint32_t GetNNodes()
Definition node-list.cc:247
static Ptr< Node > GetNode(uint32_t n)
Definition node-list.cc:240
Smart pointer class similar to boost::intrusive_ptr.
Definition ptr.h:66
#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
Every class exported by the ns3 library is enclosed in the ns3 namespace.
Callback< R, Args... > MakeCallback(R(T::*memPtr)(Args...), OBJ objPtr)
Build Callbacks for class method members which take varying numbers of arguments and potentially retu...
Definition callback.h:684