Skip to content

chore: Tests for mtu using Linux namespaces#3334

Open
larseggert wants to merge 7 commits intomozilla:mainfrom
larseggert:chore-mtu-more-tests
Open

chore: Tests for mtu using Linux namespaces#3334
larseggert wants to merge 7 commits intomozilla:mainfrom
larseggert:chore-mtu-more-tests

Conversation

@larseggert
Copy link
Collaborator

No description provided.

Copilot AI review requested due to automatic review settings January 20, 2026 11:27
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR adds comprehensive MTU detection tests for Linux using network namespaces, enabling testing of complex networking scenarios that require root privileges.

Changes:

  • Adds a new test file mtu/tests/netns.rs with network namespace-based MTU detection tests
  • Extends CI pipeline to run these tests with elevated privileges on Ubuntu
  • Tests cover various scenarios: custom MTUs, jumbo frames, multiple interfaces, loopback, and policy routing

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.

File Description
mtu/tests/netns.rs Implements network namespace test infrastructure and MTU detection test cases for Linux
.github/workflows/check-mtu.yml Adds CI job to run network namespace tests with sudo privileges

@codspeed-hq
Copy link

codspeed-hq bot commented Jan 20, 2026

Merging this PR will degrade performance by 26.76%

⚡ 2 improved benchmarks
❌ 2 regressed benchmarks
✅ 47 untouched benchmarks
⏩ 11 skipped benchmarks1

⚠️ Please fix the performance issues or acknowledge them on CodSpeed.

Performance Changes

Mode Benchmark BASE HEAD Efficiency
WallTime neqo-google 1.7 s 1.6 s +4.8%
WallTime s2n-s2n 618.1 ms 665.2 ms -7.08%
WallTime quiche-neqo 310 ms 423.3 ms -26.76%
WallTime 1-conn/1-100mb-req (aka. Upload) 575.3 ms 533.5 ms +7.83%

Comparing larseggert:chore-mtu-more-tests (c3d49f6) with main (26711da)

Open in CodSpeed

Footnotes

  1. 11 benchmarks were skipped, so the baseline results were used instead. If they were deleted from the codebase, click here and archive them to remove them from the performance reports.

@codecov
Copy link

codecov bot commented Jan 20, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 94.16%. Comparing base (4b3cc44) to head (c3d49f6).
⚠️ Report is 8 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #3334      +/-   ##
==========================================
- Coverage   94.26%   94.16%   -0.10%     
==========================================
  Files         125      129       +4     
  Lines       37973    38338     +365     
  Branches    37973    38338     +365     
==========================================
+ Hits        35795    36101     +306     
- Misses       1339     1388      +49     
- Partials      839      849      +10     
Flag Coverage Δ
freebsd 93.19% <ø> (-0.08%) ⬇️
linux 94.24% <ø> (+<0.01%) ⬆️
macos 94.12% <ø> (-0.03%) ⬇️
windows 94.26% <ø> (+0.02%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

Components Coverage Δ
neqo-common 98.49% <ø> (ø)
neqo-crypto 86.90% <ø> (ø)
neqo-http3 93.91% <100.00%> (+0.02%) ⬆️
neqo-qpack 94.79% <100.00%> (ø)
neqo-transport 95.21% <86.95%> (-0.01%) ⬇️
neqo-udp 82.90% <ø> (ø)
mtu 86.61% <ø> (ø)

],
);

// Route in table 100 via VPN interface.
Copy link
Member

Choose a reason for hiding this comment

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

Doesn't our implementation always use RT_TABLE_MAIN? Would it find routes in table 100?

rtm_table: RT_TABLE_MAIN,

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

That field doesn't matter unless we also give it RTM_F_LOOKUP_TABLE, in which case the output would be filtered to the given table. (The test checks exactly that, two routes with different MTUs in different tables + policy routing.)

Would it be clearer if we used RT_TABLE_UNSPEC in the code?

@github-actions
Copy link
Contributor

Failed Interop Tests

QUIC Interop Runner, client vs. server, differences relative to main at 26711da.

neqo-pr as clientneqo-pr as server
neqo-pr vs. aioquic: A ⚠️L1 C1
neqo-pr vs. go-x-net: A BP BA
neqo-pr vs. haproxy: A BP BA
neqo-pr vs. kwik: BP BA
neqo-pr vs. linuxquic: A 🚀L1 C1
neqo-pr vs. lsquic: L1 C1
neqo-pr vs. msquic: A L1 C1 ⚠️C2
neqo-pr vs. mvfst: A L1 🚀C1 ⚠️BA
neqo-pr vs. neqo: Z ⚠️BA
neqo-pr vs. nginx: A L1 C1 BP BA
neqo-pr vs. ngtcp2: A ⚠️L1 CM
neqo-pr vs. picoquic: A
neqo-pr vs. quic-go: A L1
neqo-pr vs. quiche: A 🚀L1 C1 BP BA
neqo-pr vs. quinn: A L1 C1
neqo-pr vs. s2n-quic: A ⚠️C1 BP BA CM
neqo-pr vs. tquic: S A 🚀C1 BP BA
neqo-pr vs. xquic: A 🚀L1 C1
aioquic vs. neqo-pr: Z 🚀C1 CM
go-x-net vs. neqo-pr: CM
kwik vs. neqo-pr: Z BP BA CM
lsquic vs. neqo-pr: Z 🚀C1
msquic vs. neqo-pr: Z CM
mvfst vs. neqo-pr: Z A L1 C1 CM
neqo vs. neqo-pr: Z
openssl vs. neqo-pr: LR M A CM
picoquic vs. neqo-pr: Z
quic-go vs. neqo-pr: Z CM
quiche vs. neqo-pr: Z CM
quinn vs. neqo-pr: Z ⚠️C1 V2 CM
s2n-quic vs. neqo-pr: 🚀L1 ⚠️BP CM
tquic vs. neqo-pr: Z CM
xquic vs. neqo-pr: M CM
All results

Succeeded Interop Tests

QUIC Interop Runner, client vs. server

neqo-pr as client

neqo-pr as server

Unsupported Interop Tests

QUIC Interop Runner, client vs. server

neqo-pr as client

neqo-pr as server

@github-actions
Copy link
Contributor

Benchmark results

Significant performance differences relative to 26711da.

transfer/1-conn/10_000-parallel-1b-resp (aka. RPS)/mtu-1504: 💔 Performance has regressed by +2.2959%.
       time:   [282.57 ms 284.43 ms 286.28 ms]
       thrpt:  [34.931 Kelem/s 35.158 Kelem/s 35.389 Kelem/s]
change:
       time:   [+1.3009% +2.2959% +3.3470] (p = 0.00 < 0.05)
       thrpt:  [-3.2386% -2.2444% -1.2842]
       Performance has regressed.
All results
transfer/1-conn/1-100mb-resp (aka. Download)/mtu-1504: Change within noise threshold.
       time:   [199.43 ms 199.81 ms 200.23 ms]
       thrpt:  [499.42 MiB/s 500.48 MiB/s 501.43 MiB/s]
change:
       time:   [-0.9418% -0.5196% -0.1758] (p = 0.00 < 0.05)
       thrpt:  [+0.1761% +0.5224% +0.9507]
       Change within noise threshold.
Found 4 outliers among 100 measurements (4.00%)
3 (3.00%) high mild
1 (1.00%) high severe
transfer/1-conn/10_000-parallel-1b-resp (aka. RPS)/mtu-1504: 💔 Performance has regressed by +2.2959%.
       time:   [282.57 ms 284.43 ms 286.28 ms]
       thrpt:  [34.931 Kelem/s 35.158 Kelem/s 35.389 Kelem/s]
change:
       time:   [+1.3009% +2.2959% +3.3470] (p = 0.00 < 0.05)
       thrpt:  [-3.2386% -2.2444% -1.2842]
       Performance has regressed.
transfer/1-conn/1-1b-resp (aka. HPS)/mtu-1504: No change in performance detected.
       time:   [38.556 ms 38.726 ms 38.914 ms]
       thrpt:  [25.698   B/s 25.822   B/s 25.936   B/s]
change:
       time:   [-1.3804% -0.6442% +0.0993] (p = 0.08 > 0.05)
       thrpt:  [-0.0992% +0.6484% +1.3998]
       No change in performance detected.
Found 9 outliers among 100 measurements (9.00%)
2 (2.00%) high mild
7 (7.00%) high severe
transfer/1-conn/1-100mb-req (aka. Upload)/mtu-1504: Change within noise threshold.
       time:   [204.00 ms 204.37 ms 204.78 ms]
       thrpt:  [488.34 MiB/s 489.31 MiB/s 490.19 MiB/s]
change:
       time:   [+0.2101% +0.4653% +0.7318] (p = 0.00 < 0.05)
       thrpt:  [-0.7265% -0.4632% -0.2097]
       Change within noise threshold.
Found 2 outliers among 100 measurements (2.00%)
1 (1.00%) high mild
1 (1.00%) high severe
decode 4096 bytes, mask ff: No change in performance detected.
       time:   [4.5185 µs 4.5299 µs 4.5426 µs]
       change: [-0.0958% +0.4764% +1.1918] (p = 0.15 > 0.05)
       No change in performance detected.
Found 5 outliers among 100 measurements (5.00%)
2 (2.00%) high mild
3 (3.00%) high severe
decode 1048576 bytes, mask ff: No change in performance detected.
       time:   [1.1572 ms 1.1591 ms 1.1609 ms]
       change: [-0.5913% -0.1013% +0.3345] (p = 0.68 > 0.05)
       No change in performance detected.
Found 12 outliers among 100 measurements (12.00%)
10 (10.00%) low severe
2 (2.00%) high mild
decode 4096 bytes, mask 7f: No change in performance detected.
       time:   [5.7916 µs 5.8009 µs 5.8110 µs]
       change: [-0.1517% +0.1397% +0.4498] (p = 0.39 > 0.05)
       No change in performance detected.
Found 5 outliers among 100 measurements (5.00%)
2 (2.00%) high mild
3 (3.00%) high severe
decode 1048576 bytes, mask 7f: No change in performance detected.
       time:   [1.4864 ms 1.4890 ms 1.4920 ms]
       change: [-0.5096% -0.0492% +0.3427] (p = 0.83 > 0.05)
       No change in performance detected.
Found 1 outliers among 100 measurements (1.00%)
1 (1.00%) high mild
decode 4096 bytes, mask 3f: No change in performance detected.
       time:   [5.5403 µs 5.5504 µs 5.5616 µs]
       change: [-0.2254% +0.0465% +0.3195] (p = 0.75 > 0.05)
       No change in performance detected.
Found 4 outliers among 100 measurements (4.00%)
2 (2.00%) high mild
2 (2.00%) high severe
decode 1048576 bytes, mask 3f: No change in performance detected.
       time:   [1.4145 ms 1.4169 ms 1.4194 ms]
       change: [-0.2366% -0.0091% +0.2174] (p = 0.94 > 0.05)
       No change in performance detected.
Found 1 outliers among 100 measurements (1.00%)
1 (1.00%) high mild
streams/simulated/1-streams/each-1000-bytes: No change in performance detected.
       time:   [129.68 ms 129.68 ms 129.68 ms]
       thrpt:  [7.5303 KiB/s 7.5306 KiB/s 7.5308 KiB/s]
change:
       time:   [-0.0042% -0.0006% +0.0029] (p = 0.75 > 0.05)
       thrpt:  [-0.0029% +0.0006% +0.0042]
       No change in performance detected.
Found 2 outliers among 100 measurements (2.00%)
2 (2.00%) high mild
streams/simulated/1000-streams/each-1-bytes: No change in performance detected.
       time:   [2.5363 s 2.5366 s 2.5369 s]
       thrpt:  [394.18   B/s 394.22   B/s 394.27   B/s]
change:
       time:   [-0.0084% +0.0084% +0.0255] (p = 0.34 > 0.05)
       thrpt:  [-0.0255% -0.0084% +0.0084]
       No change in performance detected.
streams/simulated/1000-streams/each-1000-bytes: No change in performance detected.
       time:   [6.5848 s 6.5931 s 6.6027 s]
       thrpt:  [147.90 KiB/s 148.12 KiB/s 148.31 KiB/s]
change:
       time:   [-0.3039% -0.0790% +0.1365] (p = 0.47 > 0.05)
       thrpt:  [-0.1363% +0.0791% +0.3048]
       No change in performance detected.
Found 6 outliers among 100 measurements (6.00%)
1 (1.00%) high mild
5 (5.00%) high severe
streams/walltime/1-streams/each-1000-bytes: No change in performance detected.
       time:   [588.30 µs 590.18 µs 592.35 µs]
       change: [-0.2876% +0.2560% +0.7982] (p = 0.36 > 0.05)
       No change in performance detected.
Found 8 outliers among 100 measurements (8.00%)
1 (1.00%) high mild
7 (7.00%) high severe
streams/walltime/1000-streams/each-1-bytes: No change in performance detected.
       time:   [12.528 ms 12.567 ms 12.625 ms]
       change: [-0.2700% +0.2646% +0.7930] (p = 0.38 > 0.05)
       No change in performance detected.
Found 2 outliers among 100 measurements (2.00%)
1 (1.00%) high mild
1 (1.00%) high severe
streams/walltime/1000-streams/each-1000-bytes: Change within noise threshold.
       time:   [45.444 ms 45.487 ms 45.532 ms]
       change: [-0.4150% -0.2606% -0.1168] (p = 0.00 < 0.05)
       Change within noise threshold.
Found 1 outliers among 100 measurements (1.00%)
1 (1.00%) high severe
coalesce_acked_from_zero 1+1 entries: No change in performance detected.
       time:   [91.949 ns 92.253 ns 92.563 ns]
       change: [-0.7885% -0.1905% +0.3182] (p = 0.51 > 0.05)
       No change in performance detected.
Found 10 outliers among 100 measurements (10.00%)
6 (6.00%) high mild
4 (4.00%) high severe
coalesce_acked_from_zero 3+1 entries: No change in performance detected.
       time:   [109.82 ns 110.22 ns 110.63 ns]
       change: [-0.6153% +0.0556% +0.6823] (p = 0.88 > 0.05)
       No change in performance detected.
Found 17 outliers among 100 measurements (17.00%)
3 (3.00%) low mild
1 (1.00%) high mild
13 (13.00%) high severe
coalesce_acked_from_zero 10+1 entries: No change in performance detected.
       time:   [109.08 ns 109.42 ns 109.85 ns]
       change: [-1.0757% -0.3440% +0.1797] (p = 0.35 > 0.05)
       No change in performance detected.
Found 19 outliers among 100 measurements (19.00%)
6 (6.00%) low severe
5 (5.00%) low mild
2 (2.00%) high mild
6 (6.00%) high severe
coalesce_acked_from_zero 1000+1 entries: No change in performance detected.
       time:   [94.872 ns 95.056 ns 95.244 ns]
       change: [-0.4210% +0.1215% +0.6939] (p = 0.67 > 0.05)
       No change in performance detected.
Found 8 outliers among 100 measurements (8.00%)
6 (6.00%) high mild
2 (2.00%) high severe
RxStreamOrderer::inbound_frame(): Change within noise threshold.
       time:   [109.13 ms 109.26 ms 109.44 ms]
       change: [-0.8620% -0.5546% -0.3048] (p = 0.00 < 0.05)
       Change within noise threshold.
Found 15 outliers among 100 measurements (15.00%)
6 (6.00%) low mild
5 (5.00%) high mild
4 (4.00%) high severe
sent::Packets::take_ranges: No change in performance detected.
       time:   [4.4791 µs 4.5730 µs 4.6590 µs]
       change: [-3.4618% -0.2367% +3.0106] (p = 0.89 > 0.05)
       No change in performance detected.
Found 1 outliers among 100 measurements (1.00%)
1 (1.00%) high mild
transfer/simulated/pacing-false/varying-seeds: No change in performance detected.
       time:   [23.941 s 23.941 s 23.941 s]
       thrpt:  [171.09 KiB/s 171.09 KiB/s 171.09 KiB/s]
change:
       time:   [+0.0000% +0.0000% +0.0000] (p = NaN > 0.05)
       thrpt:  [+0.0000% +0.0000% +0.0000]
       No change in performance detected.
transfer/simulated/pacing-true/varying-seeds: No change in performance detected.
       time:   [23.676 s 23.676 s 23.676 s]
       thrpt:  [173.01 KiB/s 173.01 KiB/s 173.01 KiB/s]
change:
       time:   [+0.0000% +0.0000% +0.0000] (p = NaN > 0.05)
       thrpt:  [+0.0000% +0.0000% +0.0000]
       No change in performance detected.
transfer/simulated/pacing-false/same-seed: No change in performance detected.
       time:   [23.941 s 23.941 s 23.941 s]
       thrpt:  [171.09 KiB/s 171.09 KiB/s 171.09 KiB/s]
change:
       time:   [+0.0000% +0.0000% +0.0000] (p = NaN > 0.05)
       thrpt:  [+0.0000% +0.0000% +0.0000]
       No change in performance detected.
transfer/simulated/pacing-true/same-seed: No change in performance detected.
       time:   [23.676 s 23.676 s 23.676 s]
       thrpt:  [173.01 KiB/s 173.01 KiB/s 173.01 KiB/s]
change:
       time:   [+0.0000% +0.0000% +0.0000] (p = NaN > 0.05)
       thrpt:  [+0.0000% +0.0000% +0.0000]
       No change in performance detected.
transfer/walltime/pacing-false/varying-seeds: Change within noise threshold.
       time:   [23.066 ms 23.083 ms 23.101 ms]
       change: [+0.2022% +0.3085% +0.4093] (p = 0.00 < 0.05)
       Change within noise threshold.
Found 2 outliers among 100 measurements (2.00%)
2 (2.00%) high mild
transfer/walltime/pacing-true/varying-seeds: Change within noise threshold.
       time:   [23.863 ms 23.877 ms 23.892 ms]
       change: [+1.1994% +1.4055% +1.5614] (p = 0.00 < 0.05)
       Change within noise threshold.
transfer/walltime/pacing-false/same-seed: Change within noise threshold.
       time:   [23.350 ms 23.367 ms 23.383 ms]
       change: [+0.9077% +1.0735% +1.2111] (p = 0.00 < 0.05)
       Change within noise threshold.
Found 8 outliers among 100 measurements (8.00%)
3 (3.00%) low mild
4 (4.00%) high mild
1 (1.00%) high severe
transfer/walltime/pacing-true/same-seed: No change in performance detected.
       time:   [23.652 ms 23.685 ms 23.733 ms]
       change: [-0.3383% -0.1488% +0.0640] (p = 0.17 > 0.05)
       No change in performance detected.
Found 3 outliers among 100 measurements (3.00%)
2 (2.00%) high mild
1 (1.00%) high severe

Download data for profiler.firefox.com or download performance comparison data.

@github-actions
Copy link
Contributor

Client/server transfer results

Performance differences relative to 26711da.

Transfer of 33554432 bytes over loopback, min. 100 runs. All unit-less numbers are in milliseconds.

Client vs. server (params) Mean ± σ Min Max MiB/s ± σ Δ main Δ main
msquic-neqo-cubic 190.1 ± 46.5 147.4 417.5 168.3 ± 0.7 💚 -22.8 -10.7%
neqo-neqo-cubic-nopacing 98.6 ± 4.5 89.7 108.4 324.7 ± 7.1 💔 3.8 4.0%
neqo-quiche-cubic 194.0 ± 4.4 186.7 206.3 165.0 ± 7.3 💔 1.6 0.9%
neqo-s2n-cubic 220.2 ± 4.4 212.3 231.6 145.3 ± 7.3 💔 1.9 0.9%

Table above only shows statistically significant changes. See all results below.

All results

Transfer of 33554432 bytes over loopback, min. 100 runs. All unit-less numbers are in milliseconds.

Client vs. server (params) Mean ± σ Min Max MiB/s ± σ Δ main Δ main
google-google-nopacing 463.8 ± 4.9 456.9 483.6 69.0 ± 6.5
google-neqo-cubic 275.0 ± 3.8 267.5 281.9 116.4 ± 8.4 -0.2 -0.1%
msquic-msquic-nopacing 174.6 ± 52.6 135.6 366.9 183.2 ± 0.6
msquic-neqo-cubic 190.1 ± 46.5 147.4 417.5 168.3 ± 0.7 💚 -22.8 -10.7%
neqo-google-cubic 771.6 ± 7.9 708.9 786.9 41.5 ± 4.1 -0.9 -0.1%
neqo-msquic-cubic 160.0 ± 4.5 151.8 168.1 200.0 ± 7.1 -0.8 -0.5%
neqo-neqo-cubic 98.5 ± 4.2 91.5 108.7 325.0 ± 7.6 0.5 0.5%
neqo-neqo-cubic-nopacing 98.6 ± 4.5 89.7 108.4 324.7 ± 7.1 💔 3.8 4.0%
neqo-neqo-newreno 98.5 ± 4.5 89.1 106.7 324.7 ± 7.1 0.3 0.3%
neqo-neqo-newreno-nopacing 97.1 ± 3.9 90.6 105.6 329.6 ± 8.2 -0.5 -0.6%
neqo-quiche-cubic 194.0 ± 4.4 186.7 206.3 165.0 ± 7.3 💔 1.6 0.9%
neqo-s2n-cubic 220.2 ± 4.4 212.3 231.6 145.3 ± 7.3 💔 1.9 0.9%
quiche-neqo-cubic 154.7 ± 7.2 140.5 192.8 206.8 ± 4.4 1.2 0.8%
quiche-quiche-nopacing 147.1 ± 4.3 139.5 160.6 217.6 ± 7.4
s2n-neqo-cubic 175.3 ± 5.2 166.6 187.2 182.5 ± 6.2 0.5 0.3%
s2n-s2n-nopacing 248.1 ± 22.9 232.9 349.1 129.0 ± 1.4

Download data for profiler.firefox.com or download performance comparison data.

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