Merge remote-tracking branch 'origin/master' into fips140

This commit is contained in:
Wade Simmons
2026-01-30 13:41:49 -05:00
76 changed files with 4341 additions and 1222 deletions

View File

@@ -78,7 +78,8 @@ type Interface struct {
reQueryEvery atomic.Uint32
reQueryWait atomic.Int64
sendRecvErrorConfig sendRecvErrorConfig
sendRecvErrorConfig recvErrorConfig
acceptRecvErrorConfig recvErrorConfig
// rebindCount is used to decide if an active tunnel should trigger a punch notification through a lighthouse
rebindCount int8
@@ -111,34 +112,34 @@ type EncWriter interface {
GetCertState() *CertState
}
type sendRecvErrorConfig uint8
type recvErrorConfig uint8
const (
sendRecvErrorAlways sendRecvErrorConfig = iota
sendRecvErrorNever
sendRecvErrorPrivate
recvErrorAlways recvErrorConfig = iota
recvErrorNever
recvErrorPrivate
)
func (s sendRecvErrorConfig) ShouldSendRecvError(endpoint netip.AddrPort) bool {
func (s recvErrorConfig) ShouldRecvError(endpoint netip.AddrPort) bool {
switch s {
case sendRecvErrorPrivate:
case recvErrorPrivate:
return endpoint.Addr().IsPrivate()
case sendRecvErrorAlways:
case recvErrorAlways:
return true
case sendRecvErrorNever:
case recvErrorNever:
return false
default:
panic(fmt.Errorf("invalid sendRecvErrorConfig value: %d", s))
panic(fmt.Errorf("invalid recvErrorConfig value: %d", s))
}
}
func (s sendRecvErrorConfig) String() string {
func (s recvErrorConfig) String() string {
switch s {
case sendRecvErrorAlways:
case recvErrorAlways:
return "always"
case sendRecvErrorNever:
case recvErrorNever:
return "never"
case sendRecvErrorPrivate:
case recvErrorPrivate:
return "private"
default:
return fmt.Sprintf("invalid(%d)", s)
@@ -224,6 +225,13 @@ func (f *Interface) activate() {
WithField("fips140", fips140.Enabled()).
Info("Nebula interface is active")
if f.routines > 1 {
if !f.inside.SupportsMultiqueue() || !f.outside.SupportsMultipleReaders() {
f.routines = 1
f.l.Warn("routines is not supported on this platform, falling back to a single routine")
}
}
metrics.GetOrRegisterGauge("routines", nil).Update(int64(f.routines))
// Prepare n tun queues
@@ -274,7 +282,7 @@ func (f *Interface) listenOut(i int) {
nb := make([]byte, 12, 12)
li.ListenOut(func(fromUdpAddr netip.AddrPort, payload []byte) {
f.readOutsidePackets(fromUdpAddr, nil, plaintext[:0], payload, h, fwPacket, lhh, nb, i, ctCache.Get(f.l))
f.readOutsidePackets(ViaSender{UdpAddr: fromUdpAddr}, plaintext[:0], payload, h, fwPacket, lhh, nb, i, ctCache.Get(f.l))
})
}
@@ -307,6 +315,7 @@ func (f *Interface) listenIn(reader io.ReadWriteCloser, i int) {
func (f *Interface) RegisterConfigChangeCallbacks(c *config.C) {
c.RegisterReloadCallback(f.reloadFirewall)
c.RegisterReloadCallback(f.reloadSendRecvError)
c.RegisterReloadCallback(f.reloadAcceptRecvError)
c.RegisterReloadCallback(f.reloadDisconnectInvalid)
c.RegisterReloadCallback(f.reloadMisc)
@@ -370,16 +379,16 @@ func (f *Interface) reloadSendRecvError(c *config.C) {
switch stringValue {
case "always":
f.sendRecvErrorConfig = sendRecvErrorAlways
f.sendRecvErrorConfig = recvErrorAlways
case "never":
f.sendRecvErrorConfig = sendRecvErrorNever
f.sendRecvErrorConfig = recvErrorNever
case "private":
f.sendRecvErrorConfig = sendRecvErrorPrivate
f.sendRecvErrorConfig = recvErrorPrivate
default:
if c.GetBool("listen.send_recv_error", true) {
f.sendRecvErrorConfig = sendRecvErrorAlways
f.sendRecvErrorConfig = recvErrorAlways
} else {
f.sendRecvErrorConfig = sendRecvErrorNever
f.sendRecvErrorConfig = recvErrorNever
}
}
@@ -388,6 +397,30 @@ func (f *Interface) reloadSendRecvError(c *config.C) {
}
}
func (f *Interface) reloadAcceptRecvError(c *config.C) {
if c.InitialLoad() || c.HasChanged("listen.accept_recv_error") {
stringValue := c.GetString("listen.accept_recv_error", "always")
switch stringValue {
case "always":
f.acceptRecvErrorConfig = recvErrorAlways
case "never":
f.acceptRecvErrorConfig = recvErrorNever
case "private":
f.acceptRecvErrorConfig = recvErrorPrivate
default:
if c.GetBool("listen.accept_recv_error", true) {
f.acceptRecvErrorConfig = recvErrorAlways
} else {
f.acceptRecvErrorConfig = recvErrorNever
}
}
f.l.WithField("acceptRecvError", f.acceptRecvErrorConfig.String()).
Info("Loaded accept_recv_error config")
}
}
func (f *Interface) reloadMisc(c *config.C) {
if c.HasChanged("counters.try_promote") {
n := c.GetUint32("counters.try_promote", defaultPromoteEvery)
@@ -459,6 +492,14 @@ func (f *Interface) Close() error {
f.l.WithError(err).Error("Error while closing udp socket")
}
}
for i, r := range f.readers {
if i == 0 {
continue // f.readers[0] is f.inside, which we want to save for last
}
if err := r.Close(); err != nil {
f.l.WithError(err).Error("Error while closing tun reader")
}
}
// Release the tun device
return f.inside.Close()