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>
This commit is contained in:
Brad Fitzpatrick
2022-07-24 20:08:42 -07:00
committed by Brad Fitzpatrick
parent 7b1a91dfd3
commit 7eaf5e509f
191 changed files with 1009 additions and 888 deletions

View File

@@ -10,9 +10,10 @@ import (
"sync"
"time"
"inet.af/netaddr"
"go4.org/netipx"
"tailscale.com/envknob"
"tailscale.com/net/flowtrack"
"tailscale.com/net/netaddr"
"tailscale.com/net/packet"
"tailscale.com/tstime/rate"
"tailscale.com/types/ipproto"
@@ -26,12 +27,12 @@ type Filter struct {
// this node. All packets coming in over tailscale must have a
// destination within local, regardless of the policy filter
// below.
local *netaddr.IPSet
local *netipx.IPSet
// logIPs is the set of IPs that are allowed to appear in flow
// logs. If a packet is to or from an IP not in logIPs, it will
// never be logged.
logIPs *netaddr.IPSet
logIPs *netipx.IPSet
// matches4 and matches6 are lists of match->action rules
// applied to all packets arriving over tailscale
@@ -137,7 +138,7 @@ func NewAllowAllForTest(logf logger.Logf) *Filter {
},
}
var sb netaddr.IPSetBuilder
var sb netipx.IPSetBuilder
sb.AddPrefix(any4)
sb.AddPrefix(any6)
ipSet, _ := sb.IPSet()
@@ -145,15 +146,15 @@ func NewAllowAllForTest(logf logger.Logf) *Filter {
}
// NewAllowNone returns a packet filter that rejects everything.
func NewAllowNone(logf logger.Logf, logIPs *netaddr.IPSet) *Filter {
return New(nil, &netaddr.IPSet{}, logIPs, nil, logf)
func NewAllowNone(logf logger.Logf, logIPs *netipx.IPSet) *Filter {
return New(nil, &netipx.IPSet{}, logIPs, nil, logf)
}
// NewShieldsUpFilter returns a packet filter that rejects incoming connections.
//
// If shareStateWith is non-nil, the returned filter shares state with the previous one,
// as long as the previous one was also a shields up filter.
func NewShieldsUpFilter(localNets *netaddr.IPSet, logIPs *netaddr.IPSet, shareStateWith *Filter, logf logger.Logf) *Filter {
func NewShieldsUpFilter(localNets *netipx.IPSet, logIPs *netipx.IPSet, shareStateWith *Filter, logf logger.Logf) *Filter {
// Don't permit sharing state with a prior filter that wasn't a shields-up filter.
if shareStateWith != nil && !shareStateWith.shieldsUp {
shareStateWith = nil
@@ -168,7 +169,7 @@ func NewShieldsUpFilter(localNets *netaddr.IPSet, logIPs *netaddr.IPSet, shareSt
// by matches. If shareStateWith is non-nil, the returned filter
// shares state with the previous one, to enable changing rules at
// runtime without breaking existing stateful flows.
func New(matches []Match, localNets *netaddr.IPSet, logIPs *netaddr.IPSet, shareStateWith *Filter, logf logger.Logf) *Filter {
func New(matches []Match, localNets *netipx.IPSet, logIPs *netipx.IPSet, shareStateWith *Filter, logf logger.Logf) *Filter {
var state *filterState
if shareStateWith != nil {
state = shareStateWith.state
@@ -198,12 +199,12 @@ func matchesFamily(ms matches, keep func(netaddr.IP) bool) matches {
var retm Match
retm.IPProto = m.IPProto
for _, src := range m.Srcs {
if keep(src.IP()) {
if keep(src.Addr()) {
retm.Srcs = append(retm.Srcs, src)
}
}
for _, dst := range m.Dsts {
if keep(dst.Net.IP()) {
if keep(dst.Net.Addr()) {
retm.Dsts = append(retm.Dsts, dst)
}
}
@@ -224,7 +225,7 @@ func capMatchesFunc(ms matches, keep func(netaddr.IP) bool) matches {
}
retm := Match{Caps: m.Caps}
for _, src := range m.Srcs {
if keep(src.IP()) {
if keep(src.Addr()) {
retm.Srcs = append(retm.Srcs, src)
}
}
@@ -390,7 +391,7 @@ func (f *Filter) runIn4(q *packet.Parsed) (r Response, why string) {
// A compromised peer could try to send us packets for
// destinations we didn't explicitly advertise. This check is to
// prevent that.
if !f.local.Contains(q.Dst.IP()) {
if !f.local.Contains(q.Dst.Addr()) {
return Drop, "destination not allowed"
}
@@ -450,7 +451,7 @@ func (f *Filter) runIn6(q *packet.Parsed) (r Response, why string) {
// A compromised peer could try to send us packets for
// destinations we didn't explicitly advertise. This check is to
// prevent that.
if !f.local.Contains(q.Dst.IP()) {
if !f.local.Contains(q.Dst.Addr()) {
return Drop, "destination not allowed"
}
@@ -555,11 +556,11 @@ func (f *Filter) pre(q *packet.Parsed, rf RunFlags, dir direction) Response {
return Drop
}
if q.Dst.IP().IsMulticast() {
if q.Dst.Addr().IsMulticast() {
f.logRateLimit(rf, q, dir, Drop, "multicast")
return Drop
}
if q.Dst.IP().IsLinkLocalUnicast() && q.Dst.IP() != gcpDNSAddr {
if q.Dst.Addr().IsLinkLocalUnicast() && q.Dst.Addr() != gcpDNSAddr {
f.logRateLimit(rf, q, dir, Drop, "link-local-unicast")
return Drop
}
@@ -581,7 +582,7 @@ func (f *Filter) pre(q *packet.Parsed, rf RunFlags, dir direction) Response {
// loggingAllowed reports whether p can appear in logs at all.
func (f *Filter) loggingAllowed(p *packet.Parsed) bool {
return f.logIPs.Contains(p.Src.IP()) && f.logIPs.Contains(p.Dst.IP())
return f.logIPs.Contains(p.Src.Addr()) && f.logIPs.Contains(p.Dst.Addr())
}
// omitDropLogging reports whether packet p, which has already been
@@ -593,5 +594,5 @@ func omitDropLogging(p *packet.Parsed, dir direction) bool {
return false
}
return p.Dst.IP().IsMulticast() || (p.Dst.IP().IsLinkLocalUnicast() && p.Dst.IP() != gcpDNSAddr) || p.IPProto == ipproto.IGMP
return p.Dst.Addr().IsMulticast() || (p.Dst.Addr().IsLinkLocalUnicast() && p.Dst.Addr() != gcpDNSAddr) || p.IPProto == ipproto.IGMP
}

View File

@@ -7,7 +7,8 @@
package filter
import (
"inet.af/netaddr"
"net/netip"
"tailscale.com/types/ipproto"
)
@@ -29,7 +30,7 @@ func (src *Match) Clone() *Match {
// A compilation failure here means this code must be regenerated, with the command at the top of this file.
var _MatchCloneNeedsRegeneration = Match(struct {
IPProto []ipproto.Proto
Srcs []netaddr.IPPrefix
Srcs []netip.Prefix
Dsts []NetPortRange
Caps []CapMatch
}{})

View File

@@ -13,7 +13,8 @@ import (
"testing"
"github.com/google/go-cmp/cmp"
"inet.af/netaddr"
"go4.org/netipx"
"tailscale.com/net/netaddr"
"tailscale.com/net/packet"
"tailscale.com/net/tsaddr"
"tailscale.com/tailcfg"
@@ -58,12 +59,12 @@ func newFilter(logf logger.Logf) *Filter {
// Expects traffic to 100.122.98.50, 1.2.3.4, 5.6.7.8,
// 102.102.102.102, 119.119.119.119, 8.1.0.0/16
var localNets netaddr.IPSetBuilder
var localNets netipx.IPSetBuilder
for _, n := range nets("100.122.98.50", "1.2.3.4", "5.6.7.8", "102.102.102.102", "119.119.119.119", "8.1.0.0/16", "2001::/16") {
localNets.AddPrefix(n)
}
var logB netaddr.IPSetBuilder
var logB netipx.IPSetBuilder
logB.Complement()
localNetsSet, _ := localNets.IPSet()
logBSet, _ := logB.IPSet()
@@ -140,9 +141,9 @@ func TestFilter(t *testing.T) {
if test.p.IPProto == ipproto.TCP {
var got Response
if test.p.IPVersion == 4 {
got = acl.CheckTCP(test.p.Src.IP(), test.p.Dst.IP(), test.p.Dst.Port())
got = acl.CheckTCP(test.p.Src.Addr(), test.p.Dst.Addr(), test.p.Dst.Port())
} else {
got = acl.CheckTCP(test.p.Src.IP(), test.p.Dst.IP(), test.p.Dst.Port())
got = acl.CheckTCP(test.p.Src.Addr(), test.p.Dst.Addr(), test.p.Dst.Port())
}
if test.want != got {
t.Errorf("#%d CheckTCP got=%v want=%v packet:%v", i, got, test.want, test.p)
@@ -340,7 +341,7 @@ func TestPreFilter(t *testing.T) {
{"udp", noVerdict, raw4default(ipproto.UDP, 0)},
{"icmp", noVerdict, raw4default(ipproto.ICMPv4, 0)},
}
f := NewAllowNone(t.Logf, &netaddr.IPSet{})
f := NewAllowNone(t.Logf, &netipx.IPSet{})
for _, testPacket := range packets {
p := &packet.Parsed{}
p.Decode(testPacket.b)
@@ -437,16 +438,16 @@ func TestLoggingPrivacy(t *testing.T) {
logged = true
}
var logB netaddr.IPSetBuilder
var logB netipx.IPSetBuilder
logB.AddPrefix(netaddr.MustParseIPPrefix("100.64.0.0/10"))
logB.AddPrefix(tsaddr.TailscaleULARange())
f := newFilter(logf)
f.logIPs, _ = logB.IPSet()
var (
ts4 = netaddr.IPPortFrom(tsaddr.CGNATRange().IP().Next(), 1234)
ts4 = netaddr.IPPortFrom(tsaddr.CGNATRange().Addr().Next(), 1234)
internet4 = netaddr.IPPortFrom(netaddr.MustParseIP("8.8.8.8"), 1234)
ts6 = netaddr.IPPortFrom(tsaddr.TailscaleULARange().IP().Next(), 1234)
ts6 = netaddr.IPPortFrom(tsaddr.TailscaleULARange().Addr().Next(), 1234)
internet6 = netaddr.IPPortFrom(netaddr.MustParseIP("2001::1"), 1234)
)

View File

@@ -8,7 +8,7 @@ import (
"fmt"
"strings"
"inet.af/netaddr"
"tailscale.com/net/netaddr"
"tailscale.com/net/packet"
"tailscale.com/types/ipproto"
)
@@ -99,11 +99,11 @@ func (ms matches) match(q *packet.Parsed) bool {
if !protoInList(q.IPProto, m.IPProto) {
continue
}
if !ipInList(q.Src.IP(), m.Srcs) {
if !ipInList(q.Src.Addr(), m.Srcs) {
continue
}
for _, dst := range m.Dsts {
if !dst.Net.Contains(q.Dst.IP()) {
if !dst.Net.Contains(q.Dst.Addr()) {
continue
}
if !dst.Ports.contains(q.Dst.Port()) {
@@ -117,11 +117,11 @@ func (ms matches) match(q *packet.Parsed) bool {
func (ms matches) matchIPsOnly(q *packet.Parsed) bool {
for _, m := range ms {
if !ipInList(q.Src.IP(), m.Srcs) {
if !ipInList(q.Src.Addr(), m.Srcs) {
continue
}
for _, dst := range m.Dsts {
if dst.Net.Contains(q.Dst.IP()) {
if dst.Net.Contains(q.Dst.Addr()) {
return true
}
}
@@ -137,14 +137,14 @@ func (ms matches) matchProtoAndIPsOnlyIfAllPorts(q *packet.Parsed) bool {
if !protoInList(q.IPProto, m.IPProto) {
continue
}
if !ipInList(q.Src.IP(), m.Srcs) {
if !ipInList(q.Src.Addr(), m.Srcs) {
continue
}
for _, dst := range m.Dsts {
if dst.Ports != allPorts {
continue
}
if dst.Net.Contains(q.Dst.IP()) {
if dst.Net.Contains(q.Dst.Addr()) {
return true
}
}

View File

@@ -8,7 +8,8 @@ import (
"fmt"
"strings"
"inet.af/netaddr"
"go4.org/netipx"
"tailscale.com/net/netaddr"
"tailscale.com/tailcfg"
"tailscale.com/types/ipproto"
)
@@ -140,7 +141,7 @@ func parseIPSet(arg string, bits *int) ([]netaddr.IPPrefix, error) {
if err != nil {
return nil, err
}
r := netaddr.IPRangeFrom(ip1, ip2)
r := netipx.IPRangeFrom(ip1, ip2)
if !r.Valid() {
return nil, fmt.Errorf("invalid IP range %q", arg)
}
@@ -150,7 +151,7 @@ func parseIPSet(arg string, bits *int) ([]netaddr.IPPrefix, error) {
if err != nil {
return nil, fmt.Errorf("invalid IP address %q", arg)
}
bits8 := ip.BitLen()
bits8 := uint8(ip.BitLen())
if bits != nil {
if *bits < 0 || *bits > int(bits8) {
return nil, fmt.Errorf("invalid CIDR size %d for IP %q", *bits, arg)