Visitar URL original
virtio/net: Advertise MTU to the guest via VIRTIO_NET_F_MTU by ananos · Pull Request #5828 · firecracker-microvm/firecracker · GitHub
Skip to content

virtio/net: Advertise MTU to the guest via VIRTIO_NET_F_MTU - #5828

Merged
ilstam merged 1 commit into
firecracker-microvm:mainfrom
nubificus:feat_mtu
May 21, 2026
Merged

ilstam merged 1 commit into
firecracker-microvm:mainfrom
nubificus:feat_mtu

Conversation

@ananos

@ananos ananos commented Apr 9, 2026 •

Copy link
Copy Markdown
Contributor

Changes

Add MTU negotiation support to the virtio-net device. The tap interface MTU is read using SIOCGIFMTU and stored in the ConfigSpace alongside the MAC address, with the intermediate padding fields (_status, _max_virtqueue_pairs) added to match the virtio_net_config layout.

VIRTIO_NET_F_MTU is advertised in the available features so the guest driver can read the MTU from the config space and configure the network interface accordingly, avoiding fragmentation or oversized-packet issues when the underlying tap MTU differs from the default.

Reason

An MTU != 1500 is not honored in the VM, causing packet drops from the VM.

License Acceptance

By submitting this pull request, I confirm that my contribution is made under
the terms of the Apache 2.0 license. For more information on following Developer
Certificate of Origin and signing off your commits, please check
CONTRIBUTING.md.

PR Checklist

  • I have read and understand CONTRIBUTING.md.
  • I have run tools/devtool checkbuild --all to verify that the PR passes
    build checks on all supported architectures.
  • I have run tools/devtool checkstyle to verify that the PR passes the
    automated style checks.
  • I have described what is done in these changes, why they are needed, and
    how they are solving the problem in a clear and encompassing way.
  • I have updated any relevant documentation (both in code and in the docs)
    in the PR.
  • I have mentioned all user-facing changes in CHANGELOG.md.
  • If a specific issue led to this PR, this PR closes the issue.
  • When making API changes, I have followed the
    Runbook for Firecracker API changes.
  • I have tested all new and changed functionalities in unit tests and/or
    integration tests.
  • I have linked an issue to every new TODO.

  • This functionality cannot be added in rust-vmm.

@codecov

codecov Bot commented Apr 10, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 82.89%. Comparing base (8efac0b) to head (0f3cf71).

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #5828      +/-   ##
==========================================
+ Coverage   82.88%   82.89%   +0.01%     
==========================================
  Files         277      277              
  Lines       30053    30072      +19     
==========================================
+ Hits        24908    24928      +20     
+ Misses       5145     5144       -1     
Flag Coverage Δ
5.10-m5n.metal 83.19% <100.00%> (?)
5.10-m6a.metal 82.53% <100.00%> (+0.02%) ⬆️
5.10-m6g.metal 79.82% <100.00%> (+0.01%) ⬆️
5.10-m6i.metal 83.19% <100.00%> (?)
5.10-m7a.metal-48xl 82.52% <100.00%> (+0.01%) ⬆️
5.10-m7g.metal 79.82% <100.00%> (+0.01%) ⬆️
5.10-m7i.metal-24xl 83.16% <100.00%> (+0.01%) ⬆️
5.10-m7i.metal-48xl 83.17% <100.00%> (+0.01%) ⬆️
5.10-m8g.metal-24xl 79.82% <100.00%> (+0.01%) ⬆️
5.10-m8g.metal-48xl 79.82% <100.00%> (+0.01%) ⬆️
5.10-m8i.metal-48xl 83.16% <100.00%> (+0.01%) ⬆️
5.10-m8i.metal-96xl 83.16% <100.00%> (+<0.01%) ⬆️
6.1-m5n.metal 83.21% <100.00%> (?)
6.1-m6a.metal 82.55% <100.00%> (+<0.01%) ⬆️
6.1-m6g.metal 79.82% <100.00%> (+0.01%) ⬆️
6.1-m6i.metal 83.21% <100.00%> (+0.01%) ⬆️
6.1-m7a.metal-48xl 82.55% <100.00%> (+0.01%) ⬆️
6.1-m7g.metal 79.82% <100.00%> (+0.01%) ⬆️
6.1-m7i.metal-24xl 83.22% <100.00%> (+<0.01%) ⬆️
6.1-m7i.metal-48xl 83.23% <100.00%> (+<0.01%) ⬆️
6.1-m8g.metal-24xl 79.81% <100.00%> (+0.01%) ⬆️
6.1-m8g.metal-48xl 79.81% <100.00%> (+0.01%) ⬆️
6.1-m8i.metal-48xl 83.23% <100.00%> (+0.01%) ⬆️
6.1-m8i.metal-96xl 83.23% <100.00%> (+<0.01%) ⬆️

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

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@ilstam

ilstam commented Apr 10, 2026

Copy link
Copy Markdown
Contributor

Hi Anastassios,

Thank you for your PR.

We'll need some integration test for this. Perhaps a test where different TAPs are configured with different MTUs in the host and then checking that the guest sees the MTU we expect for each of them? Also, we should probably mention this change in the CHANGELOG.

Add MTU negotiation support to the virtio-net

This seems to purely be advertisement rather than negotiation, right?

Best,
Ilias

@ananos
ananos force-pushed the feat_mtu branch 3 times, most recently from 63ad995 to 060fd39 Compare April 15, 2026 16:16
@ananos
ananos force-pushed the feat_mtu branch 2 times, most recently from 58e8459 to de8ca22 Compare April 16, 2026 16:11
@ilstam ilstam added the Status: Awaiting review Indicates that a pull request is ready to be reviewed label Apr 22, 2026
Comment thread src/vmm/src/devices/virtio/net/tap.rs Resolved
Comment thread CHANGELOG.md Resolved
@ilstam

ilstam commented Apr 28, 2026

Copy link
Copy Markdown
Contributor

Hi Anastassios. Thanks for sending the new version. Could you rebase on top of main and resolve the conflicts so that we can run the full testing pipeline and make sure everything passes?

@ananos
ananos force-pushed the feat_mtu branch 2 times, most recently from f048435 to 4ee57a6 Compare April 28, 2026 11:37
@ananos

ananos commented Apr 28, 2026

Copy link
Copy Markdown
Contributor Author

Hi Anastassios. Thanks for sending the new version. Could you rebase on top of main and resolve the conflicts so that we can run the full testing pipeline and make sure everything passes?

running the tests locally ATM, trying to resolve some linting issues - will let you know when I'm ready to kick off the CI.

@ananos

ananos commented Apr 28, 2026

Copy link
Copy Markdown
Contributor Author

Hi Anastassios. Thanks for sending the new version. Could you rebase on top of main and resolve the conflicts so that we can run the full testing pipeline and make sure everything passes?

running the tests locally ATM, trying to resolve some linting issues - will let you know when I'm ready to kick off the CI.

ok, linters fail with a timeout, but I'm not sure if its this PR changes or some glitch. Can you kick-off the CI and we can iterate?

thanks!

@ilstam

ilstam commented Apr 28, 2026 •

Copy link
Copy Markdown
Contributor

Thinking further about this. I had a quick look at what QEMU does and it doesn't seem to try and detect the MTU. It rather lets the user optionally specify it in the command line. This also works when the backend is something like vhost-user-net which we might want to support in the future. Shall we consider doing the same, i.e. adding an optional 'mtu' setting to the network interface configuration and advertise VIRTIO_NET_F_MTU only when that's set? Would that work for your use-case?

Also a practical difference I noticed is that with VIRTIO_NET_F_MTU set the guest kernel will (rightly) not allow you to configure an MTU higher than what was advertised by the virtio backend. But when VIRTIO_NET_F_MTU is not set there is no limit to what you can configure inside the guest.

@ananos

ananos commented Apr 28, 2026

Copy link
Copy Markdown
Contributor Author

Thinking further about this. I had a quick look at what QEMU does and it doesn't seem to try and detect the MTU. It rather lets the user optionally specify it in the command line. This also works when the backend is something like vhost-user-net which we might want to support in the future. Shall we consider doing the same, i.e. adding an optional 'mtu' setting to the network interface configuration and advertise VIRTIO_NET_F_MTU only when that's set? Would that work for your use-case?

totally agree, happy to include this as well as part of this PR.

Also a practical difference I noticed is that with VIRTIO_NET_F_MTU set the guest kernel will (rightly) not allow you to configure an MTU higher than what was advertised by the virtio backend. But when VIRTIO_NET_F_MTU is not set there is no limit to what you can configure inside the guest.

are you concerned about not being able to use larger MTU sizes even when the host is bound to 1500, when(/if) FC virtio-net supports this kind of functionality (LRO/TSO etc.)?

I'm assuming the config option you suggested resolves this issue. If the config is set, then we take into account the MTU set by the host interface. If not, we ignore it (not advertise it via the driver) and the guest can set whatever they want.

@ilstam

ilstam commented Apr 28, 2026

Copy link
Copy Markdown
Contributor

totally agree, happy to include this as well as part of this PR.

Sounds good.

I'm assuming the config option you suggested resolves this issue.

Yep.

are you concerned about not being able to use larger MTU sizes even when the host is bound to 1500, when(/if) FC virtio-net supports this kind of functionality (LRO/TSO etc.)?

I guess the current behaviour allows you to do weird things such as increasing both the host TAP MTU and the guest interface MTU after starting the VM. I don't know if anyone does this, but if we tried to set VIRTIO_NET_F_MTU unconditionally then we would break things like that.

If the config is set, then we take into account the MTU set by the host interface.

To be clear, the config option will carry the MTU value, so it's on the administrator/operator to specify the MTU value (rather than Firecracker trying to determine it via sysfs or otherwise).

If not, we ignore it (not advertise it via the driver) and the guest can set whatever they want.

Yes, thus preserving the current behaviour by default.

@ananos
ananos force-pushed the feat_mtu branch 3 times, most recently from 12ad4c3 to 9fce4f3 Compare April 28, 2026 20:32
@ananos

ananos commented Apr 28, 2026

Copy link
Copy Markdown
Contributor Author

made an attempt -- have a look at your convenience and let me know if you think the implementation makes sense.

Comment thread src/vmm/src/vmm_config/net.rs Resolved
Comment thread CHANGELOG.md Resolved
@ananos

ananos commented May 17, 2026

Copy link
Copy Markdown
Contributor Author

Hi @ilstam! thanks for your comments - did another pass, have a look and let me know!

thanks!

@ananos
ananos force-pushed the feat_mtu branch 3 times, most recently from 709138d to a537513 Compare May 18, 2026 18:25
@ilstam

ilstam commented May 18, 2026 •

Copy link
Copy Markdown
Contributor

Hey Anastassios. Thanks for the new revision. There are a few test failures in the CI but we should be able to merge this once these are fixed:

test device_manager::pci_mngr::tests::test_device_manager_persistence ... FAILED
test device_manager::persist::tests::test_device_manager_persistence ... FAILED
test rpc_interface::tests::test_runtime_disallowed ... FAILED

[gw0] [ 17%] FAILED integration_tests/functional/test_api.py::test_get_full_config_after_restoring_snapshot[vmlinux-5.10.252-PCI_ON]
[gw0] [ 20%] FAILED integration_tests/functional/test_api.py::test_get_full_config[vmlinux-5.10.252-PCI_ON]

For the integration tests I think this diff should help:

  --- a/tests/integration_tests/functional/test_api.py
  +++ b/tests/integration_tests/functional/test_api.py
  @@ -1347,6 +1347,7 @@
               "guest_mac": net_tools.mac_from_ip(net_iface.guest_ip),
               "iface_id": net_iface.dev_name,
               "host_dev_name": net_iface.tap_name,
  +            "mtu": None,
               "rx_rate_limiter": None,
               "tx_rate_limiter": tx_rl,
           }
  @@ -1479,6 +1480,7 @@
               "iface_id": iface_id,
               "host_dev_name": tap1.name,
               "guest_mac": "06:00:00:00:00:01",
  +            "mtu": None,
               "rx_rate_limiter": None,
               "tx_rate_limiter": tx_rl,
           }

And a similar diff is needed for the Rust tests.

I think you should be able to run these tests locally, but let me know if you need any help.

Comment thread src/vmm/src/rpc_interface.rs Resolved
@ananos
ananos force-pushed the feat_mtu branch 4 times, most recently from ee8826c to 645fb94 Compare May 20, 2026 11:58
@ilstam

ilstam commented May 20, 2026

Copy link
Copy Markdown
Contributor

All tests pass now, just tools/devtool checkstyle is failing:

E   Diff in /firecracker/src/vmm/src/devices/virtio/net/device.rs:1128:
E        };
E        use crate::devices::virtio::net::test_utils::test::TestHelper;
E        use crate::devices::virtio::net::test_utils::{
E   -        NetEvent, NetQueue, TapTrafficSimulator, default_net, enable, if_index, inject_tap_tx_frame,
E   -        set_mac,
E   +        NetEvent, NetQueue, TapTrafficSimulator, default_net, enable, if_index,
E   +        inject_tap_tx_frame, set_mac,
E        };
E        use crate::devices::virtio::queue::VIRTQ_DESC_F_WRITE;
E        use crate::devices::virtio::test_utils::VirtQueue;

@ilstam

ilstam commented May 20, 2026

Copy link
Copy Markdown
Contributor

All tests pass now, just tools/devtool checkstyle is failing:

I think I was looking at an older CI build, the last one passes. I just left one more comment, otherwise it looks good to me.

@ananos

ananos commented May 20, 2026

Copy link
Copy Markdown
Contributor Author

thanks @ilstam! Added the extra check for mtu < 68 + a unit test. Also changed the swagger description since it wouldn't make sense to keep a value that would never be used.

@ananos
ananos force-pushed the feat_mtu branch 2 times, most recently from bb22999 to ea474c7 Compare May 21, 2026 05:49
@ilstam ilstam added the Status: Awaiting review Indicates that a pull request is ready to be reviewed label May 21, 2026
@ananos

ananos commented May 21, 2026

Copy link
Copy Markdown
Contributor Author

I suspect the CI failures are not related to the PR, right?

Add an optional `mtu` field to the `NetworkInterface` API (both the
REST API and JSON config file). When set, the virtio-net device
advertises VIRTIO_NET_F_MTU and places the value in config space at
offset 10 (matching the virtio_net_config layout), allowing the guest
driver to configure the interface MTU automatically.

When `mtu` is absent (the default), VIRTIO_NET_F_MTU is not advertised
and the guest uses its own default MTU — preserving existing behaviour.

Implementation details:
- Extend `ConfigSpace` with padding fields `_status` and
  `_max_virtqueue_pairs` at offsets 6 and 8 to correctly place `mtu`
  at offset 10 per the virtio spec (#[repr(C)], ByteValued safe)
- `Net::new()` and `new_with_tap()` accept `mtu: Option<u16>`; the
  feature bit is set only when `Some`
- `Net::mtu()` accessor reflects the advertised value for use in
  snapshot save and API GET responses
- `NetConfigSpaceState` gains `mtu: Option<u16>` with
  `#[serde(default)]` for backward-compatible snapshot restore
- validate MTU range [68, 65535] in new_with_tap()
- add unit tests for VIRTIO_NET_F_MTU feature bit and mtu()
- Swagger, docs/device-api.md, and CHANGELOG updated accordingly

Signed-off-by: Anastassios Nanos <ananos@nubificus.co.uk>
@ilstam

ilstam commented May 21, 2026

Copy link
Copy Markdown
Contributor

I suspect the CI failures are not related to the PR, right?

That's correct, there's an issue in our CI pipeline and tests are failing on a certain EC2 instance size. Nothing to do with your PR.

I'm waiting for a second reviewer to approve and then we'll merge this.

Could you permit maintainers to edit this pull request? This will allow us to do the final rebase on top of mainline rather than waiting for you to do it (which will always be racy as there are things merged to mainline constantly).

@ananos

ananos commented May 21, 2026

Copy link
Copy Markdown
Contributor Author

Could you permit maintainers to edit this pull request? This will allow us to do the final rebase on top of mainline rather than waiting for you to do it (which will always be racy as there are things merged to mainline constantly).

happy to do so, but I don't think it's possible, due to this: https://github.com/orgs/community/discussions/5634 ...

@ilstam
ilstam enabled auto-merge (rebase) May 21, 2026 15:11
@ilstam
ilstam merged commit e865b9c into firecracker-microvm:main May 21, 2026
7 checks passed
@ilstam

ilstam commented May 21, 2026

Copy link
Copy Markdown
Contributor

Merged, will be deployed with the next Firecracker release in a couple weeks. Thanks.

@ananos
ananos deleted the feat_mtu branch May 21, 2026 17:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Status: Awaiting review Indicates that a pull request is ready to be reviewed

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants