// Copyright (c) 2020 Tailscale Inc & AUTHORS All rights reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. // Package router presents an interface to manipulate the host network // stack's state. package router import ( "github.com/tailscale/wireguard-go/device" "github.com/tailscale/wireguard-go/tun" "inet.af/netaddr" "tailscale.com/types/logger" "tailscale.com/wgengine/router/dns" ) // Router is responsible for managing the system network stack. // // There is typically only one instance of this interface per process. type Router interface { // Up brings the router up. Up() error // Set updates the OS network stack with a new Config. It may be // called multiple times with identical Configs, which the // implementation should handle gracefully. Set(*Config) error // Close closes the router. Close() error } // New returns a new Router for the current platform, using the // provided tun device. func New(logf logger.Logf, wgdev *device.Device, tundev tun.Device) (Router, error) { logf = logger.WithPrefix(logf, "router: ") return newUserspaceRouter(logf, wgdev, tundev) } // Cleanup restores the system network configuration to its original state // in case the Tailscale daemon terminated without closing the router. // No other state needs to be instantiated before this runs. func Cleanup(logf logger.Logf, interfaceName string) { mconfig := dns.ManagerConfig{ Logf: logf, InterfaceName: interfaceName, Cleanup: true, } dns := dns.NewManager(mconfig) if err := dns.Down(); err != nil { logf("dns down: %v", err) } cleanup(logf, interfaceName) } // NetfilterMode is the firewall management mode to use when // programming the Linux network stack. type NetfilterMode int const ( NetfilterOff NetfilterMode = iota // remove all tailscale netfilter state NetfilterNoDivert // manage tailscale chains, but don't call them NetfilterOn // manage tailscale chains and call them from main chains ) func (m NetfilterMode) String() string { switch m { case NetfilterOff: return "off" case NetfilterNoDivert: return "nodivert" case NetfilterOn: return "on" default: return "???" } } // Config is the subset of Tailscale configuration that is relevant to // the OS's network stack. type Config struct { LocalAddrs []netaddr.IPPrefix Routes []netaddr.IPPrefix // routes to point into the Tailscale interface DNS dns.Config // Linux-only things below, ignored on other platforms. SubnetRoutes []netaddr.IPPrefix // subnets being advertised to other Tailscale nodes SNATSubnetRoutes bool // SNAT traffic to local subnets NetfilterMode NetfilterMode // how much to manage netfilter rules } // shutdownConfig is a routing configuration that removes all router // state from the OS. It's the config used when callers pass in a nil // Config. var shutdownConfig = Config{}