Skip to content

Local IPv4 proxied TCP connections are dropped by rp_filter on dae0peer (IP_RPFILTER) #1078

Closed

Description

@FreeQueue

Bug Report: Local IPv4 proxied connections are dropped by rp_filter on dae0peer

Summary

On a local Linux desktop running dae/daed, all locally-generated IPv4 TCP connections that should go through proxy time out.
IPv6 works fine, so the symptom is most obvious with IPv4-only destinations like github.com (GitHub has no AAAA).

I reproduced this on:

  • daed v1.27.0 (bundled dae-core 7e67e31, veth datapath)
  • official dae v2.0.0 (Netkit datapath on kernel >= 6.7)

Environment

  • OS: CachyOS, kernel 7.1.8-1-cachyos
  • dae/daed:
    • daed v1.27.0 (dae-core commit 7e67e31e241a6d2cc5f2b5ff228b4fb5faf6d24a)
    • dae official binary v2.0.0
  • Interfaces:
    • lan_interface: "enp131s0"
    • wan_interface: "auto"
    • secondary wlan0 also present
  • Routing: fallback: proxy; github matched by geosite:github -> proxy
  • Node: self-hosted VLESS/REALITY (verified working from VPS)

Current behavior

curl -4 -I https://github.com/    # timeout after connect timeout
curl -6 https://www.google.com/   # works
curl    https://www.google.com/   # works (has AAAA, uses IPv6)
curl -4 https://www.google.com/   # timeout
curl -4 https://www.baidu.com/    # works (routing direct, not proxy)

github.com has only A records, so it always uses the broken IPv4 proxy path.

Root cause

Redirected IPv4 SYNs reach dae0peer with mark 0x8000000 and are assigned to dae's TProxy socket, but are then dropped by the normal IPv4 input path due to reverse-path filtering.

skb:kfree_skb tracepoint during the failing curl -4:

drop reason=16 proto=2048   # reason 16 = SKB_DROP_REASON_IP_RPFILTER, proto 2048 = ETH_P_IP

Inside the dae netns after dae starts:

net.ipv4.conf.all.rp_filter = 1
net.ipv4.conf.dae0peer.rp_filter = 1
net.ipv4.conf.dae0peer.accept_local = 1   # dae already sets this (PR #512)

Current upstream setupSysctl() (checked at main and v2.0.0) only sets
dae0peer.accept_local=1 inside the dae netns. It does not set
dae0peer.rp_filter=0 or the dae-netns all.rp_filter=0.

Workaround

ip netns exec daens sysctl -w net.ipv4.conf.all.rp_filter=0
ip netns exec daens sysctl -w net.ipv4.conf.dae0peer.rp_filter=0

After this, all IPv4 proxy tests pass (github.com, api.github.com, google.com, etc.).

Suggested fix

In control/netns_utils.go setupSysctl(), after entering daens, also set:

net.ipv4.conf.all.rp_filter = 0
net.ipv4.conf.dae0peer.rp_filter = 0

and make sure dae's sysctl watcher/self-heal keeps them at those values.

This matches what dae already does on the host side for dae0 / all.rp_filter after PR #980.

Related existing work

Activity

  1. dae-prow commented on Aug 15, 2026

    @dae-prow
    Contributor

    Thanks for opening this issue!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions