Skip to content

[DNM]: Support for lima:shared, lima:bridged, lima:host on Linux hosts - #5433

Draft
unsuman wants to merge 5 commits into
lima-vm:masterfrom
unsuman:net/linux-networking
Draft

[DNM]: Support for lima:shared, lima:bridged, lima:host on Linux hosts#5433
unsuman wants to merge 5 commits into
lima-vm:masterfrom
unsuman:net/linux-networking

Conversation

@unsuman

@unsuman unsuman commented Aug 20, 2026

Copy link
Copy Markdown
Member

What This PR Changes

This PR adds support for non-userV2 networking support on Linux hosts, through a helper privileged binary lima-net placed inside <PREFIX>/libexec/lima/lima-net. It creates a Linux bridge per network and attaches one tap device per instance.

Do not merge this PR as I plan to raise these changes as separate PRs for easy reviewing.

Linked Issue (Required in most cases)

Closes #4371

How I Tested This

On my Fedora Linux 43 (Workstation Edition):

make native && sudo make installlimactl sudoers >etc_sudoers.d_limasudo install -o root etc_sudoers.d_lima /etc/sudoers.d/lima

lima:shared

limactl start --name default --network lima:shared
INFO[0000] Starting `lima-net` daemon for `shared` network: [sudo --user root --group root --non-interactive /usr/local/libexec/lima/lima-net start --pidfile=/run/lima/shared_lima-net.pid --mode=shared --bridge=lima-shared --gateway=192.168.105.1 --dhcp-end=192.168.105.254 --netmask=255.255.255.0] 
INFO[0001] Running: [sudo --user root --group root --non-interactive /usr/local/libexec/lima/lima-net tap --bridge=lima-shared limatapaa651005] limactl start --name def2 --network lima:shared
INFO[0000] Running: [sudo --user root --group root --non-interactive /usr/local/libexec/lima/lima-net tap --bridge=lima-shared limatap1175a187] ip -br addr show lima-shared
lima-shared      UP             192.168.105.1/24 fe80::340e:2bff:fe43:5e10/64        limactl shell default -- ip -4 -br addr show lima0
lima0            UP             192.168.105.33/24 metric 100limactl shell def2 -- ip -4 -br addr show lima0
lima0            UP             192.168.105.176/24 metric 100 ping -c 3 192.168.105.33  # host -> guest
--- 192.168.105.33 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2070ms
rtt min/avg/max/mdev = 0.147/0.151/0.161/0.006 mslimactl shell default -- ping -c 3 192.168.105.176 # guest -> guest
--- 192.168.105.176 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2060ms
rtt min/avg/max/mdev = 0.309/0.357/0.409/0.040 mslimactl shell default -- ping -c 3 -I lima0 8.8.8.8
--- 8.8.8.8 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2003ms
rtt min/avg/max/mdev = 36.203/36.361/36.455/0.112 ms

lima:host

limactl start --name host --network lima:hostlimactl shell host -- ip -4 -br addr show lima0
lima0            UP             192.168.106.11/24 metric 100 limactl shell host -- ping -c 2 192.168.106.1
--- 192.168.106.1 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1003ms
rtt min/avg/max/mdev = 0.142/0.142/0.143/0.000 mslimactl shell host -- ping -c 2 -W 3 -I lima0 8.8.8.8
--- 8.8.8.8 ping statistics ---
2 packets transmitted, 0 received, +2 errors, 100% packet loss, time 1018ms
pipe 2limactl shell host -- ping -c 2 -W 3 -I lima0 192.168.105.33 
--- 192.168.105.33 ping statistics ---
2 packets transmitted, 0 received, +2 errors, 100% packet loss, time 1035ms
pipe 2

lima:bridged

Caution

While using this mode, the host is disconnected from the network as the physical interface is hand over to the guest.

# Create a bridge and attach a physical interface to itsudo ip link add br0 type bridgesudo ip link set enp6s0 master br0sudo ip link set br0 uplimactl start --name bridge --network lima:bridged
INFO[0000] Starting `lima-net` daemon for `bridged` network: [sudo --user root --group root --non-interactive /usr/local/libexec/lima/lima-net start --pidfile=/run/lima/bridged_lima-net.pid --mode=bridged --bridge=br0] 
INFO[0001] Running: [sudo --user root --group root --non-interactive /usr/local/libexec/lima/lima-net tap --bridge=br0 limatapf8e59646]limactl shell bridge -- ip -4 -br addr show lima0
lima0            UP             192.168.0.167/24 metric 100

# To give the interface back to the hostsudo ip link delete br0sudo systemctl restart NetworkManager

AI Usage

Assisted-by: Claude Opus 5

Generalize the daemon handling in pkg/networks, which so far assumed that
socket_vmnet is the only privileged helper, and describe the Linux helper
(lima-net) next to it:

- RequiredDaemons() returns the helpers needed on the current host, so the
  callers no longer have to hardcode socket_vmnet.
- paths.limaNet holds the path of the Linux helper, mirroring paths.socketVMNet.
- StartCmd() renders the lima-net command line, and TapCmd() the command that
  attaches an instance to the bridge of a network.
- TapName() derives a tap device name that fits into IFNAMSIZ, IsTapName()
  recognizes it, and TapNamePattern() renders the matching sudoers wildcard.

lima-net itself is added in a follow-up commit.

Signed-off-by: Ansuman Sahoo <anshumansahoo500@gmail.com>
Linux has no equivalent of socket_vmnet, so add lima-net, a small helper that
limactl runs via sudo to set up the "shared", "host" and "bridged" networks.

`lima-net start` creates (for "shared" and "host") the lima-<name> bridge,
assigns the gateway address, spawns dnsmasq for DHCP, and installs the
NAT/forwarding rules of the "shared" mode. `lima-net tap` creates the tap
device of a single instance, hands it to the calling user, and attaches it to
the bridge. Both take all parameters from the command line rather than reading
the user-writable networks.yaml, because the arguments are what the sudoers
file pins down.

The helper tears the network down again when the last instance leaves, and only
ever touches bridges and tap devices that follow the Lima naming scheme.

Signed-off-by: Ansuman Sahoo <anshumansahoo500@gmail.com>
Teach the networks.yaml defaults, the path validation and the sudoers generator
about Linux hosts:

- The default networks.yaml now points at the lima-net binary in libexec/lima,
  uses /run/lima and /etc/sudoers.d/lima, picks the "sudo" or "wheel" group, and
  documents that "bridged" needs an already existing bridge (Lima never enslaves
  a physical interface).
- Validate() checks whichever of paths.socketVMNet / paths.limaNet belongs to
  the host OS, and tolerates an unreadable /etc/sudoers.d, which is typically
  0750 root:root. varRun only has to be daemon-group-writable on macOS, because
  lima-net runs as root.
- Sudoers() iterates over RequiredDaemons() and, for lima-net, additionally
  allows the tap command, restricted by TapNamePattern() so that no extra
  arguments can be smuggled in. The mkdir rule stays macOS-only.
- `limactl sudoers` is enabled on Linux and only refers users to the
  socket_vmnet documentation on macOS.

Signed-off-by: Ansuman Sahoo <anshumansahoo500@gmail.com>
Wire the Linux helper into the instance lifecycle so that the non-usernet
networks can actually be used:

- reconcile tracks which instances use a network instead of just a boolean, so
  that it can create one tap device per instance after starting lima-net. The
  daemon list, the varRun handling and the start retries are derived from
  RequiredDaemons() rather than from GOOS checks.
- The QEMU driver attaches the instance to its tap device (script=no, since the
  device is already owned by the user and enslaved to the bridge).
- limayaml validation accepts the `lima` network field on Linux.

Signed-off-by: Ansuman Sahoo <anshumansahoo500@gmail.com>
Signed-off-by: Ansuman Sahoo <anshumansahoo500@gmail.com>
@unsuman
unsuman force-pushed the net/linux-networking branch from df585f5 to 355f303 Compare August 21, 2026 12:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Support lima:shared, lima:bridged, lima:host on Linux hosts

1 participant