Fix ipv6 route on linux

This commit is contained in:
世界 2022-08-25 18:23:33 +08:00
parent e5c59fc756
commit 409136e644
No known key found for this signature in database
GPG key ID: CD109927C34A63C4

View file

@ -167,107 +167,180 @@ func (t *NativeTun) routes(tunLink netlink.Link) []netlink.Route {
} }
func (t *NativeTun) rules() []*netlink.Rule { func (t *NativeTun) rules() []*netlink.Rule {
var p4, p6 bool
var pRule int
if t.options.Inet4Address.IsValid() {
p4 = true
pRule += 1
}
if t.options.Inet6Address.IsValid() {
p6 = true
pRule += 1
}
if pRule == 0 {
return []*netlink.Rule{}
}
var rules []*netlink.Rule var rules []*netlink.Rule
var it *netlink.Rule var it *netlink.Rule
excludeRanges := t.options.ExcludedRanges() excludeRanges := t.options.ExcludedRanges()
priority := 9000 priority := 9000
nopPriority := priority + 10*(len(excludeRanges)/10+2) nopPriority := priority + 10
for _, excludeRange := range t.options.ExcludedRanges() { for _, excludeRange := range excludeRanges {
if p4 {
it = netlink.NewRule() it = netlink.NewRule()
it.Priority = priority it.Priority = priority
it.UIDRange = netlink.NewRuleUIDRange(excludeRange.Start, excludeRange.End) it.UIDRange = netlink.NewRuleUIDRange(excludeRange.Start, excludeRange.End)
it.Goto = nopPriority it.Goto = nopPriority
it.Family = unix.AF_INET
rules = append(rules, it) rules = append(rules, it)
}
if p6 {
it = netlink.NewRule()
it.Priority = priority
it.UIDRange = netlink.NewRuleUIDRange(excludeRange.Start, excludeRange.End)
it.Goto = nopPriority
it.Family = unix.AF_INET6
rules = append(rules, it)
}
}
if len(excludeRanges) > 0 {
priority++ priority++
} }
if t.options.Inet4Address.IsValid() { if p4 {
it = netlink.NewRule() it = netlink.NewRule()
it.Priority = priority it.Priority = priority
it.Dst = t.options.Inet4Address.Masked() it.Dst = t.options.Inet4Address.Masked()
it.Table = tunTableIndex it.Table = tunTableIndex
it.Family = unix.AF_INET
rules = append(rules, it) rules = append(rules, it)
priority++
if runtime.GOOS != "android" {
// not supported on android, why?
it = netlink.NewRule()
it.Priority = priority
it.IPProto = unix.IPPROTO_ICMP
it.Goto = nopPriority
rules = append(rules, it)
priority++
} }
} if p6 {
if t.options.Inet6Address.IsValid() {
it = netlink.NewRule() it = netlink.NewRule()
it.Priority = priority it.Priority = priority
it.Dst = t.options.Inet6Address.Masked() it.Dst = t.options.Inet6Address.Masked()
it.Table = tunTableIndex it.Table = tunTableIndex
it.Family = unix.AF_INET6
rules = append(rules, it) rules = append(rules, it)
}
priority++ priority++
if runtime.GOOS != "android" { if runtime.GOOS != "android" {
// not supported on android, why?
if p4 {
it = netlink.NewRule()
it.Priority = priority
it.IPProto = unix.IPPROTO_ICMP
it.Goto = nopPriority
it.Family = unix.AF_INET
rules = append(rules, it)
}
if p6 {
it = netlink.NewRule() it = netlink.NewRule()
it.Priority = priority it.Priority = priority
it.IPProto = unix.IPPROTO_ICMPV6 it.IPProto = unix.IPPROTO_ICMPV6
it.Goto = nopPriority it.Goto = nopPriority
it.Family = unix.AF_INET6
rules = append(rules, it) rules = append(rules, it)
}
priority++ priority++
} }
}
if p4 {
it = netlink.NewRule() it = netlink.NewRule()
it.Priority = priority it.Priority = priority
it.Invert = true it.Invert = true
it.Dport = netlink.NewRulePortRange(53, 53) it.Dport = netlink.NewRulePortRange(53, 53)
it.Table = unix.RT_TABLE_MAIN it.Table = unix.RT_TABLE_MAIN
it.SuppressPrefixlen = 0 it.SuppressPrefixlen = 0
it.Family = unix.AF_INET
rules = append(rules, it) rules = append(rules, it)
}
if p6 {
it = netlink.NewRule()
it.Priority = priority
it.Invert = true
it.Dport = netlink.NewRulePortRange(53, 53)
it.Table = unix.RT_TABLE_MAIN
it.SuppressPrefixlen = 0
it.Family = unix.AF_INET6
rules = append(rules, it)
}
priority++ priority++
if p4 {
it = netlink.NewRule() it = netlink.NewRule()
it.Priority = priority it.Priority = priority
it.Invert = true it.Invert = true
it.IifName = "lo" it.IifName = "lo"
it.Table = tunTableIndex it.Table = tunTableIndex
it.Family = unix.AF_INET
rules = append(rules, it) rules = append(rules, it)
priority++
it = netlink.NewRule() it = netlink.NewRule()
it.Priority = priority it.Priority = priority
it.IifName = "lo" it.IifName = "lo"
it.Src = netip.PrefixFrom(netip.IPv4Unspecified(), 32) it.Src = netip.PrefixFrom(netip.IPv4Unspecified(), 32)
it.Table = tunTableIndex it.Table = tunTableIndex
it.Family = unix.AF_INET
rules = append(rules, it) rules = append(rules, it)
priority++
if t.options.Inet4Address.IsValid() {
it = netlink.NewRule() it = netlink.NewRule()
it.Priority = priority it.Priority = priority
it.IifName = "lo" it.IifName = "lo"
it.Src = t.options.Inet4Address.Masked() it.Src = t.options.Inet4Address.Masked()
it.Table = tunTableIndex it.Table = tunTableIndex
it.Family = unix.AF_INET
rules = append(rules, it) rules = append(rules, it)
priority++
} }
if p6 {
// FIXME: this match connections from public address
it = netlink.NewRule()
it.Priority = priority
it.Table = tunTableIndex
it.Family = unix.AF_INET6
rules = append(rules, it)
/*it = netlink.NewRule()
it.Priority = priority
it.Invert = true
it.IifName = "lo"
it.Table = tunTableIndex
it.Family = unix.AF_INET6
rules = append(rules, it)
it = netlink.NewRule()
it.Priority = priority
it.IifName = "lo"
it.Src = netip.PrefixFrom(netip.IPv6Unspecified(), 128) // not working
it.Table = tunTableIndex
it.Family = unix.AF_INET6
rules = append(rules, it)
if t.options.Inet6Address.IsValid() {
it = netlink.NewRule() it = netlink.NewRule()
it.Priority = priority it.Priority = priority
it.IifName = "lo" it.IifName = "lo"
it.Src = t.options.Inet6Address.Masked() it.Src = t.options.Inet6Address.Masked()
it.Table = tunTableIndex it.Table = tunTableIndex
rules = append(rules, it) it.Family = unix.AF_INET6
priority++ rules = append(rules, it)*/
} }
priority++
if p4 {
it = netlink.NewRule() it = netlink.NewRule()
it.Priority = nopPriority it.Priority = nopPriority
it.Family = unix.AF_INET
rules = append(rules, it) rules = append(rules, it)
}
if p6 {
it = netlink.NewRule()
it.Priority = nopPriority
it.Family = unix.AF_INET6
rules = append(rules, it)
}
return rules return rules
} }