mirror of
https://github.com/netbirdio/netbird.git
synced 2026-10-21 12:59:08 +02:00
50 lines
1.9 KiB
Go
50 lines
1.9 KiB
Go
package configurer
|
|
|
|
import (
|
|
"net"
|
|
"net/netip"
|
|
)
|
|
// prefixesToIPNets converts prefixes on their way to a device. It is the only place that
|
|
// conversion happens, so it also normalizes: the device is then given the same form the
|
|
// store records, and a v4-mapped prefix cannot reach net.IPNet, which prints such an
|
|
// address as v4 while taking the length from its 16 byte mask and so turns
|
|
// ::ffff:10.1.2.3/64 into 10.1.2.3/0 — an allowed IP matching every v4 address.
|
|
func prefixesToIPNets(prefixes []netip.Prefix) []net.IPNet {
|
|
ipNets := make([]net.IPNet, len(prefixes))
|
|
for i, prefix := range prefixes {
|
|
normalized := normalizePrefix(prefix)
|
|
ipNets[i] = net.IPNet{
|
|
IP: normalized.Addr().AsSlice(),
|
|
Mask: net.CIDRMask(normalized.Bits(), normalized.Addr().BitLen()),
|
|
}
|
|
}
|
|
return ipNets
|
|
}
|
|
|
|
// normalizePrefix puts a prefix into the form the store recognises it by. It clears the
|
|
// host bits, which a device does on its own, so a caller passing 10.20.0.1/16 still matches
|
|
// the 10.20.0.0/16 read back from the device; and it unmaps a v4-mapped prefix so that it
|
|
// compares equal to, and marshals like, the plain v4 prefix for the same network.
|
|
//
|
|
// Masking comes first because it also decides the address family: only a prefix at least 96
|
|
// bits long keeps the mapped marker through the mask, so a shorter prefix inside the mapped
|
|
// range is a genuine v6 prefix and unmapping it would yield an invalid v4 prefix.
|
|
func normalizePrefix(prefix netip.Prefix) netip.Prefix {
|
|
masked := prefix.Masked()
|
|
|
|
addr := masked.Addr()
|
|
if !addr.Is4In6() {
|
|
return masked
|
|
}
|
|
return netip.PrefixFrom(addr.Unmap(), masked.Bits()-96)
|
|
}
|
|
|
|
// normalizePrefixes returns a normalized copy without changing the caller's slice.
|
|
func normalizePrefixes(prefixes []netip.Prefix) []netip.Prefix {
|
|
normalized := make([]netip.Prefix, len(prefixes))
|
|
for i, prefix := range prefixes {
|
|
normalized[i] = normalizePrefix(prefix)
|
|
}
|
|
return normalized
|
|
}
|