Summary
A router re-advertises a prefix periodically so that hosts already holding an
address from it keep that address alive. RFC 4862 has a host that receives a
Prefix Information option for a prefix it already has an address from update
that address's lifetimes. INET never does: a host stores the lifetimes it was
given when it first formed the address, and nothing updates them afterwards.
processRaPrefixInfoForAddrAutoConf(),
src/inet/networklayer/icmpv6/Ipv6NeighbourDiscovery.cc:2464, decides what to do
with a prefix from a Router Advertisement (RA). It has two branches: form a
global address when the prefix is new to the interface
(Ipv6NeighbourDiscovery.cc:2529), and a Mobile IPv6 (MIPv6) handover path when
the interface already holds addresses from a different prefix. The case RFC 4862
describes — the same router re-advertising the same prefix to a host that is
already configured from it — sets isPrefixAssignedToInterface at
Ipv6NeighbourDiscovery.cc:2518 and then falls out of the function without
doing anything.
The method that would do the updating exists and is correct.
src/inet/networklayer/ipv6/Ipv6InterfaceData.cc:317:
void Ipv6InterfaceData::updateMatchingAddressExpiryTimes(const Ipv6Address& prefix, int length,
simtime_t expiryTime, simtime_t prefExpiryTime)
{
for (auto& elem : addresses) {
if (elem.address.matches(prefix, length)) {
elem.expiryTime = expiryTime;
elem.prefExpiryTime = prefExpiryTime;
}
}
choosePreferredAddress();
}
It is declared at src/inet/networklayer/ipv6/Ipv6InterfaceData.h:466 and has no
call sites anywhere in the tree.
What the standard says
RFC 4862 Section 5.5.3, Router Advertisement Processing, step (e):
If the advertised prefix is equal to the prefix of an address configured by
stateless autoconfiguration in the list, the preferred lifetime of the address
is reset to the Preferred Lifetime in the received advertisement. The specific
action to perform for the valid lifetime of the address depends on the Valid
Lifetime in the received advertisement and the remaining time to the valid
lifetime expiration of the previously autoconfigured address. We call the
remaining time "RemainingLifetime" in the following discussion:
-
If the received Valid Lifetime is greater than 2 hours or greater than
RemainingLifetime, set the valid lifetime of the corresponding address to
the advertised Valid Lifetime.
-
If RemainingLifetime is less than or equal to 2 hours, ignore the Prefix
Information option with regards to the valid lifetime, unless the Router
Advertisement from which this option was obtained has been authenticated
(e.g., via Secure Neighbor Discovery [RFC3971]). If the Router
Advertisement was authenticated, the valid lifetime of the corresponding
address should be set to the Valid Lifetime in the received option.
-
Otherwise, reset the valid lifetime of the corresponding address to 2
hours.
The other half of the same section is already implemented: commit 21aca8c
made a Prefix Information option with a zero valid lifetime invalidate the
address autoconfigured from that prefix. Step (e) is the missing half.
Why it matters
An address expires on the schedule set by the first advertisement that produced
it, however many times the router repeats the prefix. With INET's defaults the
advertised valid lifetime is 30 days, so no shipped example reaches it, which is
why this has gone unnoticed.
The effect on a running simulation is currently masked by two further gaps that
INET marks itself. Ipv6InterfaceData::getPreferredAddress()
(Ipv6InterfaceData.h:559) and getGlobalAddress()
(Ipv6InterfaceData.cc:777) both return an address without checking its
lifetimes, and each carries a FIXME saying so; and nothing
removes an expired address until the next unrelated change to the interface's
address list runs choosePreferredAddress(). So today an address whose lifetime
has run out keeps working by accident, and is destroyed at an arbitrary later
moment.
That makes this a correctness defect in the stored state rather than one with a
visible symptom, and it means a simulation that models address lifetimes — a
short-lifetime prefix, a renumbering study, a mobility scenario that relies on
an address being deprecated on schedule — silently produces the wrong answer.
Reproducing it needs an advertised valid lifetime short enough to be reached
within a run, which no shipped example has. The pull request that fixes this adds
tests/module/Ipv6_prefix_lifetime_refresh.test, which advertises a prefix with
a 20 s valid lifetime and a 10 s preferred lifetime every 4 s to 6 s over a 60 s
run and checks that the host keeps refreshing the address it formed; it fails on
origin/master at 8ac5675.
Found while surveying the limitations listed by showcases/ipv6/autoconfiguration.
Not a regression: the method appears never to have been wired up.
Summary
A router re-advertises a prefix periodically so that hosts already holding an
address from it keep that address alive. RFC 4862 has a host that receives a
Prefix Information option for a prefix it already has an address from update
that address's lifetimes. INET never does: a host stores the lifetimes it was
given when it first formed the address, and nothing updates them afterwards.
processRaPrefixInfoForAddrAutoConf(),src/inet/networklayer/icmpv6/Ipv6NeighbourDiscovery.cc:2464, decides what to dowith a prefix from a Router Advertisement (RA). It has two branches: form a
global address when the prefix is new to the interface
(
Ipv6NeighbourDiscovery.cc:2529), and a Mobile IPv6 (MIPv6) handover path whenthe interface already holds addresses from a different prefix. The case RFC 4862
describes — the same router re-advertising the same prefix to a host that is
already configured from it — sets
isPrefixAssignedToInterfaceatIpv6NeighbourDiscovery.cc:2518and then falls out of the function withoutdoing anything.
The method that would do the updating exists and is correct.
src/inet/networklayer/ipv6/Ipv6InterfaceData.cc:317:It is declared at
src/inet/networklayer/ipv6/Ipv6InterfaceData.h:466and has nocall sites anywhere in the tree.
What the standard says
RFC 4862 Section 5.5.3, Router Advertisement Processing, step (e):
The other half of the same section is already implemented: commit 21aca8c
made a Prefix Information option with a zero valid lifetime invalidate the
address autoconfigured from that prefix. Step (e) is the missing half.
Why it matters
An address expires on the schedule set by the first advertisement that produced
it, however many times the router repeats the prefix. With INET's defaults the
advertised valid lifetime is 30 days, so no shipped example reaches it, which is
why this has gone unnoticed.
The effect on a running simulation is currently masked by two further gaps that
INET marks itself.
Ipv6InterfaceData::getPreferredAddress()(
Ipv6InterfaceData.h:559) andgetGlobalAddress()(
Ipv6InterfaceData.cc:777) both return an address without checking itslifetimes, and each carries a
FIXMEsaying so; and nothingremoves an expired address until the next unrelated change to the interface's
address list runs
choosePreferredAddress(). So today an address whose lifetimehas run out keeps working by accident, and is destroyed at an arbitrary later
moment.
That makes this a correctness defect in the stored state rather than one with a
visible symptom, and it means a simulation that models address lifetimes — a
short-lifetime prefix, a renumbering study, a mobility scenario that relies on
an address being deprecated on schedule — silently produces the wrong answer.
Reproducing it needs an advertised valid lifetime short enough to be reached
within a run, which no shipped example has. The pull request that fixes this adds
tests/module/Ipv6_prefix_lifetime_refresh.test, which advertises a prefix witha 20 s valid lifetime and a 10 s preferred lifetime every 4 s to 6 s over a 60 s
run and checks that the host keeps refreshing the address it formed; it fails on
origin/masterat 8ac5675.Found while surveying the limitations listed by
showcases/ipv6/autoconfiguration.Not a regression: the method appears never to have been wired up.