From 2d0ecbb883318eb85e24aaad8f79147516d8fde2 Mon Sep 17 00:00:00 2001 From: James Tucker Date: Tue, 27 Sep 2022 17:46:16 -0700 Subject: [PATCH] ipn: add AcceptRoutesFilter preference for filtering peer routes The preference is stored in string form as the internal representation netipx.IPSetBuilder does not serialize. The string form is reasonably compact and readable. Signed-off-by: James Tucker --- ipn/ipn_clone.go | 1 + ipn/prefs.go | 23 ++++++++++++++++++----- ipn/prefs_test.go | 1 + 3 files changed, 20 insertions(+), 5 deletions(-) diff --git a/ipn/ipn_clone.go b/ipn/ipn_clone.go index 9794dc671..abf374190 100644 --- a/ipn/ipn_clone.go +++ b/ipn/ipn_clone.go @@ -35,6 +35,7 @@ func (src *Prefs) Clone() *Prefs { var _PrefsCloneNeedsRegeneration = Prefs(struct { ControlURL string RouteAll bool + AcceptRoutesFilter string AllowSingleHosts bool ExitNodeID tailcfg.StableNodeID ExitNodeIP netip.Addr diff --git a/ipn/prefs.go b/ipn/prefs.go index 51b7fff64..49c1a236c 100644 --- a/ipn/prefs.go +++ b/ipn/prefs.go @@ -70,6 +70,13 @@ type Prefs struct { // controlled by ExitNodeID/IP below. RouteAll bool + // AcceptRoutesFilter specifies an ordered list of IP ranges that are to be + // included or excluded from peer routes. The value is comma-seprated IP CIDRs + // with an optional leading `-` prefix indicating an exclusion, e.g. + // "0.0.0.0/0,-192.168.20.0/24" meaning "all routes except those intersecting + // 192.168.20.0/24". + AcceptRoutesFilter string + // AllowSingleHosts specifies whether to install routes for each // node IP on the tailscale network, in addition to a route for // the whole network. @@ -206,6 +213,7 @@ type MaskedPrefs struct { ControlURLSet bool `json:",omitempty"` RouteAllSet bool `json:",omitempty"` + AcceptRoutesFilterSet bool `json:",omitempty"` AllowSingleHostsSet bool `json:",omitempty"` ExitNodeIDSet bool `json:",omitempty"` ExitNodeIPSet bool `json:",omitempty"` @@ -293,6 +301,9 @@ func (p *Prefs) pretty(goos string) string { var sb strings.Builder sb.WriteString("Prefs{") fmt.Fprintf(&sb, "ra=%v ", p.RouteAll) + if p.RouteAll || p.AcceptRoutesFilter != "" { + fmt.Fprintf(&sb, "acceptfilter=%q ", p.AcceptRoutesFilter) + } if !p.AllowSingleHosts { sb.WriteString("mesh=false ") } @@ -366,6 +377,7 @@ func (p *Prefs) Equals(p2 *Prefs) bool { return p != nil && p2 != nil && p.ControlURL == p2.ControlURL && p.RouteAll == p2.RouteAll && + p.AcceptRoutesFilter == p2.AcceptRoutesFilter && p.AllowSingleHosts == p2.AllowSingleHosts && p.ExitNodeID == p2.ExitNodeID && p.ExitNodeIP == p2.ExitNodeIP && @@ -423,11 +435,12 @@ func NewPrefs() *Prefs { // later anyway. ControlURL: "", - RouteAll: true, - AllowSingleHosts: true, - CorpDNS: true, - WantRunning: false, - NetfilterMode: preftype.NetfilterOn, + RouteAll: true, + AcceptRoutesFilter: "0.0.0.0/0,::/0", + AllowSingleHosts: true, + CorpDNS: true, + WantRunning: false, + NetfilterMode: preftype.NetfilterOn, } } diff --git a/ipn/prefs_test.go b/ipn/prefs_test.go index f76796419..33ba0233d 100644 --- a/ipn/prefs_test.go +++ b/ipn/prefs_test.go @@ -38,6 +38,7 @@ func TestPrefsEqual(t *testing.T) { prefsHandles := []string{ "ControlURL", "RouteAll", + "AcceptRoutesFilter", "AllowSingleHosts", "ExitNodeID", "ExitNodeIP",