Skip to content

mipv6: complete a first home registration in a single Binding Update - #1134

Open
adamgeorge309 wants to merge 2 commits into
masterfrom
topic/gy/mipv6-first-registration-timer
Open

mipv6: complete a first home registration in a single Binding Update#1134
adamgeorge309 wants to merge 2 commits into
masterfrom
topic/gy/mipv6-first-registration-timer

Conversation

@adamgeorge309

@adamgeorge309 adamgeorge309 commented Aug 19, 2026

Copy link
Copy Markdown
Contributor

Makes a first Mobile IPv6 home registration complete in a single Binding Update, as
RFC 6275 intends. Two independent defects had to be fixed together; either one alone
leaves the behaviour unchanged.

Closes #1132
Closes #1133

The problem

The Home Agent (HA) models Duplicate Address Detection (DAD) as a 1 second delay before
it returns the Binding Acknowledgement (BA) for a new home address, which matches
DupAddrDetectTransmits x RetransTimer. The Mobile Node (MN) waited exactly 1 second
before retransmitting, so the Binding Acknowledgement (BA) could never win. Measured in
examples/ipv6/mipv6 -c Handover before the fix:

Event Time (s)
Binding Update (BU) #1 sent by Mobile Node (MN) 21.750074
Binding Update (BU) #1 received by Home Agent (HA) 21.750737
Mobile Node (MN) retransmission timer expires (+1.000 s) 22.750074
Binding Update (BU) #2 sent 22.750074
Binding Acknowledgement (BA) for Binding Update (BU) #1 arrives 22.752424
Binding Acknowledgement (BA) for Binding Update (BU) #2 arrives 22.753396

The acknowledgement lost by 2.35 ms. RFC 6275 sizes InitialBindackTimeoutFirstReg at
1.5 times the Duplicate Address Detection (DAD) time precisely to provide that margin.

The two defects

1 — the branch that reads the value is unreachable (#1132). Mipv6::createBUTimer()
implements the RFC 6275 section 11.8 rule, but its two-argument overload calls
BindingUpdateList::fetch(), a lookup-or-create, before the four-argument overload
tests !bul->isInBindingUpdateList(buDest). The entry always exists by then, so
_getInitialBindAckTimeoutFirst() was never called on any path. Raising
MIPv6_INITIAL_BINDACK_TIMEOUT_FIRST to 7 changed nothing at all, which is how this
surfaced.

Fixed by testing what the RFC actually names — an existing binding — through
hasActiveBinding(), and only for a home registration, since a Binding Update (BU) sent
to a Correspondent Node (CN) triggers no Duplicate Address Detection (DAD) and keeps
INITIAL_BINDACK_TIMEOUT.

2 — the value itself is wrong (#1133). MIPv6_INITIAL_BINDACK_TIMEOUT_FIRST was 1,
where RFC 3775 and RFC 6275 section 13 specify a default of 1.5 seconds. The definition
also sat inside the section 12 protocol-constants block although it is a section 13
protocol configuration variable, and has been moved to a correctly labelled block.

Why both commits are needed

State Binding Updates (BUs) for the first registration
Before this pull request 2
Value raised to 7 s, branch still dead 2 (no effect whatsoever)
Branch repaired, value left at 1 s 2
Both commits 1

The first commit is behaviour-neutral in isolation, because both constants hold 1 second
at that point. Its fingerprints and module test results are byte-identical to those of its
parent, so every commit on this branch is green.

Verification

  • examples/ipv6/mipv6 -c Handover now sends one Binding Update (BU); the initial timer is
    1.5 s and the Binding Acknowledgement (BA) arrives 1.0012 s after the Binding Update (BU).
  • Fingerprints: the three MIPv6 example rows in tests/fingerprint/examples.csv and in
    tests/fingerprint/mipv6-refactoring.csv are re-recorded and pass. The pmipv6 row is
    deliberately untouched — it is unaffected, and its stale tyf value reproduces identically
    on unmodified master. Three of the re-recorded rows also carried a stale tyf value, and
    mipv6roaming a stale ~tNlb value, before this change; the re-recording absorbs them.
  • MIPv6 module tests: 10 pass. MIPv6_tcp_handover fails identically on unmodified master
    (no TCP data arrives), so that failure is pre-existing and out of scope here.

Not addressed here

RFC 6275 section 13 states that mobile nodes MUST allow InitialBindackTimeoutFirstReg to
be configured by system management. It remains a #define. Exposing it as a NED parameter
next to maxHaBindingLifeTime and maxRrBindingLifeTime is a separate enhancement; #1133
records it.


Open in Devin Review

…n timeout

RFC 6275 section 11.8 requires a mobile node that holds no binding at its home
agent to start the Binding Update retransmission backoff at
InitialBindackTimeoutFirstReg instead of INITIAL_BINDACK_TIMEOUT, so that the
timer outlasts the Duplicate Address Detection the home agent performs before it
acknowledges a first home registration. createBUTimer() carried that branch but
could never enter it: the two-argument overload creates the Binding Update List
entry through fetch(), and the four-argument overload then tests
isInBindingUpdateList() for the absence of that very entry.

Test what the RFC names instead -- an existing binding -- through
hasActiveBinding(), and only for a home registration, because a Binding Update
addressed to a correspondent node causes no Duplicate Address Detection and
keeps the shorter INITIAL_BINDACK_TIMEOUT.

Behaviour is unchanged by this commit on its own: MIPv6_INITIAL_BINDACK_TIMEOUT
and MIPv6_INITIAL_BINDACK_TIMEOUT_FIRST both still hold 1 second, so the revived
branch selects the same value the dead one would have. Verified: the mipv6,
mipv6roaming and pmipv6 fingerprints and the MIPv6 module tests produce results
byte-identical to the parent commit.

Fixes #1132
RFC 3775 and RFC 6275 section 13 give InitialBindackTimeoutFirstReg a default of
1.5 seconds, derived as 1.5 times RetransTimer (RFC 4861) times
DupAddrDetectTransmits (RFC 4862). INET used 1 second, which is exactly the
Duplicate Address Detection delay the home agent applies before it answers a
first home registration, so the timer had no margin left for the round trip. The
Binding Acknowledgement therefore always arrived after the retransmission timer
had already fired, and every first home registration cost two Binding Updates
instead of one. In examples/ipv6/mipv6 -c Handover the acknowledgement lost that
race by 2.35 ms. With 1.5 seconds the registration completes in a single Binding
Update.

Move the definition out of the section 12 protocol constants block as well: it is
a section 13 protocol configuration variable, which is why the RFC writes it in
CamelCase rather than in ALL_CAPS.

Fingerprints: the three MIPv6 example rows in tests/fingerprint/examples.csv and
in tests/fingerprint/mipv6-refactoring.csv are re-recorded, because the home
registration now sends one Binding Update rather than two and every later event
shifts. The pmipv6 row is left untouched, as it is unaffected by this change and
its stale tyf value predates it. Three of the re-recorded rows likewise carried a
stale tyf value, and mipv6roaming a stale ~tNlb value, before this commit; the
re-recording absorbs those pre-existing mismatches.

MIPv6 module tests: 10 pass. MIPv6_tcp_handover fails identically here and on the
parent commit -- no TCP data arrives -- so that failure is pre-existing.

Fixes #1133

@devin-ai-integration devin-ai-integration Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Devin Review: No Issues Found

Devin Review analyzed this PR and found no bugs or issues to report.

Open in Devin Review

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

1 participant