[management] Add IPv6 overlay addressing and capability gating (#5698)

This commit is contained in:
Viktor Liu
2026-04-08 22:40:51 +08:00
committed by GitHub
parent 86f1b53bd4
commit a1e7db2713
51 changed files with 2622 additions and 394 deletions

View File

@@ -774,7 +774,8 @@ func setupTestAccountManager(b testing.TB, peers int, groups int) (*DefaultAccou
ID: fmt.Sprintf("peer-%d", i),
DNSLabel: fmt.Sprintf("peer-%d", i),
Key: peerKey.PublicKey().String(),
IP: net.ParseIP(fmt.Sprintf("100.64.%d.%d", i/256, i%256)),
IP: netip.MustParseAddr(fmt.Sprintf("100.64.%d.%d", i/256, i%256)),
IPv6: netip.MustParseAddr(fmt.Sprintf("fd00::%d", i+1)),
Status: &nbpeer.PeerStatus{LastSeen: time.Now().UTC(), Connected: true},
UserID: regularUser,
}
@@ -803,7 +804,15 @@ func setupTestAccountManager(b testing.TB, peers int, groups int) (*DefaultAccou
account.Networks = append(account.Networks, network)
ips := account.GetTakenIPs()
peerIP, err := types.AllocatePeerIP(account.Network.Net, ips)
peerIP, err := types.AllocatePeerIP(netip.MustParsePrefix(account.Network.Net.String()), ips)
if err != nil {
return nil, nil, "", "", err
}
v6Prefix, err := netip.ParsePrefix(account.Network.NetV6.String())
if err != nil {
return nil, nil, "", "", err
}
peerIPv6, err := types.AllocateRandomPeerIPv6(v6Prefix)
if err != nil {
return nil, nil, "", "", err
}
@@ -814,6 +823,7 @@ func setupTestAccountManager(b testing.TB, peers int, groups int) (*DefaultAccou
DNSLabel: fmt.Sprintf("peer-nr-%d", len(account.Peers)+1),
Key: peerKey.PublicKey().String(),
IP: peerIP,
IPv6: peerIPv6,
Status: &nbpeer.PeerStatus{LastSeen: time.Now().UTC(), Connected: true},
UserID: regularUser,
Meta: nbpeer.PeerSystemMeta{
@@ -1093,7 +1103,8 @@ func TestToSyncResponse(t *testing.T) {
},
}
peer := &nbpeer.Peer{
IP: net.ParseIP("192.168.1.1"),
IP: netip.MustParseAddr("192.168.1.1"),
IPv6: netip.MustParseAddr("fd00::1"),
SSHEnabled: true,
Key: "peer-key",
DNSLabel: "peer1",
@@ -1104,9 +1115,21 @@ func TestToSyncResponse(t *testing.T) {
Signature: "turn-pass",
}
networkMap := &types.NetworkMap{
Network: &types.Network{Net: *ipnet, Serial: 1000},
Peers: []*nbpeer.Peer{{IP: net.ParseIP("192.168.1.2"), Key: "peer2-key", DNSLabel: "peer2", SSHEnabled: true, SSHKey: "peer2-ssh-key"}},
OfflinePeers: []*nbpeer.Peer{{IP: net.ParseIP("192.168.1.3"), Key: "peer3-key", DNSLabel: "peer3", SSHEnabled: true, SSHKey: "peer3-ssh-key"}},
Network: &types.Network{Net: *ipnet, Serial: 1000},
Peers: []*nbpeer.Peer{{
IP: netip.MustParseAddr("192.168.1.2"),
IPv6: netip.MustParseAddr("fd00::2"),
Key: "peer2-key",
DNSLabel: "peer2",
SSHEnabled: true,
SSHKey: "peer2-ssh-key"}},
OfflinePeers: []*nbpeer.Peer{{
IP: netip.MustParseAddr("192.168.1.3"),
IPv6: netip.MustParseAddr("fd00::3"),
Key: "peer3-key",
DNSLabel: "peer3",
SSHEnabled: true,
SSHKey: "peer3-ssh-key"}},
Routes: []*nbroute.Route{
{
ID: "route1",
@@ -1312,7 +1335,8 @@ func Test_RegisterPeerByUser(t *testing.T) {
ID: xid.New().String(),
AccountID: existingAccountID,
Key: "newPeerKey",
IP: net.IP{123, 123, 123, 123},
IP: netip.AddrFrom4([4]byte{123, 123, 123, 123}),
IPv6: netip.MustParseAddr("fd00::7b:7b:7b:7b"),
Meta: nbpeer.PeerSystemMeta{
Hostname: "newPeer",
GoOS: "linux",
@@ -1396,7 +1420,8 @@ func Test_RegisterPeerBySetupKey(t *testing.T) {
newPeerTemplate := &nbpeer.Peer{
AccountID: existingAccountID,
UserID: "",
IP: net.IP{123, 123, 123, 123},
IP: netip.AddrFrom4([4]byte{123, 123, 123, 123}),
IPv6: netip.MustParseAddr("fd00::7b:7b:7b:7b"),
Meta: nbpeer.PeerSystemMeta{
Hostname: "newPeer",
GoOS: "linux",
@@ -1553,7 +1578,8 @@ func Test_RegisterPeerRollbackOnFailure(t *testing.T) {
AccountID: existingAccountID,
Key: "newPeerKey",
UserID: "",
IP: net.IP{123, 123, 123, 123},
IP: netip.AddrFrom4([4]byte{123, 123, 123, 123}),
IPv6: netip.MustParseAddr("fd00::7b:7b:7b:7b"),
Meta: nbpeer.PeerSystemMeta{
Hostname: "newPeer",
GoOS: "linux",
@@ -1635,7 +1661,8 @@ func Test_LoginPeer(t *testing.T) {
newPeerTemplate := &nbpeer.Peer{
AccountID: existingAccountID,
UserID: "",
IP: net.IP{123, 123, 123, 123},
IP: netip.AddrFrom4([4]byte{123, 123, 123, 123}),
IPv6: netip.MustParseAddr("fd00::7b:7b:7b:7b"),
Meta: nbpeer.PeerSystemMeta{
Hostname: "newPeer",
GoOS: "linux",
@@ -2137,14 +2164,16 @@ func Test_DeletePeer(t *testing.T) {
ID: "peer1",
AccountID: accountID,
Key: "key1",
IP: net.IP{1, 1, 1, 1},
IP: netip.AddrFrom4([4]byte{1, 1, 1, 1}),
IPv6: netip.MustParseAddr("fd00::1"),
DNSLabel: "peer1.test",
},
"peer2": {
ID: "peer2",
AccountID: accountID,
Key: "key2",
IP: net.IP{2, 2, 2, 2},
IP: netip.AddrFrom4([4]byte{2, 2, 2, 2}),
IPv6: netip.MustParseAddr("fd00::2"),
DNSLabel: "peer2.test",
},
}
@@ -2741,6 +2770,20 @@ func TestProcessPeerAddAuth(t *testing.T) {
})
}
func TestPeerWillHaveIPv6(t *testing.T) {
settings := &types.Settings{
IPv6EnabledGroups: []string{"all-group-id", "group-a"},
}
assert.True(t, peerWillHaveIPv6(settings, nil, "all-group-id"), "peer in All group should get IPv6")
assert.True(t, peerWillHaveIPv6(settings, []string{"group-a"}, ""), "peer with matching auto-group should get IPv6")
assert.False(t, peerWillHaveIPv6(settings, []string{"group-b"}, "other-all"), "peer with no matching groups should not get IPv6")
assert.False(t, peerWillHaveIPv6(settings, nil, ""), "embedded peer with no groups should not get IPv6")
emptySettings := &types.Settings{IPv6EnabledGroups: []string{}}
assert.False(t, peerWillHaveIPv6(emptySettings, []string{"group-a"}, "all-group-id"), "no IPv6 groups means no IPv6")
}
func TestUpdatePeer_DnsLabelCollisionWithFQDN(t *testing.T) {
manager, _, err := createManager(t)
require.NoError(t, err, "unable to create account manager")