Hacktoberfest 2026: the issues maintainers tagged for October, open and beginner-friendly. Browse Hacktoberfest issues

sing-tun 的 mark 模式 fallback 规则问题

Open
#99 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Assessment

Difficulty
3/5
Estimated time
1-2 days
Newbie friendliness
68/100
Issue type
Bug
Clarity
Clearly specified
Activity status
Active
Tech stack
go, linux, networking

Research direction

Read the mark mode fallback rule in tun_linux.go, especially the section around IPRoute2AutoRedirectFallbackRuleIndex and both address family rules. Check how the rule handles the default route in table 2022, then run the relevant routing tests. Done means the fallback rules suppress prefix length 0 and IPv6 bypass works with source specific main table routes.

Written by the indexing model from the issue text.

Description

IPv4 bypass 正常,v6 bypass 超时, 命中后由内核转发但路径不通、IPv4 正常、direct 正常(OpenWrt 源特定 IPv6 路由 + table 2022 的默认路由被当成直连路径)
根因
auto_redirect 的预匹配 bypass 是在 nftables/NFQUEUE 里给包打 fwmark 0x2024 后交给内核转发(nfqueue_linux.go 里 ActionBypass -> NfRepeat + outputMark)。而 IPv6 包在走到这一步之前,路由其实已经选过一次了:
本机进程 connect()/ping 时的第一次路由查找,sk_mark 还是 0;tun_linux.go 里 mark 模式的 fallback 规则是: 32768: not fwmark 0x2024 lookup 2022(tun_linux.go 中 IPRoute2AutoRedirectFallbackRuleIndex 那段);
这条规则没有 suppress_prefixlength,于是 table 2022 里的 ::/0 -> 默认路由会直接命中,连接被绑到 TUN 的 fdfe:dcba:9876::1 上,甚至先把包送进 TUN。随后预匹配命中 bypass、打上 0x2024,策略路由重查时:9000: fwmark 0x2024 goto 9002(nop)→ 跳过 2022 → 落到 main;
如果 main 里的 IPv6 默认路由是 OpenWrt sourcefilter/DHCPv6-PD 那种 带源前缀的 from 路由,此时源地址已经是 TUN 的 ULA,匹配不上任何 from 路由 → 无路由 → 包被丢弃;
IPv4 因为 main 有普通 default,所以正常;direct 正常是因为 sing-box 的 socket 在 connect() 前就 SO_MARK=0x2024,第一次查找就走 main 并选对了源地址。
修复
在 tun_linux.go 的 mark 模式 fallback 规则(32768,两个地址族)上增加 go it.SuppressPrefixlen = 0

目前解决办法是在op上取消勾选 IPv6 源路由

Dominant language
Go
Stars
240
Forks
240
PR merge metrics
No merged PRs in 30d

Getting set up

This project ships no dev container, Dockerfile or contributing guide, so setting up is up to you: start from its README, and see our first-contribution guide for the general steps.

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from SagerNet/sing-tun

All issues in SagerNet/sing-tun

Similar issues

More Go issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.