mirror of
https://github.com/slackhq/nebula.git
synced 2026-04-02 22:35:18 +02:00
crappy AI tests
This commit is contained in:
171
overlay/tun_snat_test.go
Normal file
171
overlay/tun_snat_test.go
Normal file
@@ -0,0 +1,171 @@
|
||||
package overlay
|
||||
|
||||
import (
|
||||
"io"
|
||||
"net/netip"
|
||||
"testing"
|
||||
|
||||
"github.com/sirupsen/logrus"
|
||||
"github.com/slackhq/nebula/config"
|
||||
"github.com/slackhq/nebula/routing"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
// mockDevice is a minimal Device implementation for testing prepareSnatAddr.
|
||||
type mockDevice struct {
|
||||
networks []netip.Prefix
|
||||
unsafeNetworks []netip.Prefix
|
||||
snatAddr netip.Prefix
|
||||
}
|
||||
|
||||
func (d *mockDevice) Read([]byte) (int, error) { return 0, nil }
|
||||
func (d *mockDevice) Write([]byte) (int, error) { return 0, nil }
|
||||
func (d *mockDevice) Close() error { return nil }
|
||||
func (d *mockDevice) Activate() error { return nil }
|
||||
func (d *mockDevice) Networks() []netip.Prefix { return d.networks }
|
||||
func (d *mockDevice) UnsafeNetworks() []netip.Prefix { return d.unsafeNetworks }
|
||||
func (d *mockDevice) SNATAddress() netip.Prefix { return d.snatAddr }
|
||||
func (d *mockDevice) Name() string { return "mock" }
|
||||
func (d *mockDevice) RoutesFor(netip.Addr) routing.Gateways { return routing.Gateways{} }
|
||||
func (d *mockDevice) SupportsMultiqueue() bool { return false }
|
||||
func (d *mockDevice) NewMultiQueueReader() (io.ReadWriteCloser, error) { return nil, nil }
|
||||
|
||||
func TestPrepareSnatAddr_V4Primary_NoSnat(t *testing.T) {
|
||||
l := logrus.New()
|
||||
l.SetLevel(logrus.PanicLevel)
|
||||
c := config.NewC(l)
|
||||
|
||||
// If the device has an IPv4 primary address, no SNAT needed
|
||||
d := &mockDevice{
|
||||
networks: []netip.Prefix{netip.MustParsePrefix("10.0.0.1/24")},
|
||||
}
|
||||
result := prepareSnatAddr(d, l, c, nil)
|
||||
assert.Equal(t, netip.Prefix{}, result, "should not assign SNAT addr when device has IPv4 primary")
|
||||
}
|
||||
|
||||
func TestPrepareSnatAddr_V6Primary_NoUnsafeOrRoutes(t *testing.T) {
|
||||
l := logrus.New()
|
||||
l.SetLevel(logrus.PanicLevel)
|
||||
c := config.NewC(l)
|
||||
|
||||
// IPv6 primary but no unsafe networks or IPv4 routes
|
||||
d := &mockDevice{
|
||||
networks: []netip.Prefix{netip.MustParsePrefix("fd00::1/128")},
|
||||
}
|
||||
result := prepareSnatAddr(d, l, c, nil)
|
||||
assert.Equal(t, netip.Prefix{}, result, "should not assign SNAT addr without IPv4 unsafe networks or routes")
|
||||
}
|
||||
|
||||
func TestPrepareSnatAddr_V6Primary_WithV4Unsafe(t *testing.T) {
|
||||
l := logrus.New()
|
||||
l.SetLevel(logrus.PanicLevel)
|
||||
c := config.NewC(l)
|
||||
|
||||
// IPv6 primary with IPv4 unsafe network -> should get SNAT addr
|
||||
d := &mockDevice{
|
||||
networks: []netip.Prefix{netip.MustParsePrefix("fd00::1/128")},
|
||||
unsafeNetworks: []netip.Prefix{netip.MustParsePrefix("192.168.0.0/16")},
|
||||
}
|
||||
result := prepareSnatAddr(d, l, c, nil)
|
||||
require.True(t, result.IsValid(), "should assign SNAT addr")
|
||||
assert.True(t, result.Addr().Is4(), "SNAT addr should be IPv4")
|
||||
assert.True(t, result.Addr().IsLinkLocalUnicast(), "SNAT addr should be link-local")
|
||||
assert.Equal(t, 32, result.Bits(), "SNAT addr should be /32")
|
||||
}
|
||||
|
||||
func TestPrepareSnatAddr_V6Primary_WithV4Route(t *testing.T) {
|
||||
l := logrus.New()
|
||||
l.SetLevel(logrus.PanicLevel)
|
||||
c := config.NewC(l)
|
||||
|
||||
// IPv6 primary with IPv4 route -> should get SNAT addr
|
||||
d := &mockDevice{
|
||||
networks: []netip.Prefix{netip.MustParsePrefix("fd00::1/128")},
|
||||
}
|
||||
routes := []Route{
|
||||
{Cidr: netip.MustParsePrefix("10.0.0.0/8")},
|
||||
}
|
||||
result := prepareSnatAddr(d, l, c, routes)
|
||||
require.True(t, result.IsValid(), "should assign SNAT addr when IPv4 route exists")
|
||||
assert.True(t, result.Addr().Is4())
|
||||
assert.True(t, result.Addr().IsLinkLocalUnicast())
|
||||
}
|
||||
|
||||
func TestPrepareSnatAddr_V6Primary_V6UnsafeOnly(t *testing.T) {
|
||||
l := logrus.New()
|
||||
l.SetLevel(logrus.PanicLevel)
|
||||
c := config.NewC(l)
|
||||
|
||||
// IPv6 primary with only IPv6 unsafe network -> no SNAT needed
|
||||
d := &mockDevice{
|
||||
networks: []netip.Prefix{netip.MustParsePrefix("fd00::1/128")},
|
||||
unsafeNetworks: []netip.Prefix{netip.MustParsePrefix("fd01::/64")},
|
||||
}
|
||||
result := prepareSnatAddr(d, l, c, nil)
|
||||
assert.Equal(t, netip.Prefix{}, result, "should not assign SNAT addr for IPv6-only unsafe networks")
|
||||
}
|
||||
|
||||
func TestPrepareSnatAddr_ManualAddress(t *testing.T) {
|
||||
l := logrus.New()
|
||||
l.SetLevel(logrus.PanicLevel)
|
||||
c := config.NewC(l)
|
||||
c.Settings["tun"] = map[string]any{
|
||||
"snat_address_for_4over6": "169.254.42.42",
|
||||
}
|
||||
|
||||
d := &mockDevice{
|
||||
networks: []netip.Prefix{netip.MustParsePrefix("fd00::1/128")},
|
||||
unsafeNetworks: []netip.Prefix{netip.MustParsePrefix("192.168.0.0/16")},
|
||||
}
|
||||
result := prepareSnatAddr(d, l, c, nil)
|
||||
require.True(t, result.IsValid())
|
||||
assert.Equal(t, netip.MustParseAddr("169.254.42.42"), result.Addr())
|
||||
assert.Equal(t, 32, result.Bits())
|
||||
}
|
||||
|
||||
func TestPrepareSnatAddr_InvalidManualAddress_Fallback(t *testing.T) {
|
||||
l := logrus.New()
|
||||
l.SetLevel(logrus.PanicLevel)
|
||||
c := config.NewC(l)
|
||||
c.Settings["tun"] = map[string]any{
|
||||
"snat_address_for_4over6": "not-an-ip",
|
||||
}
|
||||
|
||||
d := &mockDevice{
|
||||
networks: []netip.Prefix{netip.MustParsePrefix("fd00::1/128")},
|
||||
unsafeNetworks: []netip.Prefix{netip.MustParsePrefix("192.168.0.0/16")},
|
||||
}
|
||||
result := prepareSnatAddr(d, l, c, nil)
|
||||
// Should fall back to auto-assignment
|
||||
require.True(t, result.IsValid(), "should fall back to auto-assigned address")
|
||||
assert.True(t, result.Addr().Is4())
|
||||
assert.True(t, result.Addr().IsLinkLocalUnicast())
|
||||
}
|
||||
|
||||
func TestPrepareSnatAddr_AutoGenerated_Range(t *testing.T) {
|
||||
l := logrus.New()
|
||||
l.SetLevel(logrus.PanicLevel)
|
||||
c := config.NewC(l)
|
||||
|
||||
d := &mockDevice{
|
||||
networks: []netip.Prefix{netip.MustParsePrefix("fd00::1/128")},
|
||||
unsafeNetworks: []netip.Prefix{netip.MustParsePrefix("192.168.0.0/16")},
|
||||
}
|
||||
|
||||
// Generate several addresses and verify they're all in the expected range
|
||||
for i := 0; i < 100; i++ {
|
||||
result := prepareSnatAddr(d, l, c, nil)
|
||||
require.True(t, result.IsValid())
|
||||
addr := result.Addr()
|
||||
octets := addr.As4()
|
||||
assert.Equal(t, byte(169), octets[0], "first octet should be 169")
|
||||
assert.Equal(t, byte(254), octets[1], "second octet should be 254")
|
||||
// Should not have .0 in the last octet
|
||||
assert.NotEqual(t, byte(0), octets[3], "last octet should not be 0")
|
||||
// Should not be 169.254.255.255 (broadcast)
|
||||
if octets[2] == 255 {
|
||||
assert.NotEqual(t, byte(255), octets[3], "should not be broadcast address")
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user