Skip to content

feat(network): add IPvlan and Macvlan modes with DHCP and host access - #271

Open
ericma15 wants to merge 10 commits into
ravindu644:mainfrom
ericma15:codex/ipvlan-macvlan
Open

feat(network): add IPvlan and Macvlan modes with DHCP and host access#271
ericma15 wants to merge 10 commits into
ravindu644:mainfrom
ericma15:codex/ipvlan-macvlan

Conversation

@ericma15

@ericma15 ericma15 commented Aug 8, 2026

Copy link
Copy Markdown

Summary

This PR adds native IPvlan and Macvlan networking support to Droidspaces
across the backend, CLI, socket API, Android UI, configuration storage,
capability checks, and documentation.

The new modes give containers direct Layer 2 access to the Android host's
upstream network without using Droidspaces NAT or sharing the host network
namespace.

Motivation

The existing networking modes cover:

  • host: shares the Android network namespace
  • nat: provides isolated networking behind Droidspaces NAT
  • none: disables networking
  • gateway: delegates networking through another container

However, there was no way for a container to appear directly on the physical
LAN and obtain an address from the external router.

IPvlan and Macvlan fill this gap:

  • IPvlan shares the parent interface's MAC address and generally works better
    with Wi-Fi hardware.
  • Macvlan gives the container its own MAC address, which is useful for DHCP
    reservations and Layer 2 identity where the underlying network supports it.

What changed

New networking modes

Added:

--net=ipvlan
--net=macvlan

Both modes create a child link from an Android host interface and move it into
the container network namespace as eth0.

The parent interface can be explicitly configured:

--net-parent=wlan0

When omitted, Droidspaces automatically detects the active Android uplink.

DHCP and static addressing

Direct L2 modes support two addressing methods:

--net-ipam=dhcp
--net-ipam=static

For DHCP mode, Droidspaces does not run its embedded NAT DHCP server. Instead,
the container's own NetworkManager, systemd-networkd, dhcpcd, or equivalent
client requests an address directly from the external router.

Static configuration supports:

--net-address=192.168.1.50/24
--net-gateway=192.168.1.1
--dns=1.1.1.1,8.8.8.8

The existing IPv6-disable option is also honored.

Stable DHCP identity for IPvlan

IPvlan interfaces share the parent MAC address. Using the MAC as the DHCP
client identifier would make Android and multiple containers appear as the
same DHCP client.

For systemd-networkd guests, this PR therefore generates:

  • A stable per-container DUID-UUID
  • A stable IAID
  • A hostname containing a stable five-digit suffix
  • A stable IPv6 RA token

The identity is derived from the container UUID and remains stable across
restarts. Legacy containers without a UUID use a deterministic container-name
fallback.

Some routers ignore DHCP option 61 and identify clients only by MAC address.
The Android UI displays a warning for this limitation.

Optional Macvlan MAC address

Macvlan supports an optional user-provided unicast MAC:

--net-mac=02:11:22:33:44:55

When omitted, the kernel-selected address is left unchanged. This can be used
with router-side DHCP reservations.

Guest network-manager policy

The per-boot network-service policy now distinguishes networking modes:

  • host, none, and direct-L2 static mode keep guest network managers
    blocked.
  • nat, gateway, and direct-L2 DHCP mode allow guest network managers to
    start.
  • Runtime configuration is written under /run, so existing container images
    receive the corrected policy without requiring re-extraction.

For PTP host access, dshost0 is marked unmanaged for both systemd-networkd
and NetworkManager.

Host-to-container access

Linux normally isolates a Macvlan/IPvlan parent from its child interfaces.
Three host-access modes are provided:

--host-access=none
--host-access=ptp
--host-access=shim

none

Keeps the normal kernel parent/child isolation.

ptp — recommended

Creates a private point-to-point veth between Android and the container:

  • Uses a collision-checked /30 from a private 169.254.0.0/16 pool
  • Creates dshost0 inside the container
  • Adds /32 routes for the container's primary LAN address
  • Detects DHCP-assigned addresses after startup
  • Tracks Android parent-address changes
  • Allocates independent ranges for multiple containers

This does not add another address to the physical LAN.

shim

Creates a shared host-side IPvlan or Macvlan sibling on the selected parent:

  • Automatically reuses the Android parent interface's IPv4 address as /32
  • Adds a /32 route for each container address
  • Detects DHCP-assigned container addresses
  • Shares one shim between containers using the same parent and mode
  • Uses locking and state tracking for concurrent container lifecycle operations
  • Removes the shim only after its last live user stops

Android UI

The Android application now includes:

  • IPvlan and Macvlan network-mode choices
  • Parent-interface dropdown with active-uplink auto detection
  • DHCP/static selection
  • Static address, gateway, and DNS fields
  • Optional Macvlan MAC field
  • Host-access mode selection
  • Configuration validation
  • Installation and container summary integration
  • Editing and persistence of the new settings

When Macvlan is selected, the UI always displays the Wi-Fi limitation:

Macvlan over Wi-Fi depends on both the wireless router/AP and this phone
supporting and enabling 4addr (WDS) mode.

Wi-Fi Macvlan and 4addr handling

A normal Wi-Fi STA generally cannot transmit frames using a second source MAC
address.

When Macvlan uses a wlan* parent, Droidspaces makes a best-effort attempt to
run:

iw dev <parent> set 4addr on

Failure is logged but does not prevent the container from starting.

Both sides must support and enable 4-address/WDS mode:

  • The Android Wi-Fi driver and firmware
  • The wireless router or access point

Droidspaces can attempt to enable the phone side but cannot configure the
router. IPvlan does not require this because it shares the parent MAC address.

Kernel capability detection

The machine-readable requirements check now reports:

CONFIG_IPVLAN=0|1
CONFIG_MACVLAN=0|1

Support is determined using live Netlink capability probes rather than relying
only on /proc/config.gz.

The Android UI independently disables IPvlan or Macvlan when the corresponding
backend capability is unavailable. These are optional feature requirements and
do not prevent Droidspaces from using the existing network modes.

Required kernel options are documented as:

CONFIG_IPVLAN=y
CONFIG_MACVLAN=y

CLI and socket API

The new fields are supported by:

  • CLI parsing and validation
  • Configuration loading and saving
  • Machine-readable container information
  • Socket backend requests
  • Android command/config generation
  • Human-readable documentation output

Windows build reliability

The repository now forces Unix line endings for shell scripts:

*.sh text eol=lf

This prevents Android assets built from a Windows checkout from receiving a
CRLF shebang such as #!/system/bin/sh\r, which otherwise fails at runtime
with No such file or directory.

Compatibility

Existing networking modes and existing container configurations retain their
previous defaults and behavior.

Direct L2 defaults are:

net_ipam=dhcp
host_access=none

No host-access interfaces or routes are created unless explicitly requested.

The embedded Droidspaces DHCP server remains limited to NAT mode; IPvlan and
Macvlan DHCP requests go directly to the external network.

Testing

The following were tested on a rooted Android aarch64 device:

  • Static aarch64 backend build with the project's strict warning settings
  • Android debug APK build and in-place installation
  • Runtime CONFIG_IPVLAN capability probe
  • Runtime CONFIG_MACVLAN capability probe
  • IPvlan link creation and namespace transfer
  • IPvlan static IPv4 LAN connectivity
  • IPvlan DHCP through the external router
  • Stable per-container DHCP identity
  • IPv6 address isolation between IPvlan containers
  • Guest systemd-networkd runtime configuration
  • Android parent-interface auto detection
  • Optional Macvlan MAC configuration
  • Phone-side iw dev wlan0 set 4addr on request
  • Android UI configuration persistence and validation
  • Existing NAT mode regression testing
  • APK shell assets verified to contain LF only
  • Rootfs validator executed successfully on the Android target

End-to-end Macvlan over Wi-Fi remains dependent on phone driver/firmware and
router-side 4addr/WDS support. This limitation is explicitly surfaced in the
UI and runtime logs.

Known limitations

  • Some DHCP servers identify IPvlan clients only by MAC address and may not
    allocate separate leases even when a unique DUID is provided.(Need router support rfc4361,find some old tplink and firehome not supported,can set a static ip instead)
  • Macvlan over Wi-Fi usually requires 4addr/WDS support on both the phone and
    access point.
  • Droidspaces cannot enable or configure WDS on the external router.
  • DHCP mode requires a working DHCP client or network manager inside the
    container.
  • Host-access routing currently targets IPv4 primary addresses; normal
    direct-L2 IPv6 traffic remains independent of the host-access helper.

Test on my Oneplus 9R with ColorOs 15 (modify) with self-compiled kernel 4.19.325-perf+
Router: xiaomi be7000
IPvlan Mode all pass
Macvlan Mode lack a 4addr support router,so arp cannot pass.

@yoshi3jp yoshi3jp left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This PR appears to be in conflict with the project policy.
Android, both in the Kernel and in the userland, is not suited for this kind of network topology, in my opinion.

@ericma15

ericma15 commented Aug 9, 2026

Copy link
Copy Markdown
Author

This PR appears to be in conflict with the project policy. Android, both in the Kernel and in the userland, is not suited for this kind of network topology, in my opinion.

I'm not sure about whether default android kernel support macvlan or ipvlan. it is just a true virtual device in linux kernel like veth. it has better performance and cost low cpu than a nat (no repacket packet and no ct entry). they are basic network solution in many container network solution.,like docker. does this project only for standard google gki kernel without any other kernerl conifg (except some must have)?

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.

2 participants