mirror of
https://github.com/tailscale/tailscale.git
synced 2025-10-26 22:01:09 +01:00
wgengine/{magicsock,userspace,router}: move portupdates to the eventbus (#17423)
Also pull out interface method only needed in Linux. Instead of having userspace do the call into the router, just let the router pick up the change itself. Updates #15160 Signed-off-by: Claus Lensbøl <claus@tailscale.com>
This commit is contained in:
parent
eabc62a9dd
commit
63f7a400a8
@ -67,6 +67,7 @@ import (
|
|||||||
"tailscale.com/util/testenv"
|
"tailscale.com/util/testenv"
|
||||||
"tailscale.com/util/usermetric"
|
"tailscale.com/util/usermetric"
|
||||||
"tailscale.com/wgengine/filter"
|
"tailscale.com/wgengine/filter"
|
||||||
|
"tailscale.com/wgengine/router"
|
||||||
"tailscale.com/wgengine/wgint"
|
"tailscale.com/wgengine/wgint"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -179,6 +180,7 @@ type Conn struct {
|
|||||||
// config changes between magicsock and wireguard.
|
// config changes between magicsock and wireguard.
|
||||||
syncPub *eventbus.Publisher[syncPoint]
|
syncPub *eventbus.Publisher[syncPoint]
|
||||||
allocRelayEndpointPub *eventbus.Publisher[UDPRelayAllocReq]
|
allocRelayEndpointPub *eventbus.Publisher[UDPRelayAllocReq]
|
||||||
|
portUpdatePub *eventbus.Publisher[router.PortUpdate]
|
||||||
|
|
||||||
// pconn4 and pconn6 are the underlying UDP sockets used to
|
// pconn4 and pconn6 are the underlying UDP sockets used to
|
||||||
// send/receive packets for wireguard and other magicsock
|
// send/receive packets for wireguard and other magicsock
|
||||||
@ -393,10 +395,6 @@ type Conn struct {
|
|||||||
// wgPinger is the WireGuard only pinger used for latency measurements.
|
// wgPinger is the WireGuard only pinger used for latency measurements.
|
||||||
wgPinger lazy.SyncValue[*ping.Pinger]
|
wgPinger lazy.SyncValue[*ping.Pinger]
|
||||||
|
|
||||||
// onPortUpdate is called with the new port when magicsock rebinds to
|
|
||||||
// a new port.
|
|
||||||
onPortUpdate func(port uint16, network string)
|
|
||||||
|
|
||||||
// getPeerByKey optionally specifies a function to look up a peer's
|
// getPeerByKey optionally specifies a function to look up a peer's
|
||||||
// wireguard state by its public key. If nil, it's not used.
|
// wireguard state by its public key. If nil, it's not used.
|
||||||
getPeerByKey func(key.NodePublic) (_ wgint.Peer, ok bool)
|
getPeerByKey func(key.NodePublic) (_ wgint.Peer, ok bool)
|
||||||
@ -492,10 +490,6 @@ type Options struct {
|
|||||||
// If nil, they're ignored and not updated.
|
// If nil, they're ignored and not updated.
|
||||||
ControlKnobs *controlknobs.Knobs
|
ControlKnobs *controlknobs.Knobs
|
||||||
|
|
||||||
// OnPortUpdate is called with the new port when magicsock rebinds to
|
|
||||||
// a new port.
|
|
||||||
OnPortUpdate func(port uint16, network string)
|
|
||||||
|
|
||||||
// PeerByKeyFunc optionally specifies a function to look up a peer's
|
// PeerByKeyFunc optionally specifies a function to look up a peer's
|
||||||
// WireGuard state by its public key. If nil, it's not used.
|
// WireGuard state by its public key. If nil, it's not used.
|
||||||
// In regular use, this will be wgengine.(*userspaceEngine).PeerByKey.
|
// In regular use, this will be wgengine.(*userspaceEngine).PeerByKey.
|
||||||
@ -735,6 +729,7 @@ func NewConn(opts Options) (*Conn, error) {
|
|||||||
cli := c.eventBus.Client("magicsock.Conn")
|
cli := c.eventBus.Client("magicsock.Conn")
|
||||||
c.syncPub = eventbus.Publish[syncPoint](cli)
|
c.syncPub = eventbus.Publish[syncPoint](cli)
|
||||||
c.allocRelayEndpointPub = eventbus.Publish[UDPRelayAllocReq](cli)
|
c.allocRelayEndpointPub = eventbus.Publish[UDPRelayAllocReq](cli)
|
||||||
|
c.portUpdatePub = eventbus.Publish[router.PortUpdate](cli)
|
||||||
c.eventSubs = cli.Monitor(c.consumeEventbusTopics(cli))
|
c.eventSubs = cli.Monitor(c.consumeEventbusTopics(cli))
|
||||||
|
|
||||||
c.connCtx, c.connCtxCancel = context.WithCancel(context.Background())
|
c.connCtx, c.connCtxCancel = context.WithCancel(context.Background())
|
||||||
@ -759,7 +754,6 @@ func NewConn(opts Options) (*Conn, error) {
|
|||||||
|
|
||||||
c.netMon = opts.NetMon
|
c.netMon = opts.NetMon
|
||||||
c.health = opts.HealthTracker
|
c.health = opts.HealthTracker
|
||||||
c.onPortUpdate = opts.OnPortUpdate
|
|
||||||
c.getPeerByKey = opts.PeerByKeyFunc
|
c.getPeerByKey = opts.PeerByKeyFunc
|
||||||
|
|
||||||
if err := c.rebind(keepCurrentPort); err != nil {
|
if err := c.rebind(keepCurrentPort); err != nil {
|
||||||
@ -3533,7 +3527,7 @@ func (c *Conn) bindSocket(ruc *RebindingUDPConn, network string, curPortFate cur
|
|||||||
c.logf("magicsock: unable to bind %v port %d: %v", network, port, err)
|
c.logf("magicsock: unable to bind %v port %d: %v", network, port, err)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if c.onPortUpdate != nil {
|
if c.portUpdatePub.ShouldPublish() {
|
||||||
_, gotPortStr, err := net.SplitHostPort(pconn.LocalAddr().String())
|
_, gotPortStr, err := net.SplitHostPort(pconn.LocalAddr().String())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.logf("could not parse port from %s: %w", pconn.LocalAddr().String(), err)
|
c.logf("could not parse port from %s: %w", pconn.LocalAddr().String(), err)
|
||||||
@ -3542,7 +3536,10 @@ func (c *Conn) bindSocket(ruc *RebindingUDPConn, network string, curPortFate cur
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
c.logf("could not parse port from %s: %w", gotPort, err)
|
c.logf("could not parse port from %s: %w", gotPort, err)
|
||||||
} else {
|
} else {
|
||||||
c.onPortUpdate(uint16(gotPort), network)
|
c.portUpdatePub.Publish(router.PortUpdate{
|
||||||
|
UDPPort: uint16(gotPort),
|
||||||
|
EndpointNetwork: network,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -56,13 +56,6 @@ func (r *CallbackRouter) Set(rcfg *Config) error {
|
|||||||
return r.SetBoth(r.rcfg, r.dcfg)
|
return r.SetBoth(r.rcfg, r.dcfg)
|
||||||
}
|
}
|
||||||
|
|
||||||
// UpdateMagicsockPort implements the Router interface. This implementation
|
|
||||||
// does nothing and returns nil because this router does not currently need
|
|
||||||
// to know what the magicsock UDP port is.
|
|
||||||
func (r *CallbackRouter) UpdateMagicsockPort(_ uint16, _ string) error {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetDNS implements dns.OSConfigurator.
|
// SetDNS implements dns.OSConfigurator.
|
||||||
func (r *CallbackRouter) SetDNS(dcfg dns.OSConfig) error {
|
func (r *CallbackRouter) SetDNS(dcfg dns.OSConfig) error {
|
||||||
r.mu.Lock()
|
r.mu.Lock()
|
||||||
|
|||||||
@ -14,6 +14,7 @@ import (
|
|||||||
"os/exec"
|
"os/exec"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
"sync"
|
||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
"syscall"
|
"syscall"
|
||||||
"time"
|
"time"
|
||||||
@ -54,21 +55,14 @@ const (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type linuxRouter struct {
|
type linuxRouter struct {
|
||||||
closed atomic.Bool
|
closed atomic.Bool
|
||||||
logf func(fmt string, args ...any)
|
logf func(fmt string, args ...any)
|
||||||
tunname string
|
tunname string
|
||||||
netMon *netmon.Monitor
|
netMon *netmon.Monitor
|
||||||
health *health.Tracker
|
health *health.Tracker
|
||||||
eventSubs eventbus.Monitor
|
eventSubs eventbus.Monitor
|
||||||
rulesAddedPub *eventbus.Publisher[AddIPRules]
|
rulesAddedPub *eventbus.Publisher[AddIPRules]
|
||||||
unregNetMon func()
|
unregNetMon func()
|
||||||
addrs map[netip.Prefix]bool
|
|
||||||
routes map[netip.Prefix]bool
|
|
||||||
localRoutes map[netip.Prefix]bool
|
|
||||||
snatSubnetRoutes bool
|
|
||||||
statefulFiltering bool
|
|
||||||
netfilterMode preftype.NetfilterMode
|
|
||||||
netfilterKind string
|
|
||||||
|
|
||||||
// ruleRestorePending is whether a timer has been started to
|
// ruleRestorePending is whether a timer has been started to
|
||||||
// restore deleted ip rules.
|
// restore deleted ip rules.
|
||||||
@ -86,8 +80,16 @@ type linuxRouter struct {
|
|||||||
cmd commandRunner
|
cmd commandRunner
|
||||||
nfr linuxfw.NetfilterRunner
|
nfr linuxfw.NetfilterRunner
|
||||||
|
|
||||||
magicsockPortV4 atomic.Uint32 // actually a uint16
|
mu sync.Mutex
|
||||||
magicsockPortV6 atomic.Uint32 // actually a uint16
|
addrs map[netip.Prefix]bool
|
||||||
|
routes map[netip.Prefix]bool
|
||||||
|
localRoutes map[netip.Prefix]bool
|
||||||
|
snatSubnetRoutes bool
|
||||||
|
statefulFiltering bool
|
||||||
|
netfilterMode preftype.NetfilterMode
|
||||||
|
netfilterKind string
|
||||||
|
magicsockPortV4 uint16
|
||||||
|
magicsockPortV6 uint16
|
||||||
}
|
}
|
||||||
|
|
||||||
func newUserspaceRouter(logf logger.Logf, tunDev tun.Device, netMon *netmon.Monitor, health *health.Tracker, bus *eventbus.Bus) (router.Router, error) {
|
func newUserspaceRouter(logf logger.Logf, tunDev tun.Device, netMon *netmon.Monitor, health *health.Tracker, bus *eventbus.Bus) (router.Router, error) {
|
||||||
@ -169,6 +171,7 @@ func newUserspaceRouterAdvanced(logf logger.Logf, tunname string, netMon *netmon
|
|||||||
// [eventbus.Client] is closed.
|
// [eventbus.Client] is closed.
|
||||||
func (r *linuxRouter) consumeEventbusTopics(ec *eventbus.Client) func(*eventbus.Client) {
|
func (r *linuxRouter) consumeEventbusTopics(ec *eventbus.Client) func(*eventbus.Client) {
|
||||||
ruleDeletedSub := eventbus.Subscribe[netmon.RuleDeleted](ec)
|
ruleDeletedSub := eventbus.Subscribe[netmon.RuleDeleted](ec)
|
||||||
|
portUpdateSub := eventbus.Subscribe[router.PortUpdate](ec)
|
||||||
return func(ec *eventbus.Client) {
|
return func(ec *eventbus.Client) {
|
||||||
for {
|
for {
|
||||||
select {
|
select {
|
||||||
@ -176,6 +179,11 @@ func (r *linuxRouter) consumeEventbusTopics(ec *eventbus.Client) func(*eventbus.
|
|||||||
return
|
return
|
||||||
case rs := <-ruleDeletedSub.Events():
|
case rs := <-ruleDeletedSub.Events():
|
||||||
r.onIPRuleDeleted(rs.Table, rs.Priority)
|
r.onIPRuleDeleted(rs.Table, rs.Priority)
|
||||||
|
case pu := <-portUpdateSub.Events():
|
||||||
|
r.logf("portUpdate(port=%v, network=%s)", pu.UDPPort, pu.EndpointNetwork)
|
||||||
|
if err := r.updateMagicsockPort(pu.UDPPort, pu.EndpointNetwork); err != nil {
|
||||||
|
r.logf("updateMagicsockPort(port=%v, network=%s) failed: %v", pu.UDPPort, pu.EndpointNetwork, err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -355,7 +363,9 @@ func (r *linuxRouter) onIPRuleDeleted(table uint8, priority uint32) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (r *linuxRouter) Up() error {
|
func (r *linuxRouter) Up() error {
|
||||||
if err := r.setNetfilterMode(netfilterOff); err != nil {
|
r.mu.Lock()
|
||||||
|
defer r.mu.Unlock()
|
||||||
|
if err := r.setNetfilterModeLocked(netfilterOff); err != nil {
|
||||||
return fmt.Errorf("setting netfilter mode: %w", err)
|
return fmt.Errorf("setting netfilter mode: %w", err)
|
||||||
}
|
}
|
||||||
if err := r.addIPRules(); err != nil {
|
if err := r.addIPRules(); err != nil {
|
||||||
@ -369,6 +379,8 @@ func (r *linuxRouter) Up() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (r *linuxRouter) Close() error {
|
func (r *linuxRouter) Close() error {
|
||||||
|
r.mu.Lock()
|
||||||
|
defer r.mu.Unlock()
|
||||||
r.closed.Store(true)
|
r.closed.Store(true)
|
||||||
if r.unregNetMon != nil {
|
if r.unregNetMon != nil {
|
||||||
r.unregNetMon()
|
r.unregNetMon()
|
||||||
@ -380,7 +392,7 @@ func (r *linuxRouter) Close() error {
|
|||||||
if err := r.delIPRules(); err != nil {
|
if err := r.delIPRules(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if err := r.setNetfilterMode(netfilterOff); err != nil {
|
if err := r.setNetfilterModeLocked(netfilterOff); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if err := r.delRoutes(); err != nil {
|
if err := r.delRoutes(); err != nil {
|
||||||
@ -394,10 +406,10 @@ func (r *linuxRouter) Close() error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// setupNetfilter initializes the NetfilterRunner in r.nfr. It expects r.nfr
|
// setupNetfilterLocked initializes the NetfilterRunner in r.nfr. It expects r.nfr
|
||||||
// to be nil, or the current netfilter to be set to netfilterOff.
|
// to be nil, or the current netfilter to be set to netfilterOff.
|
||||||
// kind should be either a linuxfw.FirewallMode, or the empty string for auto.
|
// kind should be either a linuxfw.FirewallMode, or the empty string for auto.
|
||||||
func (r *linuxRouter) setupNetfilter(kind string) error {
|
func (r *linuxRouter) setupNetfilterLocked(kind string) error {
|
||||||
r.netfilterKind = kind
|
r.netfilterKind = kind
|
||||||
|
|
||||||
var err error
|
var err error
|
||||||
@ -411,24 +423,26 @@ func (r *linuxRouter) setupNetfilter(kind string) error {
|
|||||||
|
|
||||||
// Set implements the Router interface.
|
// Set implements the Router interface.
|
||||||
func (r *linuxRouter) Set(cfg *router.Config) error {
|
func (r *linuxRouter) Set(cfg *router.Config) error {
|
||||||
|
r.mu.Lock()
|
||||||
|
defer r.mu.Unlock()
|
||||||
var errs []error
|
var errs []error
|
||||||
if cfg == nil {
|
if cfg == nil {
|
||||||
cfg = &shutdownConfig
|
cfg = &shutdownConfig
|
||||||
}
|
}
|
||||||
|
|
||||||
if cfg.NetfilterKind != r.netfilterKind {
|
if cfg.NetfilterKind != r.netfilterKind {
|
||||||
if err := r.setNetfilterMode(netfilterOff); err != nil {
|
if err := r.setNetfilterModeLocked(netfilterOff); err != nil {
|
||||||
err = fmt.Errorf("could not disable existing netfilter: %w", err)
|
err = fmt.Errorf("could not disable existing netfilter: %w", err)
|
||||||
errs = append(errs, err)
|
errs = append(errs, err)
|
||||||
} else {
|
} else {
|
||||||
r.nfr = nil
|
r.nfr = nil
|
||||||
if err := r.setupNetfilter(cfg.NetfilterKind); err != nil {
|
if err := r.setupNetfilterLocked(cfg.NetfilterKind); err != nil {
|
||||||
errs = append(errs, err)
|
errs = append(errs, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := r.setNetfilterMode(cfg.NetfilterMode); err != nil {
|
if err := r.setNetfilterModeLocked(cfg.NetfilterMode); err != nil {
|
||||||
errs = append(errs, err)
|
errs = append(errs, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -470,11 +484,11 @@ func (r *linuxRouter) Set(cfg *router.Config) error {
|
|||||||
case cfg.StatefulFiltering == r.statefulFiltering:
|
case cfg.StatefulFiltering == r.statefulFiltering:
|
||||||
// state already correct, nothing to do.
|
// state already correct, nothing to do.
|
||||||
case cfg.StatefulFiltering:
|
case cfg.StatefulFiltering:
|
||||||
if err := r.addStatefulRule(); err != nil {
|
if err := r.addStatefulRuleLocked(); err != nil {
|
||||||
errs = append(errs, err)
|
errs = append(errs, err)
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
if err := r.delStatefulRule(); err != nil {
|
if err := r.delStatefulRuleLocked(); err != nil {
|
||||||
errs = append(errs, err)
|
errs = append(errs, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -538,15 +552,17 @@ func (r *linuxRouter) updateStatefulFilteringWithDockerWarning(cfg *router.Confi
|
|||||||
r.health.SetHealthy(dockerStatefulFilteringWarnable)
|
r.health.SetHealthy(dockerStatefulFilteringWarnable)
|
||||||
}
|
}
|
||||||
|
|
||||||
// UpdateMagicsockPort implements the Router interface.
|
// updateMagicsockPort implements the Router interface.
|
||||||
func (r *linuxRouter) UpdateMagicsockPort(port uint16, network string) error {
|
func (r *linuxRouter) updateMagicsockPort(port uint16, network string) error {
|
||||||
|
r.mu.Lock()
|
||||||
|
defer r.mu.Unlock()
|
||||||
if r.nfr == nil {
|
if r.nfr == nil {
|
||||||
if err := r.setupNetfilter(r.netfilterKind); err != nil {
|
if err := r.setupNetfilterLocked(r.netfilterKind); err != nil {
|
||||||
return fmt.Errorf("could not setup netfilter: %w", err)
|
return fmt.Errorf("could not setup netfilter: %w", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var magicsockPort *atomic.Uint32
|
var magicsockPort *uint16
|
||||||
switch network {
|
switch network {
|
||||||
case "udp4":
|
case "udp4":
|
||||||
magicsockPort = &r.magicsockPortV4
|
magicsockPort = &r.magicsockPortV4
|
||||||
@ -566,45 +582,41 @@ func (r *linuxRouter) UpdateMagicsockPort(port uint16, network string) error {
|
|||||||
|
|
||||||
// set the port, we'll make the firewall rule when netfilter turns back on
|
// set the port, we'll make the firewall rule when netfilter turns back on
|
||||||
if r.netfilterMode == netfilterOff {
|
if r.netfilterMode == netfilterOff {
|
||||||
magicsockPort.Store(uint32(port))
|
*magicsockPort = port
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
cur := magicsockPort.Load()
|
if *magicsockPort == port {
|
||||||
|
|
||||||
if cur == uint32(port) {
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
if cur != 0 {
|
if *magicsockPort != 0 {
|
||||||
if err := r.nfr.DelMagicsockPortRule(uint16(cur), network); err != nil {
|
if err := r.nfr.DelMagicsockPortRule(*magicsockPort, network); err != nil {
|
||||||
return fmt.Errorf("del magicsock port rule: %w", err)
|
return fmt.Errorf("del magicsock port rule: %w", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if port != 0 {
|
if port != 0 {
|
||||||
if err := r.nfr.AddMagicsockPortRule(uint16(port), network); err != nil {
|
if err := r.nfr.AddMagicsockPortRule(*magicsockPort, network); err != nil {
|
||||||
return fmt.Errorf("add magicsock port rule: %w", err)
|
return fmt.Errorf("add magicsock port rule: %w", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
magicsockPort.Store(uint32(port))
|
*magicsockPort = port
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// setNetfilterMode switches the router to the given netfilter
|
// setNetfilterModeLocked switches the router to the given netfilter
|
||||||
// mode. Netfilter state is created or deleted appropriately to
|
// mode. Netfilter state is created or deleted appropriately to
|
||||||
// reflect the new mode, and r.snatSubnetRoutes is updated to reflect
|
// reflect the new mode, and r.snatSubnetRoutes is updated to reflect
|
||||||
// the current state of subnet SNATing.
|
// the current state of subnet SNATing.
|
||||||
func (r *linuxRouter) setNetfilterMode(mode preftype.NetfilterMode) error {
|
func (r *linuxRouter) setNetfilterModeLocked(mode preftype.NetfilterMode) error {
|
||||||
if !platformCanNetfilter() {
|
if !platformCanNetfilter() {
|
||||||
mode = netfilterOff
|
mode = netfilterOff
|
||||||
}
|
}
|
||||||
|
|
||||||
if r.nfr == nil {
|
if r.nfr == nil {
|
||||||
var err error
|
if err := r.setupNetfilterLocked(r.netfilterKind); err != nil {
|
||||||
r.nfr, err = linuxfw.New(r.logf, r.netfilterKind)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -660,13 +672,13 @@ func (r *linuxRouter) setNetfilterMode(mode preftype.NetfilterMode) error {
|
|||||||
if err := r.nfr.AddBase(r.tunname); err != nil {
|
if err := r.nfr.AddBase(r.tunname); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if mport := uint16(r.magicsockPortV4.Load()); mport != 0 {
|
if r.magicsockPortV4 != 0 {
|
||||||
if err := r.nfr.AddMagicsockPortRule(mport, "udp4"); err != nil {
|
if err := r.nfr.AddMagicsockPortRule(r.magicsockPortV4, "udp4"); err != nil {
|
||||||
return fmt.Errorf("could not add magicsock port rule v4: %w", err)
|
return fmt.Errorf("could not add magicsock port rule v4: %w", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if mport := uint16(r.magicsockPortV6.Load()); mport != 0 && r.getV6FilteringAvailable() {
|
if r.magicsockPortV6 != 0 && r.getV6FilteringAvailable() {
|
||||||
if err := r.nfr.AddMagicsockPortRule(mport, "udp6"); err != nil {
|
if err := r.nfr.AddMagicsockPortRule(r.magicsockPortV6, "udp6"); err != nil {
|
||||||
return fmt.Errorf("could not add magicsock port rule v6: %w", err)
|
return fmt.Errorf("could not add magicsock port rule v6: %w", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -700,13 +712,13 @@ func (r *linuxRouter) setNetfilterMode(mode preftype.NetfilterMode) error {
|
|||||||
if err := r.nfr.AddBase(r.tunname); err != nil {
|
if err := r.nfr.AddBase(r.tunname); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if mport := uint16(r.magicsockPortV4.Load()); mport != 0 {
|
if r.magicsockPortV4 != 0 {
|
||||||
if err := r.nfr.AddMagicsockPortRule(mport, "udp4"); err != nil {
|
if err := r.nfr.AddMagicsockPortRule(r.magicsockPortV4, "udp4"); err != nil {
|
||||||
return fmt.Errorf("could not add magicsock port rule v4: %w", err)
|
return fmt.Errorf("could not add magicsock port rule v4: %w", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if mport := uint16(r.magicsockPortV6.Load()); mport != 0 && r.getV6FilteringAvailable() {
|
if r.magicsockPortV6 != 0 && r.getV6FilteringAvailable() {
|
||||||
if err := r.nfr.AddMagicsockPortRule(mport, "udp6"); err != nil {
|
if err := r.nfr.AddMagicsockPortRule(r.magicsockPortV6, "udp6"); err != nil {
|
||||||
return fmt.Errorf("could not add magicsock port rule v6: %w", err)
|
return fmt.Errorf("could not add magicsock port rule v6: %w", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1483,9 +1495,9 @@ func (r *linuxRouter) delSNATRule() error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// addStatefulRule adds a netfilter rule to perform stateful filtering from
|
// addStatefulRuleLocked adds a netfilter rule to perform stateful filtering from
|
||||||
// subnets onto the tailnet.
|
// subnets onto the tailnet.
|
||||||
func (r *linuxRouter) addStatefulRule() error {
|
func (r *linuxRouter) addStatefulRuleLocked() error {
|
||||||
if r.netfilterMode == netfilterOff {
|
if r.netfilterMode == netfilterOff {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@ -1493,9 +1505,9 @@ func (r *linuxRouter) addStatefulRule() error {
|
|||||||
return r.nfr.AddStatefulRule(r.tunname)
|
return r.nfr.AddStatefulRule(r.tunname)
|
||||||
}
|
}
|
||||||
|
|
||||||
// delStatefulRule removes the netfilter rule to perform stateful filtering
|
// delStatefulRuleLocked removes the netfilter rule to perform stateful filtering
|
||||||
// from subnets onto the tailnet.
|
// from subnets onto the tailnet.
|
||||||
func (r *linuxRouter) delStatefulRule() error {
|
func (r *linuxRouter) delStatefulRuleLocked() error {
|
||||||
if r.netfilterMode == netfilterOff {
|
if r.netfilterMode == netfilterOff {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
@ -238,13 +238,6 @@ func (r *openbsdRouter) Set(cfg *router.Config) error {
|
|||||||
return errq
|
return errq
|
||||||
}
|
}
|
||||||
|
|
||||||
// UpdateMagicsockPort implements the Router interface. This implementation
|
|
||||||
// does nothing and returns nil because this router does not currently need
|
|
||||||
// to know what the magicsock UDP port is.
|
|
||||||
func (r *openbsdRouter) UpdateMagicsockPort(_ uint16, _ string) error {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *openbsdRouter) Close() error {
|
func (r *openbsdRouter) Close() error {
|
||||||
cleanUp(r.logf, r.tunname)
|
cleanUp(r.logf, r.tunname)
|
||||||
return nil
|
return nil
|
||||||
|
|||||||
@ -115,13 +115,6 @@ func (r *plan9Router) Set(cfg *router.Config) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// UpdateMagicsockPort implements the Router interface. This implementation
|
|
||||||
// does nothing and returns nil because this router does not currently need
|
|
||||||
// to know what the magicsock UDP port is.
|
|
||||||
func (r *plan9Router) UpdateMagicsockPort(_ uint16, _ string) error {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *plan9Router) Close() error {
|
func (r *plan9Router) Close() error {
|
||||||
// TODO(bradfitz): unbind
|
// TODO(bradfitz): unbind
|
||||||
return nil
|
return nil
|
||||||
|
|||||||
@ -206,13 +206,6 @@ func (r *userspaceBSDRouter) Set(cfg *router.Config) (reterr error) {
|
|||||||
return reterr
|
return reterr
|
||||||
}
|
}
|
||||||
|
|
||||||
// UpdateMagicsockPort implements the Router interface. This implementation
|
|
||||||
// does nothing and returns nil because this router does not currently need
|
|
||||||
// to know what the magicsock UDP port is.
|
|
||||||
func (r *userspaceBSDRouter) UpdateMagicsockPort(_ uint16, _ string) error {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *userspaceBSDRouter) Close() error {
|
func (r *userspaceBSDRouter) Close() error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
@ -114,13 +114,6 @@ func hasDefaultRoute(routes []netip.Prefix) bool {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
// UpdateMagicsockPort implements the Router interface. This implementation
|
|
||||||
// does nothing and returns nil because this router does not currently need
|
|
||||||
// to know what the magicsock UDP port is.
|
|
||||||
func (r *winRouter) UpdateMagicsockPort(_ uint16, _ string) error {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *winRouter) Close() error {
|
func (r *winRouter) Close() error {
|
||||||
r.firewall.clear()
|
r.firewall.clear()
|
||||||
|
|
||||||
|
|||||||
@ -35,14 +35,6 @@ type Router interface {
|
|||||||
// implementation should handle gracefully.
|
// implementation should handle gracefully.
|
||||||
Set(*Config) error
|
Set(*Config) error
|
||||||
|
|
||||||
// UpdateMagicsockPort tells the OS network stack what port magicsock
|
|
||||||
// is currently listening on, so it can be threaded through firewalls
|
|
||||||
// and such. This is distinct from Set() since magicsock may rebind
|
|
||||||
// ports independently from the Config changing.
|
|
||||||
//
|
|
||||||
// network should be either "udp4" or "udp6".
|
|
||||||
UpdateMagicsockPort(port uint16, network string) error
|
|
||||||
|
|
||||||
// Close closes the router.
|
// Close closes the router.
|
||||||
Close() error
|
Close() error
|
||||||
}
|
}
|
||||||
@ -56,6 +48,14 @@ type NewOpts struct {
|
|||||||
Bus *eventbus.Bus // required
|
Bus *eventbus.Bus // required
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// PortUpdate is an eventbus value, reporting the port and address family
|
||||||
|
// magicsock is currently listening on, so it can be threaded through firewalls
|
||||||
|
// and such.
|
||||||
|
type PortUpdate struct {
|
||||||
|
UDPPort uint16
|
||||||
|
EndpointNetwork string // either "udp4" or "udp6".
|
||||||
|
}
|
||||||
|
|
||||||
// HookNewUserspaceRouter is the registration point for router implementations
|
// HookNewUserspaceRouter is the registration point for router implementations
|
||||||
// to register a constructor for userspace routers. It's meant for implementations
|
// to register a constructor for userspace routers. It's meant for implementations
|
||||||
// in wgengine/router/osrouter.
|
// in wgengine/router/osrouter.
|
||||||
|
|||||||
@ -27,11 +27,6 @@ func (r fakeRouter) Set(cfg *Config) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r fakeRouter) UpdateMagicsockPort(_ uint16, _ string) error {
|
|
||||||
r.logf("[v1] warning: fakeRouter.UpdateMagicsockPort: not implemented.")
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r fakeRouter) Close() error {
|
func (r fakeRouter) Close() error {
|
||||||
r.logf("[v1] warning: fakeRouter.Close: not implemented.")
|
r.logf("[v1] warning: fakeRouter.Close: not implemented.")
|
||||||
return nil
|
return nil
|
||||||
|
|||||||
@ -398,13 +398,6 @@ func NewUserspaceEngine(logf logger.Logf, conf Config) (_ Engine, reterr error)
|
|||||||
|
|
||||||
e.RequestStatus()
|
e.RequestStatus()
|
||||||
}
|
}
|
||||||
onPortUpdate := func(port uint16, network string) {
|
|
||||||
e.logf("onPortUpdate(port=%v, network=%s)", port, network)
|
|
||||||
|
|
||||||
if err := e.router.UpdateMagicsockPort(port, network); err != nil {
|
|
||||||
e.logf("UpdateMagicsockPort(port=%v, network=%s) failed: %v", port, network, err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
magicsockOpts := magicsock.Options{
|
magicsockOpts := magicsock.Options{
|
||||||
EventBus: e.eventBus,
|
EventBus: e.eventBus,
|
||||||
Logf: logf,
|
Logf: logf,
|
||||||
@ -416,7 +409,6 @@ func NewUserspaceEngine(logf logger.Logf, conf Config) (_ Engine, reterr error)
|
|||||||
HealthTracker: e.health,
|
HealthTracker: e.health,
|
||||||
Metrics: conf.Metrics,
|
Metrics: conf.Metrics,
|
||||||
ControlKnobs: conf.ControlKnobs,
|
ControlKnobs: conf.ControlKnobs,
|
||||||
OnPortUpdate: onPortUpdate,
|
|
||||||
PeerByKeyFunc: e.PeerByKey,
|
PeerByKeyFunc: e.PeerByKey,
|
||||||
}
|
}
|
||||||
if buildfeatures.HasLazyWG {
|
if buildfeatures.HasLazyWG {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user