From b01db109f53054c9ea6e9dfa0e8823853c68fff8 Mon Sep 17 00:00:00 2001 From: David Anderson Date: Fri, 8 May 2020 05:17:30 +0000 Subject: [PATCH] wgengine/router: use inet.af/netaddr, not wgcfg.CIDR. Signed-off-by: David Anderson --- go.mod | 2 +- go.sum | 2 ++ wgengine/router/ifconfig_windows.go | 6 +++--- wgengine/router/router.go | 10 +++++----- wgengine/router/router_freebsd.go | 18 ++++++++--------- wgengine/router/router_linux.go | 30 ++++++++++++++-------------- wgengine/router/router_openbsd.go | 16 +++++++-------- wgengine/userspace.go | 31 +++++++++++++++++++++++++---- 8 files changed, 70 insertions(+), 45 deletions(-) diff --git a/go.mod b/go.mod index 0f6b9379b..3a4cc3339 100644 --- a/go.mod +++ b/go.mod @@ -28,6 +28,6 @@ require ( golang.org/x/sys v0.0.0-20200501052902-10377860bb8e golang.org/x/time v0.0.0-20191024005414-555d28b269f0 gortc.io/stun v1.22.1 - inet.af/netaddr v0.0.0-20200417213433-f9e5bcc2d6ea + inet.af/netaddr v0.0.0-20200430175045-5aaf2097c7fc rsc.io/goversion v1.2.0 ) diff --git a/go.sum b/go.sum index 2d36f172b..cfac605b3 100644 --- a/go.sum +++ b/go.sum @@ -146,5 +146,7 @@ gortc.io/stun v1.22.1 h1:96mOdDATYRqhYB+TZdenWBg4CzL2Ye5kPyBXQ8KAB+8= gortc.io/stun v1.22.1/go.mod h1:XD5lpONVyjvV3BgOyJFNo0iv6R2oZB4L+weMqxts+zg= inet.af/netaddr v0.0.0-20200417213433-f9e5bcc2d6ea h1:DpXewrGVf9+vvYQFrNGj9v34bXMuTVQv+2wuULTNV8I= inet.af/netaddr v0.0.0-20200417213433-f9e5bcc2d6ea/go.mod h1:qqYzz/2whtrbWJvt+DNWQyvekNN4ePQZcg2xc2/Yjww= +inet.af/netaddr v0.0.0-20200430175045-5aaf2097c7fc h1:We3b/z+7i9LV4Ls0yWve5vYIlnAPSPeqxKVgZseRDBs= +inet.af/netaddr v0.0.0-20200430175045-5aaf2097c7fc/go.mod h1:qqYzz/2whtrbWJvt+DNWQyvekNN4ePQZcg2xc2/Yjww= rsc.io/goversion v1.2.0 h1:SPn+NLTiAG7w30IRK/DKp1BjvpWabYgxlLp/+kx5J8w= rsc.io/goversion v1.2.0/go.mod h1:Eih9y/uIBS3ulggl7KNJ09xGSLcuNaLgmvvqa07sgfo= diff --git a/wgengine/router/ifconfig_windows.go b/wgengine/router/ifconfig_windows.go index 94f1baf67..6ff21c6b0 100644 --- a/wgengine/router/ifconfig_windows.go +++ b/wgengine/router/ifconfig_windows.go @@ -310,12 +310,12 @@ func configureInterface(rs Settings, tun *tun.NativeTun) error { continue } if route.IP.Is4() { - if route.Mask == 0 { + if route.Bits == 0 { foundDefault4 = true } r.NextHop = *firstGateway4 } else if route.IP.Is6() { - if route.Mask == 0 { + if route.Bits == 0 { foundDefault6 = true } r.NextHop = *firstGateway6 @@ -360,7 +360,7 @@ func configureInterface(rs Settings, tun *tun.NativeTun) error { var dnsIPs []net.IP for _, ip := range rs.DNS { - dnsIPs = append(dnsIPs, ip.IP()) + dnsIPs = append(dnsIPs, ip.IPAddr().IP) } err = iface.SetDNS(dnsIPs) if err != nil && errAcc == nil { diff --git a/wgengine/router/router.go b/wgengine/router/router.go index 93275ba88..e10d196df 100644 --- a/wgengine/router/router.go +++ b/wgengine/router/router.go @@ -9,7 +9,7 @@ package router import ( "github.com/tailscale/wireguard-go/device" "github.com/tailscale/wireguard-go/tun" - "github.com/tailscale/wireguard-go/wgcfg" + "inet.af/netaddr" "tailscale.com/types/logger" ) @@ -38,9 +38,9 @@ func New(logf logger.Logf, wgdev *device.Device, tundev tun.Device) (Router, err // Settings is the subset of Tailscale configuration that is relevant // to the OS's network stack. type Settings struct { - LocalAddrs []wgcfg.CIDR - DNS []wgcfg.IP + LocalAddrs []netaddr.IPPrefix + DNS []netaddr.IP DNSDomains []string - Routes []wgcfg.CIDR // routes to point into the Tailscale interface - SubnetRoutes []wgcfg.CIDR // subnets being advertised to other Tailscale nodes + Routes []netaddr.IPPrefix // routes to point into the Tailscale interface + SubnetRoutes []netaddr.IPPrefix // subnets being advertised to other Tailscale nodes } diff --git a/wgengine/router/router_freebsd.go b/wgengine/router/router_freebsd.go index 86011df93..e16c9f082 100644 --- a/wgengine/router/router_freebsd.go +++ b/wgengine/router/router_freebsd.go @@ -12,7 +12,7 @@ import ( "github.com/tailscale/wireguard-go/device" "github.com/tailscale/wireguard-go/tun" - "github.com/tailscale/wireguard-go/wgcfg" + "inet.af/netaddr" "tailscale.com/types/logger" ) @@ -24,8 +24,8 @@ import ( type freebsdRouter struct { logf logger.Logf tunname string - local wgcfg.CIDR - routes map[wgcfg.CIDR]struct{} + local netaddr.IPPrefix + routes map[netaddr.IPPrefix]struct{} } func newUserspaceRouter(logf logger.Logf, _ *device.Device, tundev tun.Device) (Router, error) { @@ -70,7 +70,7 @@ func (r *freebsdRouter) Set(rs Settings) error { // Update the address. if localAddr != r.local { // If the interface is already set, remove it. - if r.local != (wgcfg.CIDR{}) { + if r.local != (netaddr.IPPrefix{}) { addrdel := []string{"ifconfig", r.tunname, "inet", r.local.String(), "-alias"} out, err := cmd(addrdel...).CombinedOutput() @@ -94,7 +94,7 @@ func (r *freebsdRouter) Set(rs Settings) error { } } - newRoutes := make(map[wgcfg.CIDR]struct{}) + newRoutes := make(map[netaddr.IPPrefix]struct{}) for _, route := range rs.Routes { newRoutes[route] = struct{}{} } @@ -103,7 +103,7 @@ func (r *freebsdRouter) Set(rs Settings) error { if _, keep := newRoutes[route]; !keep { net := route.IPNet() nip := net.IP.Mask(net.Mask) - nstr := fmt.Sprintf("%v/%d", nip, route.Mask) + nstr := fmt.Sprintf("%v/%d", nip, route.Bits) routedel := []string{"route", "-q", "-n", "del", "-inet", nstr, "-iface", r.tunname} @@ -121,7 +121,7 @@ func (r *freebsdRouter) Set(rs Settings) error { if _, exists := r.routes[route]; !exists { net := route.IPNet() nip := net.IP.Mask(net.Mask) - nstr := fmt.Sprintf("%v/%d", nip, route.Mask) + nstr := fmt.Sprintf("%v/%d", nip, route.Bits) routeadd := []string{"route", "-q", "-n", "add", "-inet", nstr, "-iface", r.tunname} @@ -152,5 +152,5 @@ func (r *freebsdRouter) Close() error { // TODO(mbaillie): these are no-ops for now. They could re-use the Linux funcs // (sans systemd parts), but I note Linux DNS is disabled(?) so leaving for now. -func (r *freebsdRouter) replaceResolvConf(_ []wgcfg.IP, _ []string) error { return nil } -func (r *freebsdRouter) restoreResolvConf() error { return nil } +func (r *freebsdRouter) replaceResolvConf(_ []netaddr.IP, _ []string) error { return nil } +func (r *freebsdRouter) restoreResolvConf() error { return nil } diff --git a/wgengine/router/router_linux.go b/wgengine/router/router_linux.go index 389264203..fb84c42f5 100644 --- a/wgengine/router/router_linux.go +++ b/wgengine/router/router_linux.go @@ -17,7 +17,7 @@ import ( "github.com/coreos/go-iptables/iptables" "github.com/tailscale/wireguard-go/device" "github.com/tailscale/wireguard-go/tun" - "github.com/tailscale/wireguard-go/wgcfg" + "inet.af/netaddr" "tailscale.com/atomicfile" "tailscale.com/types/logger" ) @@ -51,9 +51,9 @@ const ( type linuxRouter struct { logf func(fmt string, args ...interface{}) tunname string - addrs map[wgcfg.CIDR]bool - routes map[wgcfg.CIDR]bool - subnetRoutes map[wgcfg.CIDR]bool + addrs map[netaddr.IPPrefix]bool + routes map[netaddr.IPPrefix]bool + subnetRoutes map[netaddr.IPPrefix]bool ipt4 *iptables.IPTables } @@ -143,9 +143,9 @@ func (r *linuxRouter) Set(rs Settings) error { // cidrDiff calls add and del as needed to make the set of prefixes in // old and new match. Returns a map version of new, and the first // error encountered while reconfiguring, if any. - cidrDiff := func(kind string, old map[wgcfg.CIDR]bool, new []wgcfg.CIDR, add, del func(wgcfg.CIDR) error) (map[wgcfg.CIDR]bool, error) { + cidrDiff := func(kind string, old map[netaddr.IPPrefix]bool, new []netaddr.IPPrefix, add, del func(netaddr.IPPrefix) error) (map[netaddr.IPPrefix]bool, error) { var ( - ret = make(map[wgcfg.CIDR]bool, len(new)) + ret = make(map[netaddr.IPPrefix]bool, len(new)) errq error ) @@ -212,7 +212,7 @@ const ( resolvConf = "/etc/resolv.conf" ) -func (r *linuxRouter) replaceResolvConf(servers []wgcfg.IP, domains []string) error { +func (r *linuxRouter) replaceResolvConf(servers []netaddr.IP, domains []string) error { if len(servers) == 0 { return r.restoreResolvConf() } @@ -305,43 +305,43 @@ func (r *linuxRouter) restoreResolvConf() error { // addAddress adds an IP/mask to the tunnel interface. Fails if the // address is already assigned to the interface, or if the addition // fails. -func (r *linuxRouter) addAddress(addr wgcfg.CIDR) error { +func (r *linuxRouter) addAddress(addr netaddr.IPPrefix) error { return cmd("ip", "addr", "add", addr.String(), "dev", r.tunname) } // delAddress removes an IP/mask from the tunnel interface. Fails if // the address is not assigned to the interface, or if the removal // fails. -func (r *linuxRouter) delAddress(addr wgcfg.CIDR) error { +func (r *linuxRouter) delAddress(addr netaddr.IPPrefix) error { return cmd("ip", "addr", "del", addr.String(), "dev", r.tunname) } // normalizeCIDR returns cidr as an ip/mask string, with the host bits // of the IP address zeroed out. -func normalizeCIDR(cidr wgcfg.CIDR) string { +func normalizeCIDR(cidr netaddr.IPPrefix) string { ncidr := cidr.IPNet() nip := ncidr.IP.Mask(ncidr.Mask) - return fmt.Sprintf("%s/%d", nip, cidr.Mask) + return fmt.Sprintf("%s/%d", nip, cidr.Bits) } // addRoute adds a route for cidr, pointing to the tunnel // interface. Fails if the route already exists, or if adding the // route fails. -func (r *linuxRouter) addRoute(cidr wgcfg.CIDR) error { +func (r *linuxRouter) addRoute(cidr netaddr.IPPrefix) error { return cmd("ip", "route", "add", normalizeCIDR(cidr), "dev", r.tunname, "scope", "global") } // delRoute removes the route for cidr pointing to the tunnel // interface. Fails if the route doesn't exist, or if removing the // route fails. -func (r *linuxRouter) delRoute(cidr wgcfg.CIDR) error { +func (r *linuxRouter) delRoute(cidr netaddr.IPPrefix) error { return cmd("ip", "route", "del", normalizeCIDR(cidr), "dev", r.tunname, "scope", "global") } // addSubnetRule adds a netfilter rule that allows traffic to flow // from Tailscale to cidr. Fails if the rule already exists, or if // adding the route fails. -func (r *linuxRouter) addSubnetRule(cidr wgcfg.CIDR) error { +func (r *linuxRouter) addSubnetRule(cidr netaddr.IPPrefix) error { if err := r.ipt4.Insert("filter", "ts-forward", 1, "-i", r.tunname, "-d", normalizeCIDR(cidr), "-j", "MARK", "--set-mark", tailscaleSubnetRouteMark); err != nil { return err } @@ -354,7 +354,7 @@ func (r *linuxRouter) addSubnetRule(cidr wgcfg.CIDR) error { // delSubnetRule deletes the netfilter subnet forwarding rule for // cidr. Fails if the rule doesn't exist, or if removing the rule // fails. -func (r *linuxRouter) delSubnetRule(cidr wgcfg.CIDR) error { +func (r *linuxRouter) delSubnetRule(cidr netaddr.IPPrefix) error { if err := r.ipt4.Delete("filter", "ts-forward", "-i", r.tunname, "-d", normalizeCIDR(cidr), "-j", "MARK", "--set-mark", tailscaleSubnetRouteMark); err != nil { return err } diff --git a/wgengine/router/router_openbsd.go b/wgengine/router/router_openbsd.go index 53fdc7731..41e414b8d 100644 --- a/wgengine/router/router_openbsd.go +++ b/wgengine/router/router_openbsd.go @@ -17,7 +17,7 @@ import ( "github.com/tailscale/wireguard-go/device" "github.com/tailscale/wireguard-go/tun" - "github.com/tailscale/wireguard-go/wgcfg" + "inet.af/netaddr" "tailscale.com/atomicfile" "tailscale.com/types/logger" ) @@ -29,8 +29,8 @@ import ( type openbsdRouter struct { logf logger.Logf tunname string - local wgcfg.CIDR - routes map[wgcfg.CIDR]struct{} + local netaddr.IPPrefix + routes map[netaddr.IPPrefix]struct{} } func newUserspaceRouter(logf logger.Logf, _ *device.Device, tundev tun.Device) (Router, error) { @@ -70,7 +70,7 @@ func (r *openbsdRouter) Set(rs Settings) error { var errq error if localAddr != r.local { - if r.local != (wgcfg.CIDR{}) { + if r.local != (netaddr.IPPrefix{}) { addrdel := []string{"ifconfig", r.tunname, "inet", r.local.String(), "-alias"} out, err := cmd(addrdel...).CombinedOutput() @@ -113,7 +113,7 @@ func (r *openbsdRouter) Set(rs Settings) error { } } - newRoutes := make(map[wgcfg.CIDR]struct{}) + newRoutes := make(map[netaddr.IPPrefix]struct{}) for _, route := range rs.Routes { newRoutes[route] = struct{}{} } @@ -121,7 +121,7 @@ func (r *openbsdRouter) Set(rs Settings) error { if _, keep := newRoutes[route]; !keep { net := route.IPNet() nip := net.IP.Mask(net.Mask) - nstr := fmt.Sprintf("%v/%d", nip, route.Mask) + nstr := fmt.Sprintf("%v/%d", nip, route.Bits) routedel := []string{"route", "-q", "-n", "del", "-inet", nstr, "-iface", localAddr.IP.String()} @@ -138,7 +138,7 @@ func (r *openbsdRouter) Set(rs Settings) error { if _, exists := r.routes[route]; !exists { net := route.IPNet() nip := net.IP.Mask(net.Mask) - nstr := fmt.Sprintf("%v/%d", nip, route.Mask) + nstr := fmt.Sprintf("%v/%d", nip, route.Bits) routeadd := []string{"route", "-q", "-n", "add", "-inet", nstr, "-iface", localAddr.IP.String()} @@ -181,7 +181,7 @@ const ( resolvConf = "/etc/resolv.conf" ) -func (r *openbsdRouter) replaceResolvConf(servers []wgcfg.IP, domains []string) error { +func (r *openbsdRouter) replaceResolvConf(servers []netaddr.IP, domains []string) error { if len(servers) == 0 { return r.restoreResolvConf() } diff --git a/wgengine/userspace.go b/wgengine/userspace.go index 79dc4d518..db5004268 100644 --- a/wgengine/userspace.go +++ b/wgengine/userspace.go @@ -23,6 +23,7 @@ import ( "github.com/tailscale/wireguard-go/tun" "github.com/tailscale/wireguard-go/wgcfg" "go4.org/mem" + "inet.af/netaddr" "tailscale.com/ipn/ipnstate" "tailscale.com/net/interfaces" "tailscale.com/tailcfg" @@ -397,13 +398,13 @@ func (e *userspaceEngine) Reconfig(cfg *wgcfg.Config, dnsDomains []string, local } rs := router.Settings{ - LocalAddrs: addrs, - DNS: cfg.DNS, + LocalAddrs: wgCIDRToNetaddr(addrs), + DNS: wgIPToNetaddr(cfg.DNS), DNSDomains: dnsDomains, - SubnetRoutes: localRoutes, + SubnetRoutes: wgCIDRToNetaddr(localRoutes), } for _, peer := range cfg.Peers { - rs.Routes = append(rs.Routes, peer.AllowedIPs...) + rs.Routes = append(rs.Routes, wgCIDRToNetaddr(peer.AllowedIPs)...) } if err := e.router.Set(rs); err != nil { @@ -414,6 +415,28 @@ func (e *userspaceEngine) Reconfig(cfg *wgcfg.Config, dnsDomains []string, local return nil } +func wgIPToNetaddr(ips []wgcfg.IP) (ret []netaddr.IP) { + for _, ip := range ips { + nip, ok := netaddr.FromStdIP(ip.IP()) + if !ok { + panic(fmt.Sprintf("conversion of %s from wgcfg to netaddr IP failed", ip)) + } + ret = append(ret, nip) + } + return ret +} + +func wgCIDRToNetaddr(cidrs []wgcfg.CIDR) (ret []netaddr.IPPrefix) { + for _, cidr := range cidrs { + ncidr, ok := netaddr.FromStdIPNet(cidr.IPNet()) + if !ok { + panic(fmt.Sprintf("conversion of %s from wgcfg to netaddr IPNet failed", cidr)) + } + ret = append(ret, ncidr) + } + return ret +} + func (e *userspaceEngine) GetFilter() *filter.Filter { e.mu.Lock() defer e.mu.Unlock()