Skip to content

server: jitter BFD control packet transmission - #3581

Open
notsrch wants to merge 1 commit into
osrg:masterfrom
notsrch:fix-3562-bfd-tx-jitter
Open

server: jitter BFD control packet transmission#3581
notsrch wants to merge 1 commit into
osrg:masterfrom
notsrch:fix-3562-bfd-tx-jitter

Conversation

@notsrch

@notsrch notsrch commented Sep 1, 2026

Copy link
Copy Markdown
Contributor

Fixes #3562.

What was wrong

The BFD transmit path drove transmission with a fixed time.Ticker, so every control packet left
exactly on the configured period. RFC 5880 section 6.8.7 requires the interval to be reduced on
every packet by a random value of 0 to 25%, and to stay between 75% and 90% of the transmission
interval when the detect multiplier is 1. Without jitter, sessions that start at similar times stay
in lockstep, and a speaker with many BFD peers on the same interval transmits them as a repeating
burst instead of spreading them across the period.

What this changes

eventTx becomes a *time.Timer that the peer loop re-arms before each transmission with a fresh
interval: a uniformly random 75% to 100% of the configured desired minimum TX interval, narrowed to
75% to 90% when the detect multiplier is 1. Re-arming before the packet is written keeps the time
spent sending out of the gap between packets, which matters against the 90% ceiling in the
multiplier-1 case.

The issue asked which random source to use: this uses randRange, which already picks the BFD
source port. It draws whole percentage points rather than a continuous value (as the FSM's idle
hold-time jitter does), because 26 discrete values are directly assertable in a test and the RFC
only requires a random reduction within the window.

Jitter only shortens intervals, so the remote system's detection margin widens; it never rises
above the configured interval. Event-driven packets — poll replies and the poll sent on reaching
Up — are not periodic transmissions and are unchanged.

Out of scope, as proposed in the issue: raising the transmit interval to the peer's Required Min RX
Interval (#3563) and slowing transmission to one second while the session is down (#3564). Both
only change what base interval feeds the jitter, which now lives in one method; this PR changes the
type of eventTx first so those can follow in sequence.

Checks from the issue

  • Intervals vary within the required window: Test_JitteredTxInterval draws the interval 1000
    times per case and asserts the observed minimum and maximum land exactly on 75% and 100% of the
    configured interval. Endpoint equality also bounds every sample in between. The chance either
    endpoint never appears is about 1e-17, so the test is not timing-dependent and cannot flake the
    way a wall-clock packet capture in CI would.
  • Detect multiplier 1 stays within 75% to 90%: the second half of the same test asserts the
    narrowed endpoints (75% and 90%) for a multiplier-1 peer.
  • Mean rate and session health: the mean interval is 87.5% of the configured value and never
    exceeds it, so the negotiated rate is still satisfied. Test_TxPacket fails if the timer ever
    stops re-arming, and the pre-existing state-transition and expiry tests all pass unchanged.

go test -race ./pkg/server/ passes.

Assisted-by: Claude noreply@anthropic.com

RFC 5880 section 6.8.7 requires the interval between periodic BFD
control packets to be reduced on every packet by a random value of 0
to 25%, and, when the detect multiplier is 1, to stay between 75% and
90% of the transmission interval. gobgp drove transmission with a
fixed time.Ticker, so every packet left exactly on the configured
period. Sessions that start at similar times therefore stay in
lockstep, and a speaker with many BFD peers on the same interval
transmits them as a repeating burst instead of spreading them across
the period.

Replace the ticker with a timer that is re-armed before each
transmission with a fresh interval: a uniformly random 75% to 100% of
the configured desired minimum TX interval, narrowed to 75% to 90%
when the detect multiplier is 1. Re-arming before the packet is
written keeps the time spent sending out of the gap between packets.
The random source is randRange, which already picks the BFD source
port. A new test pins the inclusive endpoints of both jitter windows.

Fixes osrg#3562

Assisted-by: Claude Sonnet 5 <noreply@anthropic.com>
Assisted-by: Claude Opus 5 <noreply@anthropic.com>
Assisted-by: Claude Fable 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

BFD: control packet transmission carries no jitter, as required by RFC 5880 Section 6.8.7

1 participant