Repository navigation
Local IPv4 proxied TCP connections are dropped by rp_filter on dae0peer (IP_RPFILTER) #1078
Description
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-core7e67e31, 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 commit7e67e31e241a6d2cc5f2b5ff228b4fb5faf6d24a) - dae official binary
v2.0.0
- daed
- Interfaces:
lan_interface: "enp131s0"wan_interface: "auto"- secondary
wlan0also present
- Routing:
fallback: proxy;githubmatched bygeosite: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
- fix: sysctl net.ipv4.conf.dae0peer.accept_local=1 #512 fixed
dae0peer.accept_localfor martian source. - fix: Watch sysctl changes to ensure expected values #426 watches sysctl changes for expected values.
- fix: carry ipv4 udp fallback, outbound, trace and conn-state follow-ups #980 restored host-side
dae0rp_filter/arp_filter/accept_local. - feat(bpf): implement stack bypass #458 / feat(config): add global.netkit_mode to choose capture device (auto/netkit/veth) #1046 moved toward Netkit/stack-bypass, but this still reproduces with Netkit on kernel 7.1.8.
Activity
dae-prow commentedon Aug 15, 2026
Thanks for opening this issue!