Fix: Parse MTU to Firecracker network configuration - #836
Conversation
Ensure the MTU is retrieved from the container interface and populated in the Interface struct, preventing it from defaulting to 0. Signed-off-by: HARSHVARANDANI <hpvarandani@gmail.com>
Add MTU field to FirecrackerNet config struct and serialize it to the Firecracker config JSON to enable VIRTIO_NET_F_MTU negotiation with the guest. Signed-off-by: HARSHVARANDANI <hpvarandani@gmail.com>
… building Add test cases covering MTU parsing, JSON serialization, and baseline configuration generation for Firecracker. Signed-off-by: HARSHVARANDANI <hpvarandani@gmail.com>
✅ Deploy Preview for urunc canceled.
|
|
Hello @HARSHVARANDANI , thank you for opening the PR. Regarding the test method, we will need to verify that this works end-to-end, meaning that the Firecracker guest getc configured with the MTU we specify. A unit test is not enough for the testing. You can take a look at #564 on how to test this end-to-end. |
|
@cmainas I tested three distinct MTU scenarios: 1. Default network (no MTU pinned)sudo nerdctl --address "$CONTAINERD_ADDR" --namespace "$NAMESPACE" \
run -ti --rm -p 8890:80 --runtime io.containerd.urunc.v2 busybox-fc-test:latestResult: 2. k3s + Flannel networkRan against k3s's containerd socket, explicitly pointed at Flannel's CNI config so the container joins the real overlay network: sudo nerdctl --address /run/k3s/containerd/containerd.sock --namespace k8s.io \
--cni-netconfpath /var/lib/rancher/k3s/agent/etc/cni/net.d \
--cni-path <k3s CNI bin_dir> \
run -ti -p 8887:80 --net cbr0 --runtime io.containerd.urunc.v2 busybox-fc-test:latestCross-checked the expected value against Flannel's own computed MTU on the node: cat /run/flannel/subnet.env # FLANNEL_MTU=1450Result: 3. Custom nerdctl bridge network (arbitrary MTU)To rule out coincidence, created a synthetic network pinned to an unrelated MTU value: sudo nerdctl --address /run/k3s/containerd/containerd.sock --namespace k8s.io \
--cni-netconfpath /var/lib/rancher/k3s/agent/etc/cni/net.d \
network create urunc-mtu-1200 --subnet 10.99.0.0/24 --opt mtu=1200
sudo nerdctl --address /run/k3s/containerd/containerd.sock --namespace k8s.io \
--cni-netconfpath /var/lib/rancher/k3s/agent/etc/cni/net.d \
run -ti --rm -p 8887:80 --net urunc-mtu-1200 --runtime io.containerd.urunc.v2 busybox-fc-test:latestResult: Summary
All three independent, distinct MTU values are correctly negotiated and applied inside the Firecracker guest, confirming the MTU fix works end-to-end for this VMM. Screenshots of each |
|
Thank you @HARSHVARANDANI for the testing. Could you also provide the image you created to replicate the testing/ |
Here is the image link https://hub.docker.com/r/harshpvarandani/firecracker-busybox-initrd-ipconfig |
|
Thanks for taking the time to look into this. The MTU propagation gap in Firecracker is real and worth fixing. However, the current approach would break backwards compatibility with Firecracker versions older than v1.16.0. To verify this, I wrote an (ignore the error in the v1.16.0 invocation, I run this experiment on a Lima VM running on an Apple M1 Pro, which has no nested virtualization) We should find a way to only set this field when a supported Firecracker is installed in the system. Perhaps we could add a new option in [monitors.firecracker]
default_memory_mb = 256
default_vcpus = 1
advertise_mtu = false # requires Firecracker >= 1.16.0 |
|
I agree we should add backwards compatibility for firecracker versions.
As I understand, please correct me if I'm wrong, to add an option in Does this sound good? |
|
This would add the overhead of one extra call to Firecracker for every run. Could you try it out and measure the added latency this check will cost us? If it is very low, we can use your approach. |
|
Except of the extra overhead in the hot path, there are not any cases where a cluster might have multiple Firecracker versions. On the contrary, Firecracker is installed once (and then updated). We do not need to check its version at runtime, since this information is static. |



Description
This PR fixes an issue where the host veth's MTU was not propagated to Firecracker virtual machines.
The dynamic network implementation correctly reads the host veth's MTU, but the static network mode was leaving it unset (defaulting to
0). Furthermore, the Firecracker VMM driver completely lacked support for configuring the MTU in the generatedfc.jsonconfig file. Consequently, the guest Linux kernel defaulted to an MTU of1500regardless of the MTU configured on the host.Specifically, this change:
pkg/network/network_static.goto populate theMTUfield in the returnedInterfacestruct fromredirectLink.Attrs().MTU.mtufield to theFirecrackerNetJSON structure inpkg/unikontainers/hypervisors/firecracker.goand sets it usingargs.Net.MTU. This enablesVIRTIO_NET_F_MTUfeature negotiation with the guest.firecracker_test.go) covering the command construction, JSON config building, and JSON serialization for Firecracker.Related issues
How was this tested?
The unit tests written in
firecracker_test.goverify that the Firecracker command-line constructor (BuildExecCmd) correctly compiles and generates JSON configuration files. The test suite uses a table-driven approach to validate baseline parameters (like boot settings, seccomp filters, custom memory sizes, and virtual CPUs), verify the serialization of both default (1500) and custom (9000) MTU values, assert that zero-value MTUs are omitted from the serialized JSON configuration using the omitempty struct tag, and test the integration of auxiliary configurations such as vsock devices and custom initramfs images.LLM usage
Used Google Antigravity for writing tests and scoping the issue. All changes have been manually reviewed.
Checklist
make lint).make test_ctr,make test_nerdctl,make test_docker,make test_crictl).