mirror of
https://github.com/tailscale/tailscale.git
synced 2024-11-29 13:05:46 +00:00
wgengine/router: alter API to support multiple addrs, and use on linux.
FreeBSD and OpenBSD will error out with a complaint if we pass >1 address right now, but we don't yet so that's okay.
This commit is contained in:
parent
6802481bf5
commit
8861bb5a19
@ -41,7 +41,7 @@ func New(logf logger.Logf, wgdev *device.Device, tundev tun.Device) (Router, err
|
|||||||
// IP, etc in wgcfg.Config) plus the things that WireGuard doesn't do
|
// IP, etc in wgcfg.Config) plus the things that WireGuard doesn't do
|
||||||
// itself, like DNS stuff.
|
// itself, like DNS stuff.
|
||||||
type RouteSettings struct {
|
type RouteSettings struct {
|
||||||
LocalAddr wgcfg.CIDR // TODO: why is this here? how does it differ from wgcfg.Config's info?
|
LocalAddrs []wgcfg.CIDR
|
||||||
DNS []wgcfg.IP
|
DNS []wgcfg.IP
|
||||||
DNSDomains []string
|
DNSDomains []string
|
||||||
SubnetRoutes []wgcfg.CIDR // subnets being advertised to other Tailscale nodes
|
SubnetRoutes []wgcfg.CIDR // subnets being advertised to other Tailscale nodes
|
||||||
@ -55,5 +55,5 @@ func (rs *RouteSettings) OnlyRelevantParts() string {
|
|||||||
peers = append(peers, p.AllowedIPs)
|
peers = append(peers, p.AllowedIPs)
|
||||||
}
|
}
|
||||||
return fmt.Sprintf("%v %v %v %v %v",
|
return fmt.Sprintf("%v %v %v %v %v",
|
||||||
rs.LocalAddr, rs.DNS, rs.DNSDomains, rs.SubnetRoutes, peers)
|
rs.LocalAddrs, rs.DNS, rs.DNSDomains, rs.SubnetRoutes, peers)
|
||||||
}
|
}
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
package router
|
package router
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
@ -55,14 +56,19 @@ func (r *freebsdRouter) Up() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (r *freebsdRouter) SetRoutes(rs RouteSettings) error {
|
func (r *freebsdRouter) SetRoutes(rs RouteSettings) error {
|
||||||
if rs.LocalAddr == (wgcfg.CIDR{}) {
|
if len(rs.LocalAddrs) == 0 {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
// TODO: support configuring multiple local addrs on interface.
|
||||||
|
if len(rs.LocalAddrs) != 1 {
|
||||||
|
return errors.New("freebsd doesn't support setting multiple local addrs yet")
|
||||||
|
}
|
||||||
|
localAddr := rs.LocalAddrs[0]
|
||||||
|
|
||||||
var errq error
|
var errq error
|
||||||
|
|
||||||
// Update the address.
|
// Update the address.
|
||||||
if rs.LocalAddr != r.local {
|
if localAddr != r.local {
|
||||||
// If the interface is already set, remove it.
|
// If the interface is already set, remove it.
|
||||||
if r.local != (wgcfg.CIDR{}) {
|
if r.local != (wgcfg.CIDR{}) {
|
||||||
addrdel := []string{"ifconfig", r.tunname,
|
addrdel := []string{"ifconfig", r.tunname,
|
||||||
@ -78,7 +84,7 @@ func (r *freebsdRouter) SetRoutes(rs RouteSettings) error {
|
|||||||
|
|
||||||
// Add the interface.
|
// Add the interface.
|
||||||
addradd := []string{"ifconfig", r.tunname,
|
addradd := []string{"ifconfig", r.tunname,
|
||||||
"inet", rs.LocalAddr.String(), rs.LocalAddr.IP.String()}
|
"inet", localAddr.String(), localAddr.IP.String()}
|
||||||
out, err := cmd(addradd...).CombinedOutput()
|
out, err := cmd(addradd...).CombinedOutput()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
r.logf("addr add failed: %v: %v\n%s", addradd, err, out)
|
r.logf("addr add failed: %v: %v\n%s", addradd, err, out)
|
||||||
@ -132,7 +138,7 @@ func (r *freebsdRouter) SetRoutes(rs RouteSettings) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Store the interface and routes so we know what to change on an update.
|
// Store the interface and routes so we know what to change on an update.
|
||||||
r.local = rs.LocalAddr
|
r.local = localAddr
|
||||||
r.routes = newRoutes
|
r.routes = newRoutes
|
||||||
|
|
||||||
if err := r.replaceResolvConf(rs.DNS, rs.DNSDomains); err != nil {
|
if err := r.replaceResolvConf(rs.DNS, rs.DNSDomains); err != nil {
|
||||||
|
@ -51,7 +51,7 @@
|
|||||||
type linuxRouter struct {
|
type linuxRouter struct {
|
||||||
logf func(fmt string, args ...interface{})
|
logf func(fmt string, args ...interface{})
|
||||||
tunname string
|
tunname string
|
||||||
local wgcfg.CIDR
|
addrs map[wgcfg.CIDR]bool
|
||||||
routes map[wgcfg.CIDR]bool
|
routes map[wgcfg.CIDR]bool
|
||||||
subnetRoutes map[wgcfg.CIDR]bool
|
subnetRoutes map[wgcfg.CIDR]bool
|
||||||
|
|
||||||
@ -117,8 +117,9 @@ func (r *linuxRouter) down() error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
r.routes = map[wgcfg.CIDR]bool{}
|
r.addrs = nil
|
||||||
r.local = wgcfg.CIDR{}
|
r.routes = nil
|
||||||
|
r.subnetRoutes = nil
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@ -140,16 +141,26 @@ func (r *linuxRouter) Close() error {
|
|||||||
func (r *linuxRouter) SetRoutes(rs RouteSettings) error {
|
func (r *linuxRouter) SetRoutes(rs RouteSettings) error {
|
||||||
var errq error
|
var errq error
|
||||||
|
|
||||||
if rs.LocalAddr != r.local {
|
newAddrs := make(map[wgcfg.CIDR]bool)
|
||||||
if r.local != (wgcfg.CIDR{}) {
|
for _, addr := range rs.LocalAddrs {
|
||||||
if err := r.delAddress(r.local); err != nil {
|
newAddrs[addr] = true
|
||||||
|
}
|
||||||
|
for addr := range r.addrs {
|
||||||
|
if newAddrs[addr] {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if err := r.delAddress(addr); err != nil {
|
||||||
r.logf("addr del failed: %v", err)
|
r.logf("addr del failed: %v", err)
|
||||||
if errq == nil {
|
if errq == nil {
|
||||||
errq = err
|
errq = err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if err := r.addAddress(rs.LocalAddr); err != nil {
|
for addr := range newAddrs {
|
||||||
|
if r.addrs[addr] {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if err := r.addAddress(addr); err != nil {
|
||||||
r.logf("addr add failed: %v", err)
|
r.logf("addr add failed: %v", err)
|
||||||
if errq == nil {
|
if errq == nil {
|
||||||
errq = err
|
errq = err
|
||||||
@ -213,7 +224,7 @@ func (r *linuxRouter) SetRoutes(rs RouteSettings) error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
r.local = rs.LocalAddr
|
r.addrs = newAddrs
|
||||||
r.routes = newRoutes
|
r.routes = newRoutes
|
||||||
r.subnetRoutes = newSubnetRoutes
|
r.subnetRoutes = newSubnetRoutes
|
||||||
|
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"log"
|
"log"
|
||||||
@ -60,9 +61,15 @@ func (r *openbsdRouter) Up() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (r *openbsdRouter) SetRoutes(rs RouteSettings) error {
|
func (r *openbsdRouter) SetRoutes(rs RouteSettings) error {
|
||||||
|
// TODO: support configuring multiple local addrs on interface.
|
||||||
|
if len(rs.LocalAddrs) != 1 {
|
||||||
|
return errors.New("freebsd doesn't support setting multiple local addrs yet")
|
||||||
|
}
|
||||||
|
localAddr := rs.LocalAddrs[0]
|
||||||
|
|
||||||
var errq error
|
var errq error
|
||||||
|
|
||||||
if rs.LocalAddr != r.local {
|
if localAddr != r.local {
|
||||||
if r.local != (wgcfg.CIDR{}) {
|
if r.local != (wgcfg.CIDR{}) {
|
||||||
addrdel := []string{"ifconfig", r.tunname,
|
addrdel := []string{"ifconfig", r.tunname,
|
||||||
"inet", r.local.String(), "-alias"}
|
"inet", r.local.String(), "-alias"}
|
||||||
@ -86,7 +93,7 @@ func (r *openbsdRouter) SetRoutes(rs RouteSettings) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
addradd := []string{"ifconfig", r.tunname,
|
addradd := []string{"ifconfig", r.tunname,
|
||||||
"inet", rs.LocalAddr.String(), "alias"}
|
"inet", localAddr.String(), "alias"}
|
||||||
out, err := cmd(addradd...).CombinedOutput()
|
out, err := cmd(addradd...).CombinedOutput()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
r.logf("addr add failed: %v: %v\n%s", addradd, err, out)
|
r.logf("addr add failed: %v: %v\n%s", addradd, err, out)
|
||||||
@ -96,8 +103,8 @@ func (r *openbsdRouter) SetRoutes(rs RouteSettings) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
routeadd := []string{"route", "-q", "-n",
|
routeadd := []string{"route", "-q", "-n",
|
||||||
"add", "-inet", rs.LocalAddr.String(),
|
"add", "-inet", localAddr.String(),
|
||||||
"-iface", rs.LocalAddr.IP.String()}
|
"-iface", localAddr.IP.String()}
|
||||||
if out, err := cmd(routeadd...).CombinedOutput(); err != nil {
|
if out, err := cmd(routeadd...).CombinedOutput(); err != nil {
|
||||||
r.logf("route add failed: %v: %v\n%s", routeadd, err, out)
|
r.logf("route add failed: %v: %v\n%s", routeadd, err, out)
|
||||||
if errq == nil {
|
if errq == nil {
|
||||||
@ -119,7 +126,7 @@ func (r *openbsdRouter) SetRoutes(rs RouteSettings) error {
|
|||||||
nstr := fmt.Sprintf("%v/%d", nip, route.Mask)
|
nstr := fmt.Sprintf("%v/%d", nip, route.Mask)
|
||||||
routedel := []string{"route", "-q", "-n",
|
routedel := []string{"route", "-q", "-n",
|
||||||
"del", "-inet", nstr,
|
"del", "-inet", nstr,
|
||||||
"-iface", rs.LocalAddr.IP.String()}
|
"-iface", localAddr.IP.String()}
|
||||||
out, err := cmd(routedel...).CombinedOutput()
|
out, err := cmd(routedel...).CombinedOutput()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
r.logf("route del failed: %v: %v\n%s", routedel, err, out)
|
r.logf("route del failed: %v: %v\n%s", routedel, err, out)
|
||||||
@ -136,7 +143,7 @@ func (r *openbsdRouter) SetRoutes(rs RouteSettings) error {
|
|||||||
nstr := fmt.Sprintf("%v/%d", nip, route.Mask)
|
nstr := fmt.Sprintf("%v/%d", nip, route.Mask)
|
||||||
routeadd := []string{"route", "-q", "-n",
|
routeadd := []string{"route", "-q", "-n",
|
||||||
"add", "-inet", nstr,
|
"add", "-inet", nstr,
|
||||||
"-iface", rs.LocalAddr.IP.String()}
|
"-iface", localAddr.IP.String()}
|
||||||
out, err := cmd(routeadd...).CombinedOutput()
|
out, err := cmd(routeadd...).CombinedOutput()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
r.logf("addr add failed: %v: %v\n%s", routeadd, err, out)
|
r.logf("addr add failed: %v: %v\n%s", routeadd, err, out)
|
||||||
@ -147,7 +154,7 @@ func (r *openbsdRouter) SetRoutes(rs RouteSettings) error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
r.local = rs.LocalAddr
|
r.local = localAddr
|
||||||
r.routes = newRoutes
|
r.routes = newRoutes
|
||||||
|
|
||||||
if err := r.replaceResolvConf(rs.DNS, rs.DNSDomains); err != nil {
|
if err := r.replaceResolvConf(rs.DNS, rs.DNSDomains); err != nil {
|
||||||
|
@ -378,15 +378,20 @@ func (e *userspaceEngine) Reconfig(cfg *wgcfg.Config, dnsDomains []string, local
|
|||||||
|
|
||||||
// TODO(apenwarr): only handling the first local address.
|
// TODO(apenwarr): only handling the first local address.
|
||||||
// Currently we never use more than one anyway.
|
// Currently we never use more than one anyway.
|
||||||
var cidr wgcfg.CIDR
|
var addrs []wgcfg.CIDR
|
||||||
if len(cfg.Addresses) > 0 {
|
for _, addr := range cfg.Addresses {
|
||||||
cidr = cfg.Addresses[0]
|
addrs = append(addrs, wgcfg.CIDR{
|
||||||
|
IP: addr.IP,
|
||||||
// TODO(apenwarr): this shouldn't be hardcoded in the client
|
// TODO(apenwarr): this shouldn't be hardcoded in the client
|
||||||
cidr.Mask = 10 // route the whole cgnat range
|
// TODO(danderson): fairly sure we can make this a /32 or
|
||||||
|
// /128 based on address family. Need to check behavior on
|
||||||
|
// !linux OSes.
|
||||||
|
Mask: 10,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
rs := router.RouteSettings{
|
rs := router.RouteSettings{
|
||||||
LocalAddr: cidr,
|
LocalAddrs: addrs,
|
||||||
Cfg: cfg,
|
Cfg: cfg,
|
||||||
DNS: cfg.DNS,
|
DNS: cfg.DNS,
|
||||||
DNSDomains: dnsDomains,
|
DNSDomains: dnsDomains,
|
||||||
@ -403,7 +408,7 @@ func (e *userspaceEngine) Reconfig(cfg *wgcfg.Config, dnsDomains []string, local
|
|||||||
rss := rs.OnlyRelevantParts()
|
rss := rs.OnlyRelevantParts()
|
||||||
if rss != e.lastRoutes {
|
if rss != e.lastRoutes {
|
||||||
e.logf("wgengine: Reconfig: reconfiguring router. la=%v dns=%v dom=%v; new routes: %v",
|
e.logf("wgengine: Reconfig: reconfiguring router. la=%v dns=%v dom=%v; new routes: %v",
|
||||||
rs.LocalAddr, rs.DNS, rs.DNSDomains, rss)
|
rs.LocalAddrs, rs.DNS, rs.DNSDomains, rss)
|
||||||
e.lastRoutes = rss
|
e.lastRoutes = rss
|
||||||
err = e.router.SetRoutes(rs)
|
err = e.router.SetRoutes(rs)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
Loading…
Reference in New Issue
Block a user