ipv6: keep an address alive while its prefix is still advertised - #1182
Open
adamgeorge309 wants to merge 2 commits into
Open
ipv6: keep an address alive while its prefix is still advertised#1182adamgeorge309 wants to merge 2 commits into
adamgeorge309 wants to merge 2 commits into
Conversation
Ipv6InterfaceData stores a valid lifetime expiry per address and lets a caller set it, through assignAddress() and updateMatchingAddressExpiryTimes(), but offers no way to read it back. A caller that has to decide what a new lifetime should be from the lifetime that is left cannot do so. Add getAddressExpiryTime(int i), next to the getAddress(int i) and getAddressType(int i) it matches. Zero means an infinite valid lifetime, the same convention the stored field already uses. No caller yet, so no behaviour changes and no baseline moves.
A host stored the valid and preferred lifetimes it was given when it first
formed an address from an advertised prefix, and nothing ever updated them.
The router repeating the prefix -- which is how a host is meant to keep the
address it holds -- left them untouched, so the address stayed on the
schedule the first advertisement had set, however long the router kept
advertising.
RFC 4862 Section 5.5.3 gives the rule as 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.
processRaPrefixInfoForAddrAutoConf() had no branch for it. It formed an
address when the prefix was new to the interface, took the MIPv6 handover
path when the interface held addresses from another prefix, and did nothing
at all in the case step (e) describes: the same prefix advertised again to a
host already configured from it.
Add that branch, with the three sub-cases the step lists. The valid lifetime
follows the advertisement when it is longer than two hours or longer than
what is left; it is left alone when two hours or less remain, because the
advertisement is not authenticated; otherwise it is cut to two hours. Those
rules are what stops a forged advertisement carrying short valid lifetimes
from expiring every address of a node, while a legitimate advertisement,
which a router repeats, always takes the first case and applies at once. The
preferred lifetime follows the advertisement in every case, as the step says.
Ipv6InterfaceData::updateMatchingAddressExpiryTimes() already did the
storing; it had no caller until now.
An address with an infinite valid lifetime was not autoconfigured from a
Prefix Information option, so step (e) does not speak about it and the
branch leaves it alone.
The new Ipv6_prefix_lifetime_refresh module test 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 forms one address and then keeps
refreshing it. It fails on master, where the refresh never happens.
No fingerprint moves: no shipped example advertises a lifetime short enough
to be reached within its run, so no advertisement in the suite lands on a
prefix the receiving host already holds an address from with a lifetime worth
refreshing.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
A host stored the valid and preferred lifetimes it was given when it first
formed an address from an advertised prefix, and nothing ever updated them. The
router repeating the prefix -- which is how a host is meant to keep the address
it holds -- left them untouched, so the address stayed on the schedule the first
advertisement had set, however long the router kept advertising.
Closes #1180
Two commits: the first adds a getter to a shared component, the second is the
fix that needs it. Read them in that order.
The problem
RFC 4862 Section 5.5.3 step (e) has a host that receives a Prefix Information
option for a prefix it already holds an address from reset that address's
preferred lifetime and, under three sub-cases, its valid lifetime.
processRaPrefixInfoForAddrAutoConf()had no branch for that case at all. Itformed an address when the prefix was new to the interface, took the MIPv6
handover path when the interface held addresses from another prefix, and did
nothing when the same router repeated the same prefix.
Ipv6InterfaceData::updateMatchingAddressExpiryTimes(), which does the storing,had no caller anywhere in the tree.
The other half of Section 5.5.3 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.
The fix
The branch is added with all three sub-cases. The valid lifetime follows the
advertisement when it is longer than two hours or longer than what is left; it
is left alone when two hours or less remain, because the advertisement is not
authenticated; otherwise it is cut to two hours. Those rules are what stops a
forged advertisement carrying short valid lifetimes from expiring every address
of a node, while a legitimate advertisement, which a router repeats, always
takes the first case and applies at once. The preferred lifetime follows the
advertisement in every case, as the step says.
An address with an infinite valid lifetime was not autoconfigured from a Prefix
Information option, so step (e) does not speak about it and the branch leaves it
alone.
Why the first commit is separate
Ipv6InterfaceDatastored a per-address valid lifetime expiry and let a callerset it, through
assignAddress()andupdateMatchingAddressExpiryTimes(), butoffered no way to read it back, and step (e) has to decide the new valid lifetime
from the lifetime that is left.
getAddressExpiryTime(int i)is a change to ashared component with its own audience, so it is its own commit and comes first
(PR-SPLIT-UPSTREAM). It adds no caller of its own, so it changes no behaviour and
moves no baseline.
Verification
Unmodified master gives 1774 rows with 3 failures and 62 errors, and so does
this branch. The 62 errors are disabled optional features --
VoIPStream,TcpLwip,VoipStreamSender-- and have nothing to do with IPv6. The 3 failuresare
examples/ipv6/mipv6HandoverandRouteOptimizationTwoCNsandexamples/ipv6/mipv6roamingRoaming, all~tNlbrows ofmipv6-refactoring.csv. Their recorded values are stale on master already, sothey keep them here; re-recording them would absorb that staleness rather than
fix it.
No fingerprint moves, and none is expected: no shipped example advertises a
lifetime short enough to be reached within its run, so no advertisement in the
suite lands on a prefix the receiving host already holds an address from with a
lifetime worth refreshing. The whole 1774-row suite was still run, on both
commits, to show that.
Module tests: 43 tests, 41 pass.
MIPv6_tcp_handoverandIPv6_packet_too_bigfail identically on unmodified master. The 43rd is the new
Ipv6_prefix_lifetime_refresh, which fails on master and passes here.Protocol tests,
tests/protocol/ipv6: 29 tests, 21 pass and 8 expected failures-- the same result as unmodified master.
check-commits.shpasses.check-architecture.shandcheck-naming.shreportonly candidates already present on master, in
src/inet/applications/sctpapp,src/inet/applications/rtpappandimages/misc.Architectural surface
Ipv6InterfaceDatagains one const getter,getAddressExpiryTime(int i). Nopacket content, configuration surface, feature descriptor or contract changes,
and no sealed path is touched. The new module test is named
Ipv6_prefix_lifetime_refresh.testrather thanIPv6_..., so it does not widenthe open
NV-16row; no newAV-*orNV-*row is needed.Not addressed here
Ipv6InterfaceData::getPreferredAddress()(Ipv6InterfaceData.h:559) andgetGlobalAddress()(Ipv6InterfaceData.cc:777) return an address withoutchecking whether its lifetimes have run out; both carry a
FIXMEsaying so. Andnothing removes an address when its valid lifetime expires -- it survives until
the next unrelated change to the interface's address list runs
choosePreferredAddress(). Until both are repaired, a stale lifetime has noeffect a running simulation can see, which is why this defect needs a module test
to demonstrate it and moves no fingerprint.
Two further Neighbour Discovery conformance defects are fixed separately, in
#1178 (the initial Router Advertisement clamp) and #1179 (the Duplicate Address
Detection delay).