mirror of
https://github.com/tailscale/tailscale.git
synced 2024-11-25 19:15:34 +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
|
||||
// itself, like DNS stuff.
|
||||
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
|
||||
DNSDomains []string
|
||||
SubnetRoutes []wgcfg.CIDR // subnets being advertised to other Tailscale nodes
|
||||
@ -55,5 +55,5 @@ func (rs *RouteSettings) OnlyRelevantParts() string {
|
||||
peers = append(peers, p.AllowedIPs)
|
||||
}
|
||||
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
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"log"
|
||||
"os/exec"
|
||||
@ -55,14 +56,19 @@ func (r *freebsdRouter) Up() error {
|
||||
}
|
||||
|
||||
func (r *freebsdRouter) SetRoutes(rs RouteSettings) error {
|
||||
if rs.LocalAddr == (wgcfg.CIDR{}) {
|
||||
if len(rs.LocalAddrs) == 0 {
|
||||
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
|
||||
|
||||
// Update the address.
|
||||
if rs.LocalAddr != r.local {
|
||||
if localAddr != r.local {
|
||||
// If the interface is already set, remove it.
|
||||
if r.local != (wgcfg.CIDR{}) {
|
||||
addrdel := []string{"ifconfig", r.tunname,
|
||||
@ -78,7 +84,7 @@ func (r *freebsdRouter) SetRoutes(rs RouteSettings) error {
|
||||
|
||||
// Add the interface.
|
||||
addradd := []string{"ifconfig", r.tunname,
|
||||
"inet", rs.LocalAddr.String(), rs.LocalAddr.IP.String()}
|
||||
"inet", localAddr.String(), localAddr.IP.String()}
|
||||
out, err := cmd(addradd...).CombinedOutput()
|
||||
if err != nil {
|
||||
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.
|
||||
r.local = rs.LocalAddr
|
||||
r.local = localAddr
|
||||
r.routes = newRoutes
|
||||
|
||||
if err := r.replaceResolvConf(rs.DNS, rs.DNSDomains); err != nil {
|
||||
|
@ -51,7 +51,7 @@
|
||||
type linuxRouter struct {
|
||||
logf func(fmt string, args ...interface{})
|
||||
tunname string
|
||||
local wgcfg.CIDR
|
||||
addrs map[wgcfg.CIDR]bool
|
||||
routes map[wgcfg.CIDR]bool
|
||||
subnetRoutes map[wgcfg.CIDR]bool
|
||||
|
||||
@ -117,8 +117,9 @@ func (r *linuxRouter) down() error {
|
||||
return err
|
||||
}
|
||||
|
||||
r.routes = map[wgcfg.CIDR]bool{}
|
||||
r.local = wgcfg.CIDR{}
|
||||
r.addrs = nil
|
||||
r.routes = nil
|
||||
r.subnetRoutes = nil
|
||||
|
||||
return nil
|
||||
}
|
||||
@ -140,16 +141,26 @@ func (r *linuxRouter) Close() error {
|
||||
func (r *linuxRouter) SetRoutes(rs RouteSettings) error {
|
||||
var errq error
|
||||
|
||||
if rs.LocalAddr != r.local {
|
||||
if r.local != (wgcfg.CIDR{}) {
|
||||
if err := r.delAddress(r.local); err != nil {
|
||||
r.logf("addr del failed: %v", err)
|
||||
if errq == nil {
|
||||
errq = err
|
||||
}
|
||||
newAddrs := make(map[wgcfg.CIDR]bool)
|
||||
for _, addr := range rs.LocalAddrs {
|
||||
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)
|
||||
if errq == nil {
|
||||
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)
|
||||
if errq == nil {
|
||||
errq = err
|
||||
@ -213,7 +224,7 @@ func (r *linuxRouter) SetRoutes(rs RouteSettings) error {
|
||||
}
|
||||
}
|
||||
|
||||
r.local = rs.LocalAddr
|
||||
r.addrs = newAddrs
|
||||
r.routes = newRoutes
|
||||
r.subnetRoutes = newSubnetRoutes
|
||||
|
||||
|
@ -6,6 +6,7 @@
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
@ -60,9 +61,15 @@ func (r *openbsdRouter) Up() 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
|
||||
|
||||
if rs.LocalAddr != r.local {
|
||||
if localAddr != r.local {
|
||||
if r.local != (wgcfg.CIDR{}) {
|
||||
addrdel := []string{"ifconfig", r.tunname,
|
||||
"inet", r.local.String(), "-alias"}
|
||||
@ -86,7 +93,7 @@ func (r *openbsdRouter) SetRoutes(rs RouteSettings) error {
|
||||
}
|
||||
|
||||
addradd := []string{"ifconfig", r.tunname,
|
||||
"inet", rs.LocalAddr.String(), "alias"}
|
||||
"inet", localAddr.String(), "alias"}
|
||||
out, err := cmd(addradd...).CombinedOutput()
|
||||
if err != nil {
|
||||
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",
|
||||
"add", "-inet", rs.LocalAddr.String(),
|
||||
"-iface", rs.LocalAddr.IP.String()}
|
||||
"add", "-inet", localAddr.String(),
|
||||
"-iface", localAddr.IP.String()}
|
||||
if out, err := cmd(routeadd...).CombinedOutput(); err != nil {
|
||||
r.logf("route add failed: %v: %v\n%s", routeadd, err, out)
|
||||
if errq == nil {
|
||||
@ -119,7 +126,7 @@ func (r *openbsdRouter) SetRoutes(rs RouteSettings) error {
|
||||
nstr := fmt.Sprintf("%v/%d", nip, route.Mask)
|
||||
routedel := []string{"route", "-q", "-n",
|
||||
"del", "-inet", nstr,
|
||||
"-iface", rs.LocalAddr.IP.String()}
|
||||
"-iface", localAddr.IP.String()}
|
||||
out, err := cmd(routedel...).CombinedOutput()
|
||||
if err != nil {
|
||||
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)
|
||||
routeadd := []string{"route", "-q", "-n",
|
||||
"add", "-inet", nstr,
|
||||
"-iface", rs.LocalAddr.IP.String()}
|
||||
"-iface", localAddr.IP.String()}
|
||||
out, err := cmd(routeadd...).CombinedOutput()
|
||||
if err != nil {
|
||||
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
|
||||
|
||||
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.
|
||||
// Currently we never use more than one anyway.
|
||||
var cidr wgcfg.CIDR
|
||||
if len(cfg.Addresses) > 0 {
|
||||
cidr = cfg.Addresses[0]
|
||||
// TODO(apenwarr): this shouldn't be hardcoded in the client
|
||||
cidr.Mask = 10 // route the whole cgnat range
|
||||
var addrs []wgcfg.CIDR
|
||||
for _, addr := range cfg.Addresses {
|
||||
addrs = append(addrs, wgcfg.CIDR{
|
||||
IP: addr.IP,
|
||||
// TODO(apenwarr): this shouldn't be hardcoded in the client
|
||||
// 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{
|
||||
LocalAddr: cidr,
|
||||
LocalAddrs: addrs,
|
||||
Cfg: cfg,
|
||||
DNS: cfg.DNS,
|
||||
DNSDomains: dnsDomains,
|
||||
@ -403,7 +408,7 @@ func (e *userspaceEngine) Reconfig(cfg *wgcfg.Config, dnsDomains []string, local
|
||||
rss := rs.OnlyRelevantParts()
|
||||
if rss != e.lastRoutes {
|
||||
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
|
||||
err = e.router.SetRoutes(rs)
|
||||
if err != nil {
|
||||
|
Loading…
Reference in New Issue
Block a user