summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorJames Tucker <james@tailscale.com>2022-09-27 18:45:02 -0700
committerJames Tucker <james@tailscale.com>2022-09-27 18:45:02 -0700
commit919ad7df827a8a8043b1e9f1530a0bd66b17ddc1 (patch)
treea943cea75c78ea75aaf85fc8be4b4848f4242a7b
parent627c60b0d1630f65028d5316dde8a396593aa829 (diff)
downloadtailscale-raggi/accept-routes-filter.tar.xz
tailscale-raggi/accept-routes-filter.zip
ipn,ipn/ipnlocal,cmd/tailscale/cli: add support for passing a route filter via --accept-routesraggi/accept-routes-filter
Signed-off-by: James Tucker <james@tailscale.com>
-rw-r--r--cmd/tailscale/cli/up.go39
-rw-r--r--ipn/ipnlocal/local.go31
-rw-r--r--ipn/prefs.go26
3 files changed, 59 insertions, 37 deletions
diff --git a/cmd/tailscale/cli/up.go b/cmd/tailscale/cli/up.go
index d93058956..d98c9fb3a 100644
--- a/cmd/tailscale/cli/up.go
+++ b/cmd/tailscale/cli/up.go
@@ -69,14 +69,17 @@ func effectiveGOOS() string {
// acceptRouteDefault returns the CLI's default value of --accept-routes as
// a function of the platform it's running on.
-func acceptRouteDefault(goos string) bool {
+func acceptRouteDefault(goos string) string {
switch goos {
case "windows":
- return true
+ return "true"
case "darwin":
- return version.IsSandboxedMacOS()
+ if version.IsSandboxedMacOS() {
+ return "true"
+ }
+ return "false"
default:
- return false
+ return "false"
}
}
@@ -93,7 +96,7 @@ func newUpFlagSet(goos string, upArgs *upArgsT) *flag.FlagSet {
upf.BoolVar(&upArgs.reset, "reset", false, "reset unspecified settings to their default values")
upf.StringVar(&upArgs.server, "login-server", ipn.DefaultControlURL, "base URL of control server")
- upf.BoolVar(&upArgs.acceptRoutes, "accept-routes", acceptRouteDefault(goos), "accept routes advertised by other Tailscale nodes")
+ upf.StringVar(&upArgs.acceptRoutes, "accept-routes", acceptRouteDefault(goos), "accept routes advertised by other Tailscale nodes")
upf.BoolVar(&upArgs.acceptDNS, "accept-dns", true, "accept DNS configuration from the admin panel")
upf.BoolVar(&upArgs.singleRoutes, "host-routes", true, "install host routes to other Tailscale nodes")
upf.StringVar(&upArgs.exitNodeIP, "exit-node", "", "Tailscale exit node (IP or base name) for internet traffic, or empty string to not use an exit node")
@@ -131,7 +134,7 @@ type upArgsT struct {
qr bool
reset bool
server string
- acceptRoutes bool
+ acceptRoutes string
acceptDNS bool
singleRoutes bool
exitNodeIP string
@@ -307,7 +310,25 @@ func prefsFromUpArgs(upArgs upArgsT, warnf logger.Logf, st *ipnstate.Status, goo
prefs := ipn.NewPrefs()
prefs.ControlURL = upArgs.server
prefs.WantRunning = true
- prefs.RouteAll = upArgs.acceptRoutes
+
+ switch upArgs.acceptRoutes {
+ case "0", "f", "false":
+ prefs.RouteAll = false
+ case "1", "t", "true":
+ prefs.RouteAll = true
+ default:
+ prefs.RouteAll = true
+ prefs.AcceptRoutesFilter = upArgs.acceptRoutes
+
+ // accept-routes accepts an include/exclude ip range of the form:
+ // 0.0.0.0/0,-192.168.20.0/24
+ // Ensure that the provided values parse correctly, as the backend can only
+ // bury errors in the logs.
+ _, err := ipn.ParseAcceptRoutesFilter(prefs.AcceptRoutesFilter)
+ if err != nil {
+ return nil, fmt.Errorf("accept-routes filter %q did not parse: %w", prefs.AcceptRoutesFilter, err)
+ }
+ }
if upArgs.exitNodeIP != "" {
if err := prefs.SetExitNodeIP(upArgs.exitNodeIP, st); err != nil {
@@ -453,7 +474,7 @@ func runUp(ctx context.Context, args []string) (retErr error) {
if distro.Get() == distro.Synology {
notSupported := "not supported on Synology; see https://github.com/tailscale/tailscale/issues/1995"
- if upArgs.acceptRoutes {
+ if upArgs.acceptRoutes != "" && upArgs.acceptRoutes != "f" && upArgs.acceptRoutes != "false" {
return errors.New("--accept-routes is " + notSupported)
}
if upArgs.exitNodeIP != "" {
@@ -735,10 +756,10 @@ func init() {
// And this flag has two ipn.Prefs:
addPrefFlagMapping("exit-node", "ExitNodeIP", "ExitNodeID")
+ addPrefFlagMapping("accept-routes", "RouteAll", "AcceptRoutesFilter")
// The rest are 1:1:
addPrefFlagMapping("accept-dns", "CorpDNS")
- addPrefFlagMapping("accept-routes", "RouteAll")
addPrefFlagMapping("advertise-tags", "AdvertiseTags")
addPrefFlagMapping("host-routes", "AllowSingleHosts")
addPrefFlagMapping("hostname", "Hostname")
diff --git a/ipn/ipnlocal/local.go b/ipn/ipnlocal/local.go
index 7f130f2db..03c25d52e 100644
--- a/ipn/ipnlocal/local.go
+++ b/ipn/ipnlocal/local.go
@@ -2775,32 +2775,6 @@ func ipPrefixLess(ri, rj netip.Prefix) bool {
return ri.Addr().Less(rj.Addr())
}
-func (b *LocalBackend) parseAcceptRoutesFilter(acceptFilter string) (*netipx.IPSet, error) {
- var acceptFilterBuilder netipx.IPSetBuilder
- for _, af := range strings.Split(acceptFilter, ",") {
- af = strings.TrimSpace(af)
- if af == "" {
- continue
- }
- includeRange := true
- if strings.HasPrefix(af, "-") {
- includeRange = false
- af = af[1:]
- }
- pfx, err := netip.ParsePrefix(af)
- if err != nil {
- b.logf("accept routes filter: invalid prefix %q will be ignored: %v (check accept-routes flag)", af, err)
- continue
- }
- if includeRange {
- acceptFilterBuilder.AddPrefix(pfx)
- } else {
- acceptFilterBuilder.RemovePrefix(pfx)
- }
- }
- return acceptFilterBuilder.IPSet()
-}
-
func (b *LocalBackend) filterRoutes(routes []netip.Prefix, acceptFilter *netipx.IPSet) []netip.Prefix {
if acceptFilter == nil {
return routes
@@ -2815,6 +2789,7 @@ func (b *LocalBackend) filterRoutes(routes []netip.Prefix, acceptFilter *netipx.
b.logf("accept routes filter: failed to build filtered set, all routes will be accepted: %v (check accept-routes flag)", err)
return routes
}
+ b.logf("accept routes filter: accepting routes: %v", set.Ranges())
return set.Prefixes()
}
@@ -2825,9 +2800,9 @@ func (b *LocalBackend) routerConfig(cfg *wgcfg.Config, prefs *ipn.Prefs, oneCGNA
singleRouteThreshold = 1
}
- acceptRoutesFilterSet, err := b.parseAcceptRoutesFilter(prefs.AcceptRoutesFilter)
+ acceptRoutesFilterSet, err := ipn.ParseAcceptRoutesFilter(prefs.AcceptRoutesFilter)
if err != nil {
- b.logf("accept routes filter: failed to build filter set: %v", err)
+ b.logf("accept routes filter: failed to build filter set from %q: %v", prefs.AcceptRoutesFilter, err)
}
rs := &router.Config{
diff --git a/ipn/prefs.go b/ipn/prefs.go
index 49c1a236c..aaf369dda 100644
--- a/ipn/prefs.go
+++ b/ipn/prefs.go
@@ -17,6 +17,7 @@ import (
"runtime"
"strings"
+ "go4.org/netipx"
"tailscale.com/atomicfile"
"tailscale.com/ipn/ipnstate"
"tailscale.com/net/netaddr"
@@ -657,3 +658,28 @@ func SavePrefs(filename string, p *Prefs) {
log.Printf("SavePrefs: %v\n", err)
}
}
+
+func ParseAcceptRoutesFilter(acceptFilter string) (*netipx.IPSet, error) {
+ var acceptFilterBuilder netipx.IPSetBuilder
+ for _, af := range strings.Split(acceptFilter, ",") {
+ af = strings.TrimSpace(af)
+ if af == "" {
+ continue
+ }
+ includeRange := true
+ if strings.HasPrefix(af, "-") {
+ includeRange = false
+ af = af[1:]
+ }
+ pfx, err := netip.ParsePrefix(af)
+ if err != nil {
+ return nil, err
+ }
+ if includeRange {
+ acceptFilterBuilder.AddPrefix(pfx)
+ } else {
+ acceptFilterBuilder.RemovePrefix(pfx)
+ }
+ }
+ return acceptFilterBuilder.IPSet()
+}