cmd/tailscale/cli: add CLI option to offer an exit node to the tailnet.

Finishes up linux part of #1154.

Signed-off-by: David Anderson <danderson@tailscale.com>
pull/1395/head
David Anderson 4 years ago
parent e9e4f1063d
commit ebf3f2fd9f

@ -14,6 +14,7 @@ import (
"os" "os"
"os/exec" "os/exec"
"runtime" "runtime"
"sort"
"strconv" "strconv"
"strings" "strings"
"sync" "sync"
@ -53,6 +54,7 @@ specify any flags, options are reset to their default.
upf.StringVar(&upArgs.hostname, "hostname", "", "hostname to use instead of the one provided by the OS") upf.StringVar(&upArgs.hostname, "hostname", "", "hostname to use instead of the one provided by the OS")
if runtime.GOOS == "linux" || isBSD(runtime.GOOS) || version.OS() == "macOS" { if runtime.GOOS == "linux" || isBSD(runtime.GOOS) || version.OS() == "macOS" {
upf.StringVar(&upArgs.advertiseRoutes, "advertise-routes", "", "routes to advertise to other nodes (comma-separated, e.g. 10.0.0.0/8,192.168.0.0/24)") upf.StringVar(&upArgs.advertiseRoutes, "advertise-routes", "", "routes to advertise to other nodes (comma-separated, e.g. 10.0.0.0/8,192.168.0.0/24)")
upf.BoolVar(&upArgs.advertiseDefaultRoute, "advertise-exit-node", false, "offer to be an exit node for internet traffic for the tailnet")
} }
if runtime.GOOS == "linux" { if runtime.GOOS == "linux" {
upf.BoolVar(&upArgs.snat, "snat-subnet-routes", true, "source NAT traffic to local routes advertised with --advertise-routes") upf.BoolVar(&upArgs.snat, "snat-subnet-routes", true, "source NAT traffic to local routes advertised with --advertise-routes")
@ -79,6 +81,7 @@ var upArgs struct {
shieldsUp bool shieldsUp bool
forceReauth bool forceReauth bool
advertiseRoutes string advertiseRoutes string
advertiseDefaultRoute bool
advertiseTags string advertiseTags string
snat bool snat bool
netfilterMode string netfilterMode string
@ -148,7 +151,7 @@ func runUp(ctx context.Context, args []string) error {
} }
} }
var routes []netaddr.IPPrefix routeMap := map[netaddr.IPPrefix]bool{}
var default4, default6 bool var default4, default6 bool
if upArgs.advertiseRoutes != "" { if upArgs.advertiseRoutes != "" {
advroutes := strings.Split(upArgs.advertiseRoutes, ",") advroutes := strings.Split(upArgs.advertiseRoutes, ",")
@ -165,15 +168,31 @@ func runUp(ctx context.Context, args []string) error {
} else if ipp == ipv6default { } else if ipp == ipv6default {
default6 = true default6 = true
} }
routes = append(routes, ipp) routeMap[ipp] = true
} }
if default4 && !default6 { if default4 && !default6 {
fatalf("%s advertised without its IPv6 counterpart, please also advertise %s", ipv4default, ipv6default) fatalf("%s advertised without its IPv6 counterpart, please also advertise %s", ipv4default, ipv6default)
} else if default6 && !default4 { } else if default6 && !default4 {
fatalf("%s advertised without its IPv6 counterpart, please also advertise %s", ipv6default, ipv4default) fatalf("%s advertised without its IPv6 counterpart, please also advertise %s", ipv6default, ipv4default)
} }
}
if upArgs.advertiseDefaultRoute {
routeMap[netaddr.MustParseIPPrefix("0.0.0.0/0")] = true
routeMap[netaddr.MustParseIPPrefix("::/0")] = true
}
if len(routeMap) > 0 {
checkIPForwarding() checkIPForwarding()
} }
routes := make([]netaddr.IPPrefix, 0, len(routeMap))
for r := range routeMap {
routes = append(routes, r)
}
sort.Slice(routes, func(i, j int) bool {
if routes[i].Bits != routes[j].Bits {
return routes[i].Bits < routes[j].Bits
}
return routes[i].IP.Less(routes[j].IP)
})
var exitNodeIP netaddr.IP var exitNodeIP netaddr.IP
if upArgs.exitNodeIP != "" { if upArgs.exitNodeIP != "" {

Loading…
Cancel
Save