diff --git a/ipn/local.go b/ipn/local.go index 7e2c60909..580c49abc 100644 --- a/ipn/local.go +++ b/ipn/local.go @@ -562,12 +562,13 @@ func (b *LocalBackend) updateFilter(netMap *controlclient.NetworkMap, prefs *Pre localNets := unmapIPPrefixes(netMap.Addresses, advRoutes) + oldFilter := b.e.GetFilter() if shieldsUp { b.logf("netmap packet filter: (shields up)") - b.e.SetFilter(filter.NewShieldsUpFilter(b.logf)) + b.e.SetFilter(filter.NewShieldsUpFilter(localNets, oldFilter, b.logf)) } else { b.logf("netmap packet filter: %v", packetFilter) - b.e.SetFilter(filter.New(packetFilter, localNets, b.e.GetFilter(), b.logf)) + b.e.SetFilter(filter.New(packetFilter, localNets, oldFilter, b.logf)) } } diff --git a/wgengine/filter/filter.go b/wgengine/filter/filter.go index 65c6fd289..b7eae68b1 100644 --- a/wgengine/filter/filter.go +++ b/wgengine/filter/filter.go @@ -132,8 +132,16 @@ func NewAllowNone(logf logger.Logf) *Filter { return New(nil, nil, nil, logf) } -func NewShieldsUpFilter(logf logger.Logf) *Filter { - f := New(nil, nil, nil, logf) +// NewShieldsUpFilter returns a packet filter that rejects incoming connections. +// +// If shareStateWith is non-nil, the returned filter shares state with the previous one, +// as long as the previous one was also a shields up filter. +func NewShieldsUpFilter(localNets []netaddr.IPPrefix, shareStateWith *Filter, logf logger.Logf) *Filter { + // Don't permit sharing state with a prior filter that wasn't a shields-up filter. + if shareStateWith != nil && !shareStateWith.shieldsUp { + shareStateWith = nil + } + f := New(nil, localNets, shareStateWith, logf) f.shieldsUp = true return f }