feat: add TAP networking backend for bridged A2065 emulation#1784
feat: add TAP networking backend for bridged A2065 emulation#1784midwan merged 3 commits intoBlitterStudio:masterfrom
Conversation
9de625a to
a84a752
Compare
Prepare for the TAP networking backend by widening the preprocessor scope of shared symbols. Code that both pcap and TAP backends will use (struct uaenet_data, queue management, open/close/trigger API, utility functions) moves from #ifdef WITH_UAENET_PCAP to the combined guard #if defined(WITH_UAENET_PCAP) || defined(WITH_UAENET_TAP). pcap-specific code (GRO segmentation, pcap worker thread, pcap enumeration, pcap_open_live/BPF filter, pcap_sendpacket calls) remains under #ifdef WITH_UAENET_PCAP. Zero functional changes when WITH_UAENET_PCAP is defined. Verified by rebuilding, installing, and running PCAP networking tests on the emulated Amiga. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
a84a752 to
8ad6d57
Compare
|
Cleanup code duplication in Also, the |
Good catches. Regarding the forward declaration, I'll move uaenet_tap_enumerate_free() above uaenet_tap_enumerate() and delete the forward declaration. That's cleaner. |
Add a TAP backend alongside the existing PCAP backend for the A2065 network card emulation. TAP operates at L2 through the kernel's bridge, avoiding PCAP's promiscuous-mode requirement and enabling direct host-to-guest communication — something PCAP on a bridge cannot do. Two operating modes: - Option A (auto-create): user configures a2065=br0, Amiberry creates a TAP device (amiberry0), adds it to the bridge, and tears it down on exit. Requires CAP_NET_ADMIN. - Option B (pre-created): user configures a2065=tap0 for a TAP device that was set up externally, avoiding STP forwarding delays. Only requires CAP_NET_RAW. The TAP backend is preferred when available and falls back to PCAP on failure or when CAP_NET_ADMIN is missing. Build-time control via -DUSE_UAENET_TAP=OFF; disabled automatically on non-Linux platforms. Performance: LAN FTP throughput ~1.6 MB/s (vs ~885 KB/s with PCAP). Host-to-guest ping <5ms (previously impossible with PCAP on bridge). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
5818db7 to
0c4a290
Compare
Summary
The PCAP backend works for bridged A2065 networking but has an inherent limitation: the host cannot communicate directly with the emulated machine.
pcap_sendpacket()on a bridge interface forwards frames to bridge ports but doesn't loop back to the local kernel stack. This means services running on the host (FTP, SSH, telnet) cannot reach the emulated Amiga, and vice versa.The TAP backend solves this by creating a kernel-level virtual Ethernet port that participates in the bridge natively. The kernel routes traffic between the TAP port and the local network stack, enabling full bidirectional host-to-guest communication. TAP also eliminates the need for promiscuous mode, BPF filters, and userspace GRO segmentation — the kernel delivers standard-sized frames through the bridge before they reach the TAP fd.
The Approach
Two operating modes
Option A (auto-create): Configure
a2065=br0. Amiberry opens/dev/net/tun, creates a TAP interface namedamiberryN, adds it to the specified bridge viaSIOCBRADDIF, and brings it up. On exit, the interface is removed from the bridge and destroyed. Requirescap_net_admin.Option B (pre-created): Configure
a2065=tap0. Amiberry attaches to an existing TAP device created by the administrator (e.g. viaip tuntap add). It does not modify bridge membership or destroy the interface on exit. Does not requirecap_net_admin.Graceful fallback
If TAP creation fails (e.g. missing
cap_net_admincapability), the backend falls back to PCAP transparently with a log message. No user intervention required.Build system
TAP is controlled by the
USE_UAENET_TAPcmake option (ON by default on Linux, forced OFF on Android, macOS, and FreeBSD). PCAP and TAP can be independently enabled or disabled at compile time.Bridge MAC handling
The TAP interface MAC is intentionally not set to the emulated NIC's MAC address. When a bridge port's link-layer address matches a destination MAC, Linux creates a "permanent local" FDB entry and delivers those frames to the bridge's own network stack instead of forwarding them to the port. This silently breaks all unicast receive. Instead, the TAP keeps its kernel-assigned random MAC, and the bridge learns the Amiga MAC from outgoing traffic — the standard L2 learning path.
Enumeration cache safety
The UAE device selection system caches
ndd[]pointers on first enumeration. TAP enumeration populates a statictap_nd[]array whose entries are referenced by those cached pointers. On subsequent single-device lookups (which happen duringa2065_config()), the TAP enumerator searches the existing array rather than re-enumerating, which would free the strings and invalidate the cached pointers.Testing
Tested on Debian 13 (kernel 6.12) running as a Proxmox VM with a virtio NIC (
ens18) bridged tobr0. Emulated A4000/040 with A2065 NIC, Roadshow TCP/IP stack.PCAP regression tests (no regressions found)
a2065=ens18a2065=br0,cap_net_adminremoved-DUSE_UAENET_TAP=OFFTAP integration tests
a2065=br0)amiberry0, adds tobr0, DHCP acquires IPPerformance comparison (TAP vs PCAP)
Generated with Claude Code