Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions WHATSNEW
Original file line number Diff line number Diff line change
Expand Up @@ -471,6 +471,10 @@ Notable bug fixes are the following:

The HT mode factory now includes band and preamble format in its cache key. A 5 GHz request after an equivalent 2.4 GHz request therefore receives the requested band and timing. Previously, that request could receive the earlier mode. Identical complete requests still reuse one object.

2. A router sends no Router Advertisement while its link-local address is tentative

A router sent Router Advertisements from its link-local address while Duplicate Address Detection for that address was running, and before it started, although RFC 4861 Section 4.2 requires the source to be the assigned link-local address, Section 6.2.2 allows them only on an interface with an assigned unicast address, and RFC 4862 does not count a tentative address as assigned. Periodic, solicited and Proxy Mobile IPv6 advertisements are now not sent while the link-local address is tentative; a solicited advertisement that is due after the address is verified is sent as before. Simulations with short advertisement intervals, or with advertisements solicited or sent by Proxy Mobile IPv6 while a router is still verifying its address, produce different results, for example in examples/manetrouting/dymo, examples/ipv6/pmipv6 and examples/inet/hierarchical99.


INET-4.7 (July 2026) — feature release
--------------------------------------
Expand Down
24 changes: 21 additions & 3 deletions src/inet/networklayer/icmpv6/Ipv6NeighbourDiscovery.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1258,9 +1258,15 @@ bool Ipv6NeighbourDiscovery::validateRsPacket(Packet *packet, const Ipv6RouterSo

void Ipv6NeighbourDiscovery::createAndSendRaPacket(const Ipv6Address& destAddr, NetworkInterface *ie)
{
EV_INFO << "Create and send RA invoked!\n";
// Must use link-local addr. See: RFC2461 Section 6.1.2
Ipv6Address sourceAddr = ie->getProtocolData<Ipv6InterfaceData>()->getLinkLocalAddress();
// RFC 4861 Section 4.2: the source is the link-local address assigned to the interface,
// and a tentative address is not assigned (RFC 4862 Section 5.4)
if (ie->getProtocolData<Ipv6InterfaceData>()->isTentativeAddress(sourceAddr)) {
EV_INFO << "Link-local address " << sourceAddr << " is tentative, RA not sent\n";
return;
}
EV_INFO << "Create and send RA invoked!\n";

// This operation includes all options, regardless whether it is solicited or unsolicited.
if (ie->getProtocolData<Ipv6InterfaceData>()->getAdvSendAdvertisements()) { // if this is an advertising interface
Expand Down Expand Up @@ -1682,8 +1688,14 @@ void Ipv6NeighbourDiscovery::sendPeriodicRa(cMessage *msg)
NetworkInterface *ie = (NetworkInterface *)msg->getContextPointer();
AdvIfEntry *advIfEntry = fetchAdvIfEntry(ie);
Ipv6Address destAddr = Ipv6Address("FF02::1");
createAndSendRaPacket(destAddr, ie);
advIfEntry->numRASent++;
// an RA that is not sent while the link-local address is tentative does not count
// as one of the initial advertisements
if (!ie->getProtocolData<Ipv6InterfaceData>()->isTentativeAddress(ie->getProtocolData<Ipv6InterfaceData>()->getLinkLocalAddress())) {
createAndSendRaPacket(destAddr, ie);
advIfEntry->numRASent++;
}
else
EV_INFO << "Link-local address is tentative, periodic RA not sent\n";

// RFC 2461, Section 6.2.4
/*Whenever a multicast advertisement is sent from an interface, the timer is
Expand Down Expand Up @@ -1726,6 +1738,12 @@ void Ipv6NeighbourDiscovery::sendSolicitedRa(cMessage *msg)
NetworkInterface *ie = (NetworkInterface *)msg->getContextPointer();
Ipv6Address destAddr = Ipv6Address("FF02::1");
EV_DETAIL << "Testing condition!\n";
if (ie->getProtocolData<Ipv6InterfaceData>()->isTentativeAddress(ie->getProtocolData<Ipv6InterfaceData>()->getLinkLocalAddress())) {
// createAndSendRaPacket() sends nothing; processRsPacket() took this RA as the next
// scheduled one, so point back at the periodic RA, or later RSs would be ignored
if (AdvIfEntry *advIfEntry = fetchAdvIfEntry(ie))
advIfEntry->nextScheduledRATime = advIfEntry->raTimeoutMsg->getArrivalTime();
}
createAndSendRaPacket(destAddr, ie);
delete msg;
}
Expand Down
10 changes: 5 additions & 5 deletions tests/fingerprint/examples.csv
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@

# /examples/inet/hierarchical99/, -f .qtenv.ini -c General -r 0
/examples/inet/hierarchical99/, -f networklayer.ini -c IPv4 -r 0, 10000s, a94d-edae/tplx;1f32-e325/~tNl;b138-ee8b/~tND;66c9-cd73/tyf, PASS, EthernetMac Ipv4
/examples/inet/hierarchical99/, -f networklayer.ini -c IPv6 -r 0, 10000s, 0001-0108/tplx;3960-479e/~tNl;add1-e848/~tND;2c03-abef/tyf, PASS, EthernetMac
/examples/inet/hierarchical99/, -f networklayer.ini -c IPv6 -r 0, 10000s, 2066-f2bb/tplx;a251-4e01/~tNl;0502-0a17/~tND;b45b-90f6/tyf, PASS, EthernetMac
/examples/inet/hierarchical99/, -f networklayer.ini -c Generic -r 0, 10000s, 6ae4-6e75/tplx;2209-80ac/~tNl;93bf-6657/tyf, PASS, EthernetMac
/examples/inet/hierarchical99/, -f networklayer.ini -c Flooding -r 0, 10000s, 7ba7-5b91/tplx;b0f0-411e/~tNl;2b94-8906/tyf, PASS, EthernetMac
/examples/inet/hierarchical99/, -f networklayer.ini -c ProbabilisticBroadcast -r 0, 10000s, 5a54-9779/tplx;1165-a70b/~tNl;760b-abfc/tyf, PASS, EthernetMac
Expand Down Expand Up @@ -348,16 +348,16 @@
# /examples/manetrouting/dymo/, -f omnetpp.ini -c _IPv4 -r 0 # abstract-config
/examples/manetrouting/dymo/, -f omnetpp.ini -c IPv4 -r 0, 10s, 1a85-cb5d/tplx;dfe8-11b9/~tNl;2b10-4dcb/tyf, PASS, wireless adhoc Ipv4
# /examples/manetrouting/dymo/, -f omnetpp.ini -c _IPv6 -r 0 # abstract-config
/examples/manetrouting/dymo/, -f omnetpp.ini -c IPv6 -r 0, 10s, d3ef-c8cf/tplx;fd53-3e15/~tNl;8301-9264/tyf, PASS, wireless adhoc
/examples/manetrouting/dymo/, -f omnetpp.ini -c IPv6 -r 0, 10s, e6da-b593/tplx;145b-4eb1/~tNl;b4b9-189a/tyf, PASS, wireless adhoc
# /examples/manetrouting/dymo/, -f omnetpp.ini -c _Generic -r 0 # abstract-config
/examples/manetrouting/dymo/, -f omnetpp.ini -c Generic -r 0, 10s, 5f8a-7174/tplx;9713-e7fe/~tNl;5716-c166/tyf, PASS, wireless adhoc
# /examples/manetrouting/dymo/, -f omnetpp.ini -c _Multi -r 0 # abstract-config
/examples/manetrouting/dymo/, -f omnetpp.ini -c MultiIPv4 -r 0, 10s, b346-3570/tplx;7bce-e34f/~tNl;4782-99e5/tyf, PASS, wireless adhoc Ipv4
/examples/manetrouting/dymo/, -f omnetpp.ini -c MultiIPv6 -r 0, 10s, d3ef-c8cf/tplx;fd53-3e15/~tNl;3ba7-352e/tyf, PASS, wireless adhoc
/examples/manetrouting/dymo/, -f omnetpp.ini -c MultiIPv6 -r 0, 10s, e6da-b593/tplx;145b-4eb1/~tNl;0adc-8b6a/tyf, PASS, wireless adhoc
/examples/manetrouting/dymo/, -f omnetpp.ini -c MultiGeneric -r 0, 10s, 0354-6dd4/tplx;735c-957d/~tNl;31f0-2788/tyf, PASS, wireless adhoc
# /examples/manetrouting/dymo/, -f omnetpp.ini -c _Dynamic -r 0 # abstract-config
/examples/manetrouting/dymo/, -f omnetpp.ini -c DynamicIPv4 -r 0, 22s, 2f57-3280/tplx;8f96-3d9c/~tNl;c33f-4f8c/tyf, PASS, wireless adhoc Ipv4
/examples/manetrouting/dymo/, -f omnetpp.ini -c DynamicIPv6 -r 0, 22s, 1e32-4f69/tplx;c684-e25f/~tNl;3469-a611/tyf, PASS, wireless adhoc
/examples/manetrouting/dymo/, -f omnetpp.ini -c DynamicIPv6 -r 0, 22s, cc61-27bb/tplx;c396-a2df/~tNl;749c-1382/tyf, PASS, wireless adhoc
/examples/manetrouting/dymo/, -f omnetpp.ini -c DynamicGeneric -r 0, 22s, b68e-dfe3/tplx;9c68-c2d4/~tNl;8c4d-6bc7/tyf, PASS, wireless adhoc

# /examples/manetrouting/gpsr/, -f omnetpp.ini -c Random -r 0, # abstract-config
Expand All @@ -383,7 +383,7 @@
/examples/ipv6/mipv6/, -f omnetpp.ini -c Handover -r 0, 70s, 68ea-9693/tplx;a44c-17bf/~tNl;96ff-ed7c/~tND;44ef-1a45/tyf, PASS, wireless EthernetMac
/examples/ipv6/mipv6/, -f omnetpp.ini -c RouteOptimizationTwoCNs -r 0, 60s, bacf-986a/tplx;e6db-28c0/~tNl;805b-8a25/~tND;ed3e-17fa/tyf, PASS, wireless EthernetMac
/examples/ipv6/mipv6roaming/, -f omnetpp.ini -c Roaming -r 0, 70s, b275-b584/tplx;28ce-974e/~tNl;dcec-ae59/~tND;afae-2b3c/tyf, PASS, wireless EthernetMac
/examples/ipv6/pmipv6/, -f omnetpp.ini -c General -r 0, 60s, e801-4d1a/tplx;1064-9bd4/~tNl;bd46-d85c/~tND;0277-d784/tyf, PASS, wireless EthernetMac
/examples/ipv6/pmipv6/, -f omnetpp.ini -c General -r 0, 60s, 1ace-6963/tplx;117c-4089/~tNl;ddb3-870d/~tND;62ee-3f4a/tyf, PASS, wireless EthernetMac

/examples/mobility/, -f omnetpp.ini -c AnsimMobility -r 0, 10000s, 72f8-5c0b/tplx;0000-0000/~tNl;0000-0000/~tND;7dd1-18eb/tyf, PASS,
/examples/mobility, -f omnetpp.ini -c AttachedMobility, 10s, 566c-6355/tplx;0000-0000/~tNl;0000-0000/~tND;fa92-f68c/tyf, PASS,
Expand Down
6 changes: 3 additions & 3 deletions tests/fingerprint/mipv6-refactoring.csv
Original file line number Diff line number Diff line change
Expand Up @@ -23,14 +23,14 @@
/examples/ipv6/nclients/, -f omnetpp.ini -c PPP_SCTP -r 0, 100s, 3a7c-924c/~tNlb, PASS,

# IPv6 networking examples
/examples/inet/hierarchical99/, -f networklayer.ini -c IPv6 -r 0, 10000s, f206-a0e2/~tNlb, PASS, EthernetMac
/examples/inet/hierarchical99/, -f networklayer.ini -c IPv6 -r 0, 10000s, 5836-f09b/~tNlb, PASS, EthernetMac
/examples/inet/udpclientserver/, -f omnetpp.ini -c udp_OK_ipv6 -r 0, 10s, 8feb-3936/~tNlb, PASS,
/examples/inet/udpclientserver/, -f omnetpp.ini -c udp_Port_Unav_ipv6 -r 0, 10s, 9661-c1f5/~tNlb, PASS,
/examples/inet/udpclientserver/, -f omnetpp.ini -c udp_Host_Unav_ipv6 -r 0, 10s, 6360-9ed1/~tNlb, PASS,

# DYMO with IPv6
/examples/manetrouting/dymo/, -f omnetpp.ini -c IPv6 -r 0, 10s, d23a-ce35/~tNlb, PASS, wireless adhoc
/examples/manetrouting/dymo/, -f omnetpp.ini -c MultiIPv6 -r 0, 10s, d23a-ce35/~tNlb, PASS, wireless adhoc
/examples/manetrouting/dymo/, -f omnetpp.ini -c IPv6 -r 0, 10s, cbc4-92bf/~tNlb, PASS, wireless adhoc
/examples/manetrouting/dymo/, -f omnetpp.ini -c MultiIPv6 -r 0, 10s, cbc4-92bf/~tNlb, PASS, wireless adhoc

# EIGRP with IPv6
/examples/eigrp/testing_scenario6/, -f omnetpp.ini -c EIGRP-IPv6_exp1_bandwidth-change -r 0, 3min, c645-565e/~tNlb, PASS, eigrp EthernetMac
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
%description:
A router sends no Router Advertisement while its link-local address is tentative: RFC 4861
Section 6.2.2 forbids Router Advertisements on an interface that is not an advertising
interface, which needs an assigned unicast address, and RFC 4862 Section 5.4 does not count
a tentative address as assigned.

Topology: router -- host

The router's Router Advertisement interval is 30-70 ms, shorter than its Duplicate Address
Detection (DAD) for the link-local address. Only the router's Neighbour Discovery logs, so
no "Create and send RA invoked!" line may come before its "DAD completed for address fe80"
line, and at least one must come after it.

%#--------------------------------------------------------------------------------------------------------------
%file: test.ned

import inet.networklayer.configurator.ipv6.Ipv6FlatNetworkConfigurator;
import inet.node.ipv6.Router6;
import inet.node.ipv6.StandardHost6;
import ned.DatarateChannel;

network TentativeRouterAdvertisementTest
{
types:
channel ethline extends DatarateChannel
{
delay = 0.1us;
datarate = 10Mbps;
}
submodules:
configurator: Ipv6FlatNetworkConfigurator;
router: Router6;
host: StandardHost6;
connections:
router.ethg++ <--> ethline <--> host.ethg++;
}

%#--------------------------------------------------------------------------------------------------------------
%inifile: omnetpp.ini

[General]
network = TentativeRouterAdvertisementTest
ned-path = .;../../../../src
sim-time-limit = 3s
record-vector-results = false
cmdenv-express-mode = false

**.router.ipv6.neighbourDiscovery.minIntervalBetweenRAs = 0.03s
**.router.ipv6.neighbourDiscovery.maxIntervalBetweenRAs = 0.07s

**.router.ipv6.neighbourDiscovery.cmdenv-log-level = info
**.cmdenv-log-level = off

%#--------------------------------------------------------------------------------------------------------------
%contains-regex: stdout
DAD completed for address fe80::[0-9a-f:]+ on eth0, address is unique[\s\S]*Create and send RA invoked!
%#--------------------------------------------------------------------------------------------------------------
%not-contains-regex: stdout
Create and send RA invoked![\s\S]*DAD completed for address fe80
%#--------------------------------------------------------------------------------------------------------------
%not-contains: stdout
<!> Error
%#--------------------------------------------------------------------------------------------------------------
Loading