Commit Graph

111 Commits (0e0e53d3b3a6d22469758daa1aecdcca930875db)

Author SHA1 Message Date
Brad Fitzpatrick 5ec01bf3ce wgengine/filter: support FilterRules matching on srcIP node caps [capver 100]
See #12542 for background.

Updates #12542

Change-Id: Ida312f700affc00d17681dc7551ee9672eeb1789
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
5 months ago
Keli bd50a3457d
wgengine/filter: add "Accept" TCP log lines to verbose logging (#12525)
Changes "Accept" TCP logs to display in verbose logs only,
and removes lines from default logging behavior.

Updates #12158

Signed-off-by: Keli Velazquez <keli@tailscale.com>
5 months ago
Brad Fitzpatrick 21460a5b14 tailcfg, wgengine/filter: remove most FilterRule.SrcBits code
The control plane hasn't sent it to clients in ages.

Updates tailscale/corp#20965

Change-Id: I1d71a4b6dd3f75010a05c544ee39827837c30772
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
5 months ago
Brad Fitzpatrick 9e0a5cc551 net/flowtrack: optimize Tuple type for use as map key
This gets UDP filter overhead closer to TCP. Still ~2x, but no longer ~3x.

    goos: darwin
    goarch: arm64
    pkg: tailscale.com/wgengine/filter
                                       │   before    │                after                │
                                       │   sec/op    │   sec/op     vs base                │
    FilterMatch/tcp-not-syn-v4-8         15.43n ± 3%   15.38n ± 5%        ~ (p=0.339 n=10)
    FilterMatch/udp-existing-flow-v4-8   42.45n ± 0%   34.77n ± 1%  -18.08% (p=0.000 n=10)
    geomean                              25.59n        23.12n        -9.65%

Updates #12486

Change-Id: I595cfadcc6b7234604bed9c4dd4261e087c0d4c4
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
5 months ago
Brad Fitzpatrick bd93c3067e wgengine/filter/filtertype: make Match.IPProto a view
I noticed we were allocating these every time when they could just
share the same memory. Rather than document ownership, just lock it
down with a view.

I was considering doing all of the fields but decided to just do this
one first as test to see how infectious it became.  Conclusion: not
very.

Updates #cleanup (while working towards tailscale/corp#20514)

Change-Id: I8ce08519de0c9a53f20292adfbecd970fe362de0
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
5 months ago
Brad Fitzpatrick 20a5f939ba wgengine/filter: add UDP flow benchmark
To show the effects of the flow LRU accounting on e.g. QUIC traffic.

For an open TCP connection:

    BenchmarkFilterMatch/tcp-not-syn-v4-8           66602070                16.74 ns/op
    BenchmarkFilterMatch/tcp-not-syn-v4-8           67718179                16.60 ns/op
    BenchmarkFilterMatch/tcp-not-syn-v4-8           68403351                16.84 ns/op
    BenchmarkFilterMatch/tcp-not-syn-v4-8           66076416                16.87 ns/op
    BenchmarkFilterMatch/tcp-not-syn-v4-8           67159012                16.67 ns/op
    BenchmarkFilterMatch/tcp-not-syn-v4-8           65009526                16.58 ns/op
    BenchmarkFilterMatch/tcp-not-syn-v4-8           66588055                16.62 ns/op
    BenchmarkFilterMatch/tcp-not-syn-v4-8           63037071                16.58 ns/op
    BenchmarkFilterMatch/tcp-not-syn-v4-8           69124975                21.15 ns/op
    BenchmarkFilterMatch/tcp-not-syn-v4-8           54482922                20.41 ns/op

And an open UDP connection:

    BenchmarkFilterMatch/udp-existing-flow-v4-8             25570020                44.09 ns/op
    BenchmarkFilterMatch/udp-existing-flow-v4-8             26725958                46.99 ns/op
    BenchmarkFilterMatch/udp-existing-flow-v4-8             25936412                47.11 ns/op
    BenchmarkFilterMatch/udp-existing-flow-v4-8             25418325                45.99 ns/op
    BenchmarkFilterMatch/udp-existing-flow-v4-8             25759848                44.73 ns/op
    BenchmarkFilterMatch/udp-existing-flow-v4-8             25212488                46.26 ns/op
    BenchmarkFilterMatch/udp-existing-flow-v4-8             25344370                44.55 ns/op
    BenchmarkFilterMatch/udp-existing-flow-v4-8             26399372                45.26 ns/op
    BenchmarkFilterMatch/udp-existing-flow-v4-8             26274159                47.51 ns/op
    BenchmarkFilterMatch/udp-existing-flow-v4-8             26070472                46.79 ns/op

Updates #12486

Change-Id: Ica4263fb77972cf43db5a2e9433b4429506edfde
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
5 months ago
Brad Fitzpatrick 86e0f9b912 net/ipset, wgengine/filter/filtertype: add split-out packages
This moves NewContainsIPFunc from tsaddr to new ipset package.

And wgengine/filter types gets split into wgengine/filter/filtertype,
so netmap (and thus the CLI, etc) doesn't need to bring in ipset,
bart, etc.

Then add a test making sure the CLI deps don't regress.

Updates #1278

Change-Id: Ia246d6d9502bbefbdeacc4aef1bed9c8b24f54d5
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
5 months ago
Brad Fitzpatrick 36b1b4af2f wgengine/filter: split local+logging lookups by IPv4-vs-IPv6
If we already know it's an incoming IPv4 packet, no need to match
against the set of IPv6s and vice versa.

    goos: darwin
    goarch: arm64
    pkg: tailscale.com/wgengine/filter
                                         │   before    │                after                │
                                         │   sec/op    │   sec/op     vs base                │
    FilterMatch/not-local-v4-8             21.40n ± 3%   16.04n ± 1%  -25.09% (p=0.000 n=10)
    FilterMatch/not-local-v6-8             20.75n ± 9%   15.71n ± 0%  -24.31% (p=0.000 n=10)
    FilterMatch/no-match-v4-8              81.37n ± 1%   78.57n ± 3%   -3.43% (p=0.005 n=10)
    FilterMatch/no-match-v6-8              77.73n ± 2%   73.71n ± 3%   -5.18% (p=0.002 n=10)
    FilterMatch/tcp-not-syn-v4-8           21.41n ± 3%   16.86n ± 0%  -21.25% (p=0.000 n=10)
    FilterMatch/tcp-not-syn-v4-no-logs-8   10.04n ± 0%   10.05n ± 0%        ~ (p=0.446 n=10)
    geomean                                29.07n        25.05n       -13.84%

Updates #12486

Change-Id: I70e5024af03893327d26629a994ab2aa9811f4f3
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
5 months ago
Brad Fitzpatrick d4220a76da wgengine/filter: add TCP non-SYN benchmarks
To show performance during heavy flows on established connections.

    BenchmarkFilterMatch/tcp-not-syn-v4-8           52125848                21.46 ns/op
    BenchmarkFilterMatch/tcp-not-syn-v4-8           52388781                21.43 ns/op
    BenchmarkFilterMatch/tcp-not-syn-v4-8           52916954                21.32 ns/op
    BenchmarkFilterMatch/tcp-not-syn-v4-8           52590730                21.43 ns/op
    BenchmarkFilterMatch/tcp-not-syn-v4-8           53015923                21.32 ns/op
    BenchmarkFilterMatch/tcp-not-syn-v4-no-logs-8   122795029                9.783 ns/op
    BenchmarkFilterMatch/tcp-not-syn-v4-no-logs-8   100000000               10.09 ns/op
    BenchmarkFilterMatch/tcp-not-syn-v4-no-logs-8   120090948                9.747 ns/op
    BenchmarkFilterMatch/tcp-not-syn-v4-no-logs-8   122350448               10.55 ns/op
    BenchmarkFilterMatch/tcp-not-syn-v4-no-logs-8   122943025                9.813 ns/op

Updates #12486

Change-Id: I8e7c9380bf969ad646851d53f8a4c287717694ea
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
5 months ago
Brad Fitzpatrick 10e8a2a05c wgengine/filter: fix copy/pasteo in new benchmark's v6 CIDR
I noticed the not-local-v6 numbers were nowhere near the v4 numbers
(they should be identical) and then saw this. It meant the
Addr().Next() wasn't picking an IP that was no longer local, as
assumed.

Updates #12486

Change-Id: I18dfb641f00c74c6252666bc41bd2248df15fadd
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
5 months ago
Brad Fitzpatrick 7574f586aa wgengine/filter: add more benchmarks, make names more explicit
Updates #12486

Change-Id: If2e6d9c70212644eb4a0bc8ec6768512894a646a
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
5 months ago
Brad Fitzpatrick 21ed31e33a wgengine/filter: use NewContainsIPFunc for Srcs matches
NewContainsIPFunc returns a contains matcher optimized for its
input. Use that instead of what this did before, always doing a test
over each of a list of netip.Prefixes.

    goos: darwin
    goarch: arm64
    pkg: tailscale.com/wgengine/filter
                        │   before    │                after                │
                        │   sec/op    │   sec/op     vs base                │
    FilterMatch/file1-8   32.60n ± 1%   18.87n ± 1%  -42.12% (p=0.000 n=10)

Updates #12486

Change-Id: I8f902bc064effb431e5b46751115942104ff6531
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
5 months ago
Brad Fitzpatrick e2c0d69c9c wgengine/filter: add filter benchmark
Baseline, on 2020 M1 Macbook Pro, on power:

    goos: darwin
    goarch: arm64
    pkg: tailscale.com/wgengine/filter
    BenchmarkFilterMatch/file1-8    34089133                32.79 ns/op
    BenchmarkFilterMatch/file1-8    35423917                32.59 ns/op
    BenchmarkFilterMatch/file1-8    35208598                32.80 ns/op
    BenchmarkFilterMatch/file1-8    35180470                33.39 ns/op
    BenchmarkFilterMatch/file1-8    36671608                32.82 ns/op
    BenchmarkFilterMatch/file1-8    35435991                33.13 ns/op
    BenchmarkFilterMatch/file1-8    34689181                33.29 ns/op
    BenchmarkFilterMatch/file1-8    34786053                32.94 ns/op
    BenchmarkFilterMatch/file1-8    35366235                32.56 ns/op
    BenchmarkFilterMatch/file1-8    35342799                32.47 ns/op

Updates #12486

Change-Id: I8f902bc064effb431e5b46751115942104ff6531
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
5 months ago
Brad Fitzpatrick 7c1d6e35a5 all: use Go 1.22 range-over-int
Updates #11058

Change-Id: I35e7ef9b90e83cac04ca93fd964ad00ed5b48430
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
7 months ago
Andrew Lytvynov 263e01c47b
wgengine/filter: add protocol-agnostic packet checker (#10446)
For use in ACL tests, we need a way to check whether a packet is allowed
not just with TCP, but any protocol.

Updates #3561

Signed-off-by: Andrew Lytvynov <awly@tailscale.com>
12 months ago
Brad Fitzpatrick 8b630c91bc wgengine/filter: use slices.Contains in another place
We keep finding these.

Updates #cleanup

Change-Id: Iabc049b0f8da07341011356f0ecd5315c33ff548
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
1 year ago
James Tucker 324f0d5f80 cmd/cloner,*: revert: optimize nillable slice cloner
This reverts commit ee90cd02fd.

The outcome is not identical for empty slices. Cloner really needs
tests!

Updates #9601

Signed-off-by: James Tucker <james@tailscale.com>
1 year ago
James Tucker ee90cd02fd cmd/cloner,*: optimize nillable slice cloner
A wild @josharian appears with a good suggestion for a refactor, thanks
Josh!

Updates #9410
Signed-off-by: James Tucker <james@tailscale.com>
1 year ago
Maisem Ali d06b48dd0a tailcfg: add RawMessage
This adds a new RawMessage type backed by string instead of the
json.RawMessage which is backed by []byte. The byte slice makes
the generated views be a lot more defensive than the need to be
which we can get around by using a string instead.

Updates #cleanup

Signed-off-by: Maisem Ali <maisem@tailscale.com>
1 year ago
Maisem Ali a61caea911 tailcfg: define a type for NodeCapability
Instead of untyped string, add a type to identify these.

Updates #cleanup

Signed-off-by: Maisem Ali <maisem@tailscale.com>
1 year ago
James Tucker 1858ad65c8 cmd/cloner: do not allocate slices when the source is nil
tailcfg.Node zero-value clone equality checks failed when I added a
[]*foo to the structure, as the zero value and it's clone contained a
different slice header.

Updates #9377
Updates #9408
Signed-off-by: James Tucker <james@tailscale.com>
1 year ago
Brad Fitzpatrick bc0eb6b914 all: import x/exp/maps as xmaps to distinguish from Go 1.21 "maps"
Updates #8419

Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
1 year ago
Brad Fitzpatrick e8551d6b40 all: use Go 1.21 slices, maps instead of x/exp/{slices,maps}
Updates #8419

Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
1 year ago
Maisem Ali 1ecc16da5f tailcfg,ipn/ipnlocal,wgengine: add values to PeerCapabilities
Define PeerCapabilty and PeerCapMap as the new way of sending down
inter-peer capability information.

Previously, this was unstructured and you could only send down strings
which got too limiting for certain usecases. Instead add the ability
to send down raw JSON messages that are opaque to Tailscale but provide
the applications to define them however they wish.

Also update accessors to use the new values.

Updates #4217

Signed-off-by: Maisem Ali <maisem@tailscale.com>
1 year ago
Maisem Ali 1a30b2d73f all: use tstest.Replace more
Signed-off-by: Maisem Ali <maisem@tailscale.com>
2 years ago
Will Norris 71029cea2d all: update copyright and license headers
This updates all source files to use a new standard header for copyright
and license declaration.  Notably, copyright no longer includes a date,
and we now use the standard SPDX-License-Identifier header.

This commit was done almost entirely mechanically with perl, and then
some minimal manual fixes.

Updates #6865

Signed-off-by: Will Norris <will@tailscale.com>
2 years ago
Brad Fitzpatrick c1a2e2c380 net/{packet,tstun},wgengine/filter: fix unknown IP protocol handling
01b90df2fa added SCTP support before
(with explicit parsing for ports) and
69de3bf7bf tried to add support for
arbitrary IP protocols (as long as the ACL permited a port of "*",
since we might not know how to find ports from an arbitrary IP
protocol, if it even has such a concept). But apparently that latter
commit wasn't tested end-to-end enough. It had a lot of tests, but the
tests made assumptions about layering that either weren't true, or
regressed since 1.20. Notably, it didn't remove the (*Filter).pre
bidirectional filter that dropped all "unknown" protocol packets both
leaving and entering, even if there were explicit protocol matches
allowing them in.

Also, don't map all unknown protocols to 0. Keep their IP protocol
number parsed so it's matchable by later layers. Only reject illegal
things.

Fixes #6423
Updates #2162
Updates #2163

Change-Id: I9659b3ece86f4db51d644f9b34df78821758842c
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2 years ago
Brad Fitzpatrick 3386a59cf1 wgengine/filter: include IP proto number in unknown protocol errors
Updates #6423

Change-Id: I9e363922e2c24fdc42687707c069af5bba68b93e
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2 years ago
Brad Fitzpatrick 006ec659e6 wgengine/filter: reorder RunOut disjunctive cases to match RunIn above
Change-Id: Ia422121cde1687044b18be7bea9e7bf51a4183b9
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2 years ago
Tom DNetto 2ac5474be1 net/flowtrack,wgengine/filter: refactor Cache to use generics
Signed-off-by: Tom DNetto <tom@tailscale.com>
2 years ago
Brad Fitzpatrick aad6830df0 util/codegen, all: use latest year, not time.Now, in generated files
Updates #6865

Change-Id: I6b86c646968ebbd4553cf37df5e5612fbf5c5f7d
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2 years ago
Josh Soref d4811f11a0 all: fix spelling mistakes
Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com>
2 years ago
Brad Fitzpatrick 8725b14056 all: migrate more code code to net/netip directly
Instead of going through the tailscale.com/net/netaddr transitional
wrappers.

Updates #5162

Change-Id: I3dafd1c2effa1a6caa9b7151ecf6edd1a3fda3dd
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2 years ago
Brad Fitzpatrick 116f55ff66 all: gofmt for Go 1.19
Updates #5210

Change-Id: Ib02cd5e43d0a8db60c1f09755a8ac7b140b670be
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2 years ago
Brad Fitzpatrick a12aad6b47 all: convert more code to use net/netip directly
perl -i -npe 's,netaddr.IPPrefixFrom,netip.PrefixFrom,' $(git grep -l -F netaddr.)
    perl -i -npe 's,netaddr.IPPortFrom,netip.AddrPortFrom,' $(git grep -l -F netaddr. )
    perl -i -npe 's,netaddr.IPPrefix,netip.Prefix,g' $(git grep -l -F netaddr. )
    perl -i -npe 's,netaddr.IPPort,netip.AddrPort,g' $(git grep -l -F netaddr. )
    perl -i -npe 's,netaddr.IP\b,netip.Addr,g' $(git grep -l -F netaddr. )
    perl -i -npe 's,netaddr.IPv6Raw\b,netip.AddrFrom16,g' $(git grep -l -F netaddr. )
    goimports -w .

Then delete some stuff from the net/netaddr shim package which is no
longer neeed.

Updates #5162

Change-Id: Ia7a86893fe21c7e3ee1ec823e8aba288d4566cd8
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2 years ago
Brad Fitzpatrick 6a396731eb all: use various net/netip parse funcs directly
Mechanical change with perl+goimports.

Changed {Must,}Parse{IP,IPPrefix,IPPort} to their netip variants, then
goimports -d .

Finally, removed the net/netaddr wrappers, to prevent future use.

Updates #5162

Change-Id: I59c0e38b5fbca5a935d701645789cddf3d7863ad
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2 years ago
Brad Fitzpatrick 7eaf5e509f net/netaddr: start migrating to net/netip via new netaddr adapter package
Updates #5162

Change-Id: Id7bdec303b25471f69d542f8ce43805328d56c12
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2 years ago
Tom 9343967317
wgengine/filter: preallocate some hot slices in MatchesFromFilterRules (#4672)
Profiling identified this as a fairly hot path for growing a slice.

Given this is only used in control & when a new packet filter is received, this shouldnt be hot in the client.
3 years ago
Maisem Ali e409e59a54 cmd/cloner,util/codegen: refactor cloner internals to allow reuse
Also run go generate again for Copyright updates.

Signed-off-by: Maisem Ali <maisem@tailscale.com>
3 years ago
Brad Fitzpatrick 16f3520089 all: add arbitrary capability support
Updates #4217

RELNOTE=start of WhoIsResponse capability support

Change-Id: I6522998a911fe49e2f003077dad6164c017eed9b
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
3 years ago
Brad Fitzpatrick f2041c9088 all: use strings.Cut even more
Change-Id: I943ce72c6f339589235bddbe10d07799c4e37979
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
3 years ago
Josh Bleecher Snyder 0868329936 all: use any instead of interface{}
My favorite part of generics.

Signed-off-by: Josh Bleecher Snyder <josh@tailscale.com>
3 years ago
Brad Fitzpatrick 61ee72940c all: use Go 1.18's strings.Cut
More remain.

Change-Id: I6ec562cc1f687600758deae1c9d7dbd0d04004cb
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
3 years ago
Brad Fitzpatrick 41fd4eab5c envknob: add new package for all the strconv.ParseBool(os.Getenv(..))
A new package can also later record/report which knobs are checked and
set. It also makes the code cleaner & easier to grep for env knobs.

Change-Id: Id8a123ab7539f1fadbd27e0cbeac79c2e4f09751
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
3 years ago
Brad Fitzpatrick 69de3bf7bf wgengine/filter: let unknown IPProto match if IP okay & match allows all ports
RELNOTE=yes

Change-Id: I96eaf3cf550cee7bb6cdb4ad81fc761e280a1b2a
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
3 years ago
Brad Fitzpatrick ff9727c9ff wgengine/filter: fix, test NewAllowAllForTest
I probably broke it when SCTP support was added but nothing apparently
ever used NewAllowAllForTest so it wasn't noticed when it broke.

Change-Id: Ib5a405be233d53cb7fcc61d493ae7aa2d1d590a2
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
3 years ago
Josh Bleecher Snyder 94fb42d4b2 all: use testingutil.MinAllocsPerRun
There are a few remaining uses of testing.AllocsPerRun:
Two in which we only log the number of allocations,
and one in which dynamically calculate the allocations
target based on a different AllocsPerRun run.

This also allows us to tighten the "no allocs"
test in wgengine/filter.

Signed-off-by: Josh Bleecher Snyder <josh@tailscale.com>
3 years ago
Joe Tsai 9af27ba829 cmd/cloner: mangle "go:generate" in cloner.go
The "go generate" command blindly looks for "//go:generate" anywhere
in the file regardless of whether it is truly a comment.
Prevent this false positive in cloner.go by mangling the string
to look less like "//go:generate".

Signed-off-by: Joe Tsai <joetsai@digital-static.net>
3 years ago
Josh Bleecher Snyder d5ab18b2e6 cmd/cloner: add Clone context to regen struct assignments
Signed-off-by: Josh Bleecher Snyder <josh@tailscale.com>
3 years ago
Josh Bleecher Snyder 4bbf5a8636 cmd/cloner: reduce diff noise when changing command
Spelling out the command to run for every type
means that changing the command makes for a large, repetitive diff.
Stop doing that.

Signed-off-by: Josh Bleecher Snyder <josh@tailscale.com>
3 years ago