Skip to content

Add FreeBSD /dev/tun support with FIB-based routing isolation - #97

Open
vxzman wants to merge 2 commits into
SagerNet:devfrom
vxzman:pr/freebsd-support
Open

vxzman wants to merge 2 commits into
SagerNet:devfrom
vxzman:pr/freebsd-support

Conversation

@vxzman

@vxzman vxzman commented Oct 4, 2026

Copy link
Copy Markdown

Summary

This PR adds native FreeBSD TUN device and routing support to sing-tun.

Key Design & Implementation Details:

  1. Device Management (tun_freebsd.go):

    • Opens /dev/tun clone device, discovers the assigned interface name via TUNGIFNAME, and sets flags with TUNSIFHEAD (4-byte packet information header), TUNSIFMODE (IFF_BROADCAST|IFF_MULTICAST), and TUNSIFPID.
    • On FreeBSD 15+, enables TUNSTRANSIENT so the device is automatically destroyed upon closing the descriptor, surviving even SIGKILL. On FreeBSD 12–14, best-effort SIOCIFDESTROY cleanup is performed on Close().
    • Handles interface renaming (SIOCSIFNAME), safely skipping rename if the clone device already matches the requested name (avoiding EEXIST).
    • Configures IPv4/IPv6 addresses via SIOCAIFADDR and SIOCAIFADDR_IN6 with IN6_IFF_NODAD flag and sets ND6 flags to suppress automatic link-local generation. Link-local IPv6 default gateways are embedded with interface scope.
  2. Loop Prevention via FIB Isolation (FIB 2022):

    • FreeBSD lacks Linux's SO_BINDTODEVICE/fwmark and macOS's scoped routing (IP_BOUND_IF). Instead, FreeBSD natively provides per-socket routing table selection via SO_SETFIB.
    • Subnet capture routes (auto_route) are installed into default FIB 0 via AF_ROUTE routing sockets.
    • The real default gateway is queried via route.FetchRIB and replicated into a dedicated FIB (iproute2_table_index, default 2022). Outbound dialer sockets in sing-box are marked with SO_SETFIB=2022, ensuring outbound traffic never loops back into the tun capture routes.
  3. gVisor Link Endpoint (tun_freebsd_gvisor.go):

    • Implements native gVisor LinkEndpoint for FreeBSD with self-address reflection (packets directed to the tun interface's own IP are reflected back).
  4. Network Monitoring (monitor_route_bsd.go):

    • Shares the Darwin AF_ROUTE and FetchRIB route change monitor with FreeBSD under build tag darwin || freebsd.

Test Plan

  • Verified go build ./... across:
    • GOOS=freebsd GOARCH=amd64
    • GOOS=freebsd GOARCH=arm64
    • GOOS=linux GOARCH=amd64
    • GOOS=darwin GOARCH=arm64
  • Verified go vet ./... passes without warnings.
  • Real-machine verified on FreeBSD 15.1-RELEASE VM and FreeBSD 14.x:
    • Device creation, address assignment, and MTU configuration.
    • FIB isolation (net.fibs > 1, net.add_addr_allfibs=1): verified zero loopback, CPU idle, successful traffic capture and outbound dialing.
    • gVisor and system stack packet read/write loops.

@vxzman
vxzman force-pushed the pr/freebsd-support branch from 4db9e75 to 1fa5127 Compare October 4, 2026 15:44
@nekohasekai
nekohasekai force-pushed the dev branch 2 times, most recently from 7539c98 to 5c2edb1 Compare October 9, 2026 03:10
Share the darwin route-based monitor and auto-route range
building logic with FreeBSD, which uses the same AF_ROUTE
and FetchRIB primitives.
Add /dev/tun based NativeTun for FreeBSD:

- Clone device setup via TUNSIFHEAD/TUNSIFMODE/TUNSIFPID ioctls
- Set TUNSTRANSIENT (FreeBSD 15+) for lifecycle cleanup on close
- IPv4/IPv6 address assignment with NODAD and link-local scope handling
- Auto route via AF_ROUTE route messages in the default FIB
- Loop prevention: a dedicated FIB (iproute2_table_index) holds a copy
  of the real default gateway, so outbound sockets bound to that FIB
  never match the capture routes
- gVisor link endpoint with self-address reflection
@vxzman
vxzman force-pushed the pr/freebsd-support branch from 1fa5127 to d12856c Compare October 10, 2026 05:50
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.

1 participant