[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

@@ -341,7 +341,11 @@ components:
description: Allows to define a custom network range for the account in CIDR format
type: string
format: cidr
example: 100.64.0.0/16
network_range_v6:
description: Allows to define a custom IPv6 network range for the account in CIDR format.
type: string
format: cidr
example: fd00:1234:5678::/64
peer_expose_enabled:
description: Enables or disables peer expose. If enabled, peers can expose local services through the reverse proxy using the CLI.
type: boolean
@@ -377,6 +381,12 @@ components:
type: boolean
readOnly: true
example: false
ipv6_enabled_groups:
description: List of group IDs whose peers receive IPv6 overlay addresses. Peers not in any of these groups will not be allocated an IPv6 address. New accounts default to the All group.
type: array
items:
type: string
example: ["ch8i4ug6lnn4g9hqv7m0"]
required:
- peer_login_expiration_enabled
- peer_login_expiration
@@ -776,6 +786,11 @@ components:
type: string
format: ipv4
example: 100.64.0.15
ipv6:
description: Peer's IPv6 overlay address. Omitted if IPv6 is not enabled for the account.
type: string
format: ipv6
example: "fd00:4e42:ab12::1"
required:
- name
- ssh_enabled
@@ -795,6 +810,11 @@ components:
description: Peer's IP address
type: string
example: 10.64.0.1
ipv6:
description: Peer's IPv6 overlay address
type: string
format: ipv6
example: "fd00:4e42:ab12::1"
connection_ip:
description: Peer's public connection IP address
type: string
@@ -1013,6 +1033,10 @@ components:
description: Peer's IP address
type: string
example: 10.64.0.1
ipv6:
description: Peer's IPv6 overlay address
type: string
example: "fd00:4e42:ab12::1"
dns_label:
description: Peer's DNS label is the parsed peer name for domain resolution. It is used to form an FQDN by appending the account's domain to the peer label. e.g. peer-dns-label.netbird.cloud
type: string

View File

@@ -1351,6 +1351,9 @@ type AccessiblePeer struct {
// Ip Peer's IP address
Ip string `json:"ip"`
// Ipv6 Peer's IPv6 overlay address
Ipv6 *string `json:"ipv6,omitempty"`
// LastSeen Last time peer connected to Netbird's management service
LastSeen time.Time `json:"last_seen"`
@@ -1435,6 +1438,9 @@ type AccountSettings struct {
// GroupsPropagationEnabled Allows propagate the new user auto groups to peers that belongs to the user
GroupsPropagationEnabled *bool `json:"groups_propagation_enabled,omitempty"`
// Ipv6EnabledGroups List of group IDs whose peers receive IPv6 overlay addresses. Peers not in any of these groups will not be allocated an IPv6 address. New accounts default to the All group.
Ipv6EnabledGroups *[]string `json:"ipv6_enabled_groups,omitempty"`
// JwtAllowGroups List of groups to which users are allowed access
JwtAllowGroups *[]string `json:"jwt_allow_groups,omitempty"`
@@ -1453,6 +1459,9 @@ type AccountSettings struct {
// NetworkRange Allows to define a custom network range for the account in CIDR format
NetworkRange *string `json:"network_range,omitempty"`
// NetworkRangeV6 Allows to define a custom IPv6 network range for the account in CIDR format.
NetworkRangeV6 *string `json:"network_range_v6,omitempty"`
// PeerExposeEnabled Enables or disables peer expose. If enabled, peers can expose local services through the reverse proxy using the CLI.
PeerExposeEnabled bool `json:"peer_expose_enabled"`
@@ -3111,6 +3120,9 @@ type Peer struct {
// Ip Peer's IP address
Ip string `json:"ip"`
// Ipv6 Peer's IPv6 overlay address
Ipv6 *string `json:"ipv6,omitempty"`
// KernelVersion Peer's operating system kernel version
KernelVersion string `json:"kernel_version"`
@@ -3202,6 +3214,9 @@ type PeerBatch struct {
// Ip Peer's IP address
Ip string `json:"ip"`
// Ipv6 Peer's IPv6 overlay address
Ipv6 *string `json:"ipv6,omitempty"`
// KernelVersion Peer's operating system kernel version
KernelVersion string `json:"kernel_version"`
@@ -3301,7 +3316,10 @@ type PeerRequest struct {
InactivityExpirationEnabled bool `json:"inactivity_expiration_enabled"`
// Ip Peer's IP address
Ip *string `json:"ip,omitempty"`
Ip *string `json:"ip,omitempty"`
// Ipv6 Peer's IPv6 overlay address. Omitted if IPv6 is not enabled for the account.
Ipv6 *string `json:"ipv6,omitempty"`
LoginExpirationEnabled bool `json:"login_expiration_enabled"`
Name string `json:"name"`
SshEnabled bool `json:"ssh_enabled"`

View File

@@ -14,10 +14,15 @@ import (
)
// EncodePrefix encodes a netip.Prefix into compact bytes.
// The address is always unmapped before encoding.
// The address is always unmapped before encoding. If unmapping produces a v4
// address, the prefix length is clamped to 32.
func EncodePrefix(p netip.Prefix) []byte {
addr := p.Addr().Unmap()
return append(addr.AsSlice(), byte(p.Bits()))
bits := p.Bits()
if addr.Is4() && bits > 32 {
bits = 32
}
return append(addr.AsSlice(), byte(bits))
}
// DecodePrefix decodes compact bytes into a netip.Prefix.

View File

@@ -80,6 +80,26 @@ func TestEncodePrefixUnmaps(t *testing.T) {
assert.Equal(t, netip.MustParsePrefix("10.1.2.3/32"), decoded)
}
func TestEncodePrefixUnmapsClampsBits(t *testing.T) {
// v4-mapped v6 with bits > 32 should clamp to /32
mapped := netip.MustParsePrefix("::ffff:10.1.2.3/128")
b := EncodePrefix(mapped)
assert.Equal(t, 5, len(b), "v4-mapped should encode as 5 bytes")
decoded, err := DecodePrefix(b)
require.NoError(t, err)
assert.Equal(t, netip.MustParsePrefix("10.1.2.3/32"), decoded)
// v4-mapped v6 with bits=96 should also clamp to /32
mapped96 := netip.MustParsePrefix("::ffff:10.0.0.0/96")
b96 := EncodePrefix(mapped96)
assert.Equal(t, 5, len(b96))
decoded96, err := DecodePrefix(b96)
require.NoError(t, err)
assert.Equal(t, 32, decoded96.Bits())
}
func TestDecodeAddr(t *testing.T) {
v4 := netip.MustParseAddr("100.64.0.5")
b := EncodeAddr(v4)