mirror of
https://github.com/tailscale/tailscale.git
synced 2025-02-18 02:48:40 +00:00
net/ipset: return all closures from named wrappers
So profiles show more useful names than just func1, func2, func3, etc. There will still be func1 on them all, but the symbol before will say what the lookup type is. Updates #12486 Change-Id: I910b024a7861394eb83d07f5a899eae338cb1f22 Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
This commit is contained in:
parent
86e0f9b912
commit
bf2d13cfa0
@ -10,11 +10,47 @@ import (
|
||||
|
||||
"github.com/gaissmai/bart"
|
||||
"tailscale.com/types/views"
|
||||
"tailscale.com/util/set"
|
||||
)
|
||||
|
||||
// FalseContainsIPFunc is shorthand for NewContainsIPFunc(views.Slice[netip.Prefix]{}).
|
||||
func FalseContainsIPFunc() func(ip netip.Addr) bool {
|
||||
return func(ip netip.Addr) bool { return false }
|
||||
return emptySet
|
||||
}
|
||||
|
||||
func emptySet(ip netip.Addr) bool { return false }
|
||||
|
||||
func bartLookup(t *bart.Table[struct{}]) func(netip.Addr) bool {
|
||||
return func(ip netip.Addr) bool {
|
||||
_, ok := t.Get(ip)
|
||||
return ok
|
||||
}
|
||||
}
|
||||
|
||||
func prefixContainsLoop(addrs []netip.Prefix) func(netip.Addr) bool {
|
||||
return func(ip netip.Addr) bool {
|
||||
for _, p := range addrs {
|
||||
if p.Contains(ip) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
func oneIP(ip1 netip.Addr) func(netip.Addr) bool {
|
||||
return func(ip netip.Addr) bool { return ip == ip1 }
|
||||
}
|
||||
|
||||
func twoIP(ip1, ip2 netip.Addr) func(netip.Addr) bool {
|
||||
return func(ip netip.Addr) bool { return ip == ip1 || ip == ip2 }
|
||||
}
|
||||
|
||||
func ipInMap(m set.Set[netip.Addr]) func(netip.Addr) bool {
|
||||
return func(ip netip.Addr) bool {
|
||||
_, ok := m[ip]
|
||||
return ok
|
||||
}
|
||||
}
|
||||
|
||||
// pathForTest is a test hook for NewContainsIPFunc, to test that it took the
|
||||
@ -29,7 +65,7 @@ func NewContainsIPFunc(addrs views.Slice[netip.Prefix]) func(ip netip.Addr) bool
|
||||
// (or just IPv6), and both IPv4 and IPv6.
|
||||
if addrs.Len() == 0 {
|
||||
pathForTest("empty")
|
||||
return func(netip.Addr) bool { return false }
|
||||
return emptySet
|
||||
}
|
||||
// If any addr is a prefix with more than a single IP, then do either a
|
||||
// linear scan or a bart table, depending on the number of addrs.
|
||||
@ -41,40 +77,27 @@ func NewContainsIPFunc(addrs views.Slice[netip.Prefix]) func(ip netip.Addr) bool
|
||||
for i := range addrs.Len() {
|
||||
t.Insert(addrs.At(i), struct{}{})
|
||||
}
|
||||
return func(ip netip.Addr) bool {
|
||||
_, ok := t.Get(ip)
|
||||
return ok
|
||||
}
|
||||
return bartLookup(t)
|
||||
} else {
|
||||
pathForTest("linear-contains")
|
||||
// Small enough to do a linear search.
|
||||
acopy := addrs.AsSlice()
|
||||
return func(ip netip.Addr) bool {
|
||||
for _, a := range acopy {
|
||||
if a.Contains(ip) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
return prefixContainsLoop(addrs.AsSlice())
|
||||
}
|
||||
}
|
||||
// Fast paths for 1 and 2 IPs:
|
||||
if addrs.Len() == 1 {
|
||||
pathForTest("one-ip")
|
||||
a := addrs.At(0)
|
||||
return func(ip netip.Addr) bool { return ip == a.Addr() }
|
||||
return oneIP(addrs.At(0).Addr())
|
||||
}
|
||||
if addrs.Len() == 2 {
|
||||
pathForTest("two-ip")
|
||||
a, b := addrs.At(0), addrs.At(1)
|
||||
return func(ip netip.Addr) bool { return ip == a.Addr() || ip == b.Addr() }
|
||||
return twoIP(addrs.At(0).Addr(), addrs.At(1).Addr())
|
||||
}
|
||||
// General case:
|
||||
pathForTest("ip-map")
|
||||
m := map[netip.Addr]bool{}
|
||||
m := set.Set[netip.Addr]{}
|
||||
for i := range addrs.Len() {
|
||||
m[addrs.At(i).Addr()] = true
|
||||
m.Add(addrs.At(i).Addr())
|
||||
}
|
||||
return func(ip netip.Addr) bool { return m[ip] }
|
||||
return ipInMap(m)
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user