Merge branch 'client-ipv6-ssh-netflow' into client-ipv6-acl-usp

This commit is contained in:
Viktor Liu
2026-03-25 10:58:40 +01:00
3 changed files with 77 additions and 24 deletions

View File

@@ -11,12 +11,10 @@ import (
"github.com/netbirdio/netbird/client/firewall/uspfilter/common"
)
// localIPSnapshot is an immutable snapshot of local IP addresses.
// The entire snapshot is swapped atomically so reads are lock-free.
// localIPSnapshot is an immutable snapshot of local IP addresses, swapped
// atomically so reads are lock-free.
type localIPSnapshot struct {
ips map[netip.Addr]struct{}
// loopbackV4 is pre-checked to avoid map lookups for 127.0.0.0/8
loopbackV4 bool
}
type localIPManager struct {
@@ -95,10 +93,7 @@ func (m *localIPManager) UpdateLocalIPs(iface common.IFaceMapper) (err error) {
}
}
m.snapshot.Store(&localIPSnapshot{
ips: ips,
loopbackV4: true,
})
m.snapshot.Store(&localIPSnapshot{ips: ips})
log.Debugf("Local IP addresses: %v", addresses)
return nil
@@ -108,11 +103,8 @@ func (m *localIPManager) UpdateLocalIPs(iface common.IFaceMapper) (err error) {
func (m *localIPManager) IsLocalIP(ip netip.Addr) bool {
s := m.snapshot.Load()
// Fast path for 127.x.x.x without map lookup
if s.loopbackV4 && ip.Is4() {
if ip.As4()[0] == 127 {
return true
}
if ip.Is4() && ip.As4()[0] == 127 {
return true
}
_, found := s.ips[ip]

View File

@@ -0,0 +1,70 @@
package uspfilter
import (
"net/netip"
"testing"
"github.com/netbirdio/netbird/client/iface/wgaddr"
)
func setupManager(b *testing.B) *localIPManager {
b.Helper()
m := newLocalIPManager()
mock := &IFaceMock{
AddressFunc: func() wgaddr.Address {
return wgaddr.Address{
IP: netip.MustParseAddr("100.64.0.1"),
Network: netip.MustParsePrefix("100.64.0.0/16"),
IPv6: netip.MustParseAddr("fd00::1"),
IPv6Net: netip.MustParsePrefix("fd00::/64"),
}
},
}
_ = m.UpdateLocalIPs(mock)
return m
}
func BenchmarkIsLocalIP_v4_hit(b *testing.B) {
m := setupManager(b)
ip := netip.MustParseAddr("100.64.0.1")
b.ResetTimer()
for i := 0; i < b.N; i++ {
m.IsLocalIP(ip)
}
}
func BenchmarkIsLocalIP_v4_miss(b *testing.B) {
m := setupManager(b)
ip := netip.MustParseAddr("8.8.8.8")
b.ResetTimer()
for i := 0; i < b.N; i++ {
m.IsLocalIP(ip)
}
}
func BenchmarkIsLocalIP_v6_hit(b *testing.B) {
m := setupManager(b)
ip := netip.MustParseAddr("fd00::1")
b.ResetTimer()
for i := 0; i < b.N; i++ {
m.IsLocalIP(ip)
}
}
func BenchmarkIsLocalIP_v6_miss(b *testing.B) {
m := setupManager(b)
ip := netip.MustParseAddr("2001:db8::1")
b.ResetTimer()
for i := 0; i < b.N; i++ {
m.IsLocalIP(ip)
}
}
func BenchmarkIsLocalIP_loopback(b *testing.B) {
m := setupManager(b)
ip := netip.MustParseAddr("127.0.0.1")
b.ResetTimer()
for i := 0; i < b.N; i++ {
m.IsLocalIP(ip)
}
}

View File

@@ -40,7 +40,6 @@ import (
"github.com/netbirdio/netbird/client/system"
mgm "github.com/netbirdio/netbird/shared/management/client"
mgmProto "github.com/netbirdio/netbird/shared/management/proto"
"github.com/netbirdio/netbird/shared/netiputil"
"github.com/netbirdio/netbird/shared/relay/auth/hmac"
relayClient "github.com/netbirdio/netbird/shared/relay/client"
signal "github.com/netbirdio/netbird/shared/signal/client"
@@ -530,16 +529,8 @@ func createEngineConfig(key wgtypes.Key, config *profilemanager.Config, peerConf
}
if !config.DisableIPv6 {
if raw := peerConfig.GetAddressV6(); len(raw) > 0 {
prefix, err := netiputil.DecodePrefix(raw)
if err != nil {
log.Warnf("decode v6 overlay address: %v", err)
} else if !prefix.Addr().Is6() {
log.Warnf("expected IPv6 overlay address, got %s", prefix.Addr())
} else {
wgAddr.IPv6 = prefix.Addr()
wgAddr.IPv6Net = prefix.Masked()
}
if err := wgAddr.SetIPv6FromCompact(peerConfig.GetAddressV6()); err != nil {
log.Warn(err)
}
}