Skip to content

device: serialize nonce stamping with the outbound enqueue - #103

Merged
illotum merged 1 commit into
tailscalefrom
illotum/nonce-multiqueue
Sep 28, 2026
Merged

illotum merged 1 commit into
tailscalefrom
illotum/nonce-multiqueue

Conversation

@illotum

@illotum illotum commented Sep 25, 2026

Copy link
Copy Markdown

SendStagedPackets stamps keypair.sendNonce and enqueues to peer.queue.outbound as two steps. Two TUN readers staging for the same peer can invert them, and the sequential sender then puts those packets on the wire out of nonce order.

Pinning the read side to match, which would keep stamping serial without a lock, is not open to us: the kernel hashes the 5-tuple with a siphash keyed by an unexported random value that userspace cannot reproduce, and overriding it requires TUNSETSTEERINGEBPF.

The following was measured on builds instrumented to observe reorder events and max reorder distance. 12-core hosts, TX, 25s runs, 3 rounds, a custom load generator rotating at speed through UDP flows:

2 conn / 2 tun queues, 1 peer x 16 streams, ~1000 new flows/s
before 20.36 Gb/s 3.892 cores/Gb/s reordered 2107, 1645, 1448
after 20.58 Gb/s 3.885 cores/Gb/s reordered 0, 0, 0

Max reorder distance was 47.

Updates: tailscale/corp#37878

Change-Id: I0894d39a928aadc28a58939e7125f9a26a6a6964

This comment was marked as low quality.

@jwhited jwhited left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Just docs nits. LGTM.

Comment thread tun/tun.go
Comment thread device/peer.go Outdated
Comment thread device/send.go Outdated
@illotum
illotum force-pushed the illotum/nonce-multiqueue branch from 85ed634 to 5be9a3a Compare September 28, 2026 20:46
SendStagedPackets stamps keypair.sendNonce and enqueues to
peer.queue.outbound as two steps. Two TUN readers staging for the same
peer can invert them, and the sequential sender then puts those packets
on the wire out of nonce order.

Pinning the read side to match, which would keep stamping serial without
a lock, is not open to us: the kernel hashes the 5-tuple with a siphash
keyed by an unexported random value that userspace cannot reproduce, and
overriding it requires TUNSETSTEERINGEBPF.

The following was measured on builds instrumented to observe reorder
events and max reorder distance. 12-core hosts, TX, 25s runs, 3 rounds,
a custom load generator rotating at speed through UDP flows:

  2 conn / 2 tun queues, 1 peer x 16 streams, ~1000 new flows/s
    before  20.36 Gb/s  3.892 cores/Gb/s  reordered 2107, 1645, 1448
    after   20.58 Gb/s  3.885 cores/Gb/s  reordered 0, 0, 0

Max reorder distance was 47.

Updates: tailscale/corp#37878
Signed-off-by: Alex Valiushko <alexvaliushko@tailscale.com>
Change-Id: I0894d39a928aadc28a58939e7125f9a26a6a6964
@illotum
illotum force-pushed the illotum/nonce-multiqueue branch from 5be9a3a to e4c0118 Compare September 28, 2026 21:28
@illotum
illotum merged commit e61b6b7 into tailscale Sep 28, 2026
15 checks passed
@illotum
illotum deleted the illotum/nonce-multiqueue branch September 28, 2026 21:35
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.

3 participants