mipv6: verify the home address before acknowledging a home registration - #1195
Open
adamgeorge309 wants to merge 2 commits into
Open
mipv6: verify the home address before acknowledging a home registration#1195adamgeorge309 wants to merge 2 commits into
adamgeorge309 wants to merge 2 commits into
Conversation
Ipv6NeighbourDiscovery could run Duplicate Address Detection only for an address it was about to assign: initiateDad() puts the address on the interface, and makeTentativeAddressPermanent() keeps it there when the probe succeeds. RFC 6275 Section 10.3.1 needs the other shape. Before a home agent accepts a first home registration it must run Duplicate Address Detection for the mobile node's home address on the home link -- an address it must not take for itself, because Ipv6InterfaceData::hasAddress() answers true for a tentative address as well, so assigning it would make the home agent start accepting packets that belong to the mobile node. Add startAddressProbe(), which sends the RFC 4862 Section 5.4.2 solicitations without ever touching the interface and reports the outcome through the new IAddressProbeHandler interface. cancelAddressProbe() abandons a probe, and isAddressProbeRunning() lets a caller that holds state for the duration of one notice a probe that ended without a callback -- stop() drops the probe list, so the callback is promised at most once, not exactly once. The random RFC 4862 Section 5.4.2 term delays the first solicitation, rather than being added to the timeout as initiateDad() does. The join must precede the solicitation, so delaying the join delays the solicitation with it; adding it to the timeout instead is issue #1179, which pull request #1183 repairs for initiateDad(). The total wait is the same either way, so this only decides when the solicitation leaves, and a new probe should not be written with the defect in it. Probing an address this node already holds reports it in use rather than asserting. That is the honest answer to the question the probe asks, and it is the state a home agent will be in once it proxies the address. A duplicate is reported when another node defends the address with a Neighbor Advertisement, which arrives because a defending advertisement goes to the all-nodes multicast address. The competing case -- another node running Duplicate Address Detection for the same address at the same time -- is not reported. That solicitation goes to the solicited-node multicast address of the probed address, and two gates stop it: Ipv6::routeMulticastPacket() delivers a multicast locally only if the node holds the address or joined the group, and processNsPacket() then discards a solicitation whose target the node does not hold. A proxying home agent passes both, so that case belongs with the proxy Neighbor Discovery work. There is no caller yet, so no behaviour changes and no baseline moves.
RFC 6275 Section 10.3.1:
Unless this home agent already has a binding for the given home address, the
home agent MUST perform Duplicate Address Detection on the mobile node's
home link before returning the Binding Acknowledgement. ... If this
Duplicate Address Detection fails for the given home address or an
associated link local address, then the home agent MUST reject the complete
Binding Update and MUST return a Binding Acknowledgement to the mobile node,
in which the Status field is set to 134.
Neither half was implemented. The check was replaced by a hardcoded one second
delay on the acknowledgement, sendTime = existingBinding ? 0 : 1, carrying the
admission "TODO solve the HA DAD problem in a different way"; the rejection
path was a bare TODO, so status 134 could never be sent.
Reproduce the defect on the unfixed tree:
cd examples/ipv6/mipv6
inet -u Cmdenv -c Handover -r 0 --seed-set=1 --sim-time-limit=25s \
--cmdenv-express-mode=false --cmdenv-log-level=off \
'--*.Home_Agent.ipv6.neighbourDiscovery.cmdenv-log-level=trace' \
'--*.Home_Agent.ipv6.mipv6.cmdenv-log-level=info'
The home agent logs Duplicate Address Detection exactly twice, both at
t=0.0436 s for its own two interfaces at boot, and never at t=21.712822 s when
the Binding Update arrives and is validated. No solicitation for the home
address is ever sent. The acknowledgement arrives 1.0015 s after the Binding
Update on every seed set: 1.001527, 1.001727 and 1.001587 s for sets 1 to 3,
one second of sendDelayed plus link latency.
Run the probe instead, and hold the acknowledgement until it ends: status 0
when nobody answers, status 134 with the binding, its tunnel and its expiry
timer withdrawn when another node defends the address. With no caller left
passing a delay, the sendTime parameter and the delayed-send branch it fed go
with it.
Three deltas in behaviour, all intended.
The acknowledgement delay now varies per seed, 1.036, 1.451 and 1.911 s for
seed sets 1 to 3, because real Duplicate Address Detection costs retransTimer
plus the RFC 4862 Section 5.4.2 group-join term. It was a constant standing in
for a quantity that genuinely has spread.
A first registration draws one Binding Acknowledgement instead of two. The
mobile node's retransmission -- its first-registration timeout is one second,
see issues #1132 and #1133 -- used to arrive after the Binding Cache entry
already existed, so it was read as a re-registration and acknowledged at once,
on top of the delayed acknowledgement owed to the original. A registration
still waiting for its probe is no longer a binding the home agent already has.
A home agent that receives a Binding Update with the home registration flag
clear now acknowledges it immediately rather than one second later. Master
delayed every first-time Binding Update a home agent saw; RFC 6275 Section
9.5.4 asks for no Duplicate Address Detection on a correspondent binding.
Three fingerprint rows move, all in examples.csv, and each for the same reason:
the mipv6 Handover, mipv6 RouteOptimizationTwoCNs and mipv6roaming Roaming
scenarios are the only ones in the suite where a home agent accepts a first
home registration. In each, the tplx, ~tNl and ~tND values move because the
acknowledgement now waits for a real probe instead of a constant, because the
home agent's probe solicitations are new packets on the home link, and because
the duplicate acknowledgement is gone. No other row moves: the remaining 13
IPv6 rows matched in examples.csv are unchanged, pmipv6 among them, which
shares the same Ipv6NeighbourDiscovery.
mipv6-refactoring.csv is deliberately not touched. Its three MIPv6 rows already
fail on origin/master 021485b, which was confirmed by building and running
that commit unchanged; the recent IEEE 802.11 and serializer work moved them
and re-recorded examples.csv without them. Re-recording them here would fold
that unrelated movement into this commit.
MIPv6_home_agent_dad covers the success path and pins the acknowledgement count
at one. MIPv6_home_agent_dad_duplicate covers the rejection: a squatter on the
home link carries the mobile node's MAC, so autoconfiguration gives them the
same home address, and Duplicate Address Detection is switched off on both so
that neither defends against the other while they boot. The home agent, which
keeps it on, then probes, is answered, and rejects.
That test also shows a limitation this change makes reachable: the mobile node
logs the rejection but does not act on it, so it retries with the ordinary
Binding Update backoff -- rejections at t=32.8, 33.8, 35.8, 39.8, 47.8, 63.8 s,
doubling to the 32 s cap and never giving up. RFC 6275 Section 11.7.3 asks it to
stop; the code says "retransmission is performed anyway as timers are not
deleted". That is a separate defect on the mobile node's side, previously
unreachable because status 134 could never be sent.
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.
Fixes #1194.
A home agent now runs real Duplicate Address Detection for the mobile node's home address on the
home link before it acknowledges a first home registration, as RFC 6275 Section 10.3.1 requires,
instead of standing a hardcoded one-second delay in for the check. It also rejects the
registration with status 134 when the address turns out to be in use, which was a bare
// TODO.The two commits
ipv6: add an address probe to Neighbour Discoveryadds the capability and nothing else.Ipv6NeighbourDiscoverycould previously run Duplicate Address Detection only for an address itwas about to assign:
initiateDad()puts the address on the interface, andmakeTentativeAddressPermanent()keeps it there on success. A home agent needs the opposite --it must check an address it must not take, because
Ipv6InterfaceData::hasAddress()answerstrue for a tentative address too, so assigning the home address would make the home agent start
accepting the mobile node's packets and destroy the interception the tunnel depends on.
startAddressProbe()sends the RFC 4862 Section 5.4.2 solicitations without touching theinterface and reports the outcome through the new
IAddressProbeHandler.The random Section 5.4.2 term delays the first solicitation here, rather than being added to
the timeout as
initiateDad()does. The join must precede the solicitation, so delaying the joindelays the solicitation with it; adding it to the timeout is #1179, which #1183 repairs for
initiateDad(). The total wait is the same either way, so this only decides when thesolicitation leaves -- but a new probe should not be written with the defect in it. If #1183
lands first there is nothing to reconcile; if this lands first, #1183 brings
initiateDad()tothe same shape.
mipv6: verify the home address before acknowledging a home registrationuses it, andcarries the baseline it moves.
Architecture
IAddressProbeHandleris a new contract, in its own header so thatmipv6can implement itwithout
icmpv6gaining any dependency onmipv6. Nothing else in the surface changes: no NEDfile, no
.msgfile, no packet content, no configuration parameter, no signal.DAD_FAILED = 134already existed in
MobilityHeader.msg. No sealed path is touched, andcheck-architecture.shflags nothing in
icmpv6/ormipv6/.One deliberate deletion: with no caller left passing a delay, the
sendTimeparameter ofcreateAndSendBAMessage()andsendMobilityMessageToIPv6Module()and thesendDelayed()branchit fed are removed, along with the
// TODO solve the HA DAD problem in a different waythat saton them. That TODO was a claim, and this makes good on it; leaving it would describe a mechanism
the change had just deleted.
What changes in behaviour
The delay varies now because Duplicate Address Detection genuinely costs
retransTimerplus theuniform 0-1 s group-join term of RFC 4862 Section 5.4.2.
The double acknowledgement is gone because a registration still waiting for its probe is no longer
treated as a binding the home agent already has. Previously the mobile node's retransmission
arrived after the Binding Cache entry existed, was read as a re-registration, and was acknowledged
immediately on top of the delayed acknowledgement owed to the original.
The third row is a change master made by accident: it delayed every first-time Binding Update a
home agent received, including one with the home registration flag clear. RFC 6275 Section 9.5.4
asks for no Duplicate Address Detection on a correspondent binding, so the guard is now on
homeRegistrationas well.The mobile node still retransmits its first Binding Update on every seed, because the probe
costs
retransTimer(1 s) plus a non-negative term while its own first-registration timeout is1 s (#1132, #1133). It is acknowledged once either way. Whether #1134's 1.5 s changes that has not
been measured here and is not claimed.
Baselines
Three rows move, all in
examples.csv, and they share one explanation:mipv6 Handover,mipv6 RouteOptimizationTwoCNsandmipv6roaming Roamingare the only scenarios in the suitewhere a home agent accepts a first home registration. In each, the
tplx,~tNland~tNDvalues move because the acknowledgement now waits for a real probe instead of a constant, because
the home agent's probe solicitations are new packets on the home link, and because the duplicate
acknowledgement is gone.
Ingredient letters, verified against
omnetpp/include/omnetpp/cfingerprint.handsrc/inet/common/FingerprintCalculator.h:~network-communication filter,tsimulation time,Nnetwork node path,lmessage bit length,Dpacket data,pmodule full path,xextradata.
r(random numbers drawn) appears in none of these specs, so the addeduniform()draw isnot hashed directly; only its effect on packet timing is.
No other row moves. The 13 other IPv6 rows matched in
examples.csvare unchanged:ipv6/pmipv6 General,pim/sm_ipv6,pim/dm_ipv6,pim/ssm_ipv6,inet/ipsecUDPTraffic6/TCPTraffic6/Multicast6,inet/udpclientserverudp_OK_ipv6/udp_Port_Unav_ipv6/udp_Host_Unav_ipv6, andipv6/nclientsETH/PPP/PPP_SCTP.pmipv6matters most of those: it shares the sameIpv6NeighbourDiscoveryand isuntouched. The new code is inert unless a home agent accepts a first home registration.
mipv6-refactoring.csvis deliberately not touched. Its three MIPv6 rows already fail onorigin/master021485b99c-- confirmed by building and running that commit unchanged, whichproduces
ad4c-9f8c,2402-9a6fand464c-536fagainst recorded values ofaa29-a8c5,068b-23aaand7ed8-bee3. The recent IEEE 802.11 and serializer work moved them and re-recordedexamples.csvwithout them. Re-recording them here would fold that unrelated movement into thiscommit, which is exactly what TR-BASELINE-PROVENANCE forbids. They want a separate refresh from
whoever landed that work.
The
tyffingerprints are not re-recorded. They were already stale at the merge base -- theuntouched
pmipv6row failstyftoo -- and the tool itself reports them as not regularly keptup to date. Since
tis one of their ingredients, this change does move them; they are simply nottracked.
How this was verified
From the repository root, with
source setenv, onorigin/master021485b99c:The two failures are
MIPv6_tcp_handoverandIPv6_packet_too_big, both already failing onorigin/masterbefore any change here, and neither file is touched by this branch. Every othertest keeps its verdict; the only difference in the verdict list is the two new tests.
The first commit was checked on its own, with the second stashed: at that commit
examples.csvpasses 16/16 against the un-updated baseline and the module suite reproduces42/40/2 exactly, which is what "adds the capability and nothing else" means.
Tests
MIPv6_home_agent_dadcovers the success path: the home agent holds the acknowledgement,Neighbour Discovery sends a real probe, nobody answers, the registration is acknowledged. It also
pins the acknowledgement count at exactly one, which is the assertion that would have caught the
double acknowledgement.
MIPv6_home_agent_dad_duplicatecovers the rejection. Arranging a duplicate needs one trick worthexplaining: a node holding the home address from the start would defend it against the mobile
node's own autoconfiguration at boot, and the mobile node would never get a home address to
register. So a squatter on the home link carries the mobile node's MAC -- autoconfiguration then
derives the same address for both -- and Duplicate Address Detection is switched off on both so
that neither probes and neither defends while they boot. The home agent keeps it enabled, probes,
is answered, and rejects. The test asserts that no registration is ever accepted.
Both are separate files rather than assertions bolted onto
MIPv6_handover, so that a failurenames which property broke.
A defect this makes reachable
MIPv6_home_agent_dad_duplicateexposes something that could not happen before, because status134 could never be sent: the mobile node logs the rejection and then ignores it.
processBAMessagesays so itself -- "retransmission is performed anyway as timers are not deleted", with a
// TODO store DO_NOT_SEND_BU in BUL. So it retries with the ordinary Binding Update backoff:rejections at t=32.8, 33.8, 35.8, 39.8, 47.8 and 63.8 s, doubling to the 32 s cap and never giving
up. RFC 6275 Section 11.7.3 asks it to stop on a rejection status.
This is a separate defect on the mobile node's side and is not fixed here. It was previously
unreachable, and is worth its own issue.
What this does not do
The binding, its expiry timer and the home-agent tunnel are still installed when the Binding
Update is accepted, before the probe finishes, so for the 1-2 s the probe lasts the home agent is
already tunnelling for an address another node may own. RFC 6275 Section 10.3.1 places Duplicate
Address Detection before the acknowledgement, not before the cache entry, so this follows the
text; it is called out because it is a real window. On rejection all three are withdrawn.
A de-registration that overtakes a running probe cancels it and sends no acknowledgement for the
registration it withdrew. That is a choice, not something the RFC states.
The competing-probe case is deliberately not detected: another node running Duplicate Address
Detection for the same address sends its solicitation to the solicited-node multicast address of
that address, and two gates stop it --
Ipv6::routeMulticastPacket()delivers a multicast locallyonly if the node holds the address or joined the group, and
processNsPacket()then discards asolicitation whose target the node does not hold. Writing that branch today would be unreachable
code. A proxying home agent passes both gates, so it belongs with the proxy Neighbor Discovery
work.
Mipv6::findHomeLinkInterface()duplicates the loop inIpv6RoutingTable::isOnLinkAddress().Companion work on proxy Neighbor Discovery extracts that loop as
Ipv6RoutingTable::findOnLinkInterface(); whichever lands second should fold one into the other.Kept separate here so the two changes do not conflict.
Proxy Neighbor Discovery at the home agent (RFC 6275 Section 10.4.1) is out of scope and filed
separately. Section 10.3.1 governs what must happen before the acknowledgement goes out; Section
10.4.1 governs what must happen on the home link while the binding lives. Different triggers,
independently testable, independently revertible.