Use a genuinely random ULA /48 for auto-allocated IPv6 subnets
The old fd00:168:0::/48 base was never actually generated via RFC 4193's randomization procedure -- just a memorable placeholder chosen to visibly pair with the IPv4 10.168.x.x scheme. Replaced with fdf0:f243:f06f::/48, a real randomly-generated ULA prefix. That /48 consumes all three "identity" hextets a ULA prefix has room for, leaving only the subnet-id (4th) hextet -- the same one the per-network auto-allocation index already lived in -- with nowhere left to also place a fixed "168" marker without colliding with either the random prefix or the index itself. Per the user's own choice (offered two options): the per-network index is now offset by a constant 168 instead of matching IPv4's index number-for-number, so the first auto-allocated network's IPv6 block is fdf0:f243:f06f:168::/64 (paired with 10.168.0.0/24), second is ...:169::/64 (paired with 10.168.1.0/24), and so on -- deterministic and still visibly project-stamped, just via a constant offset instead of an identical digit. network_subnet.cpp's new ipv6_ula_prefix48/ipv6_subnet_id_base constants hold the new prefix and offset. Verified as root via the doas rule: two freshly created extern networks got fdf0:f243:f06f:168::/64 and fdf0:f243:f06f:169::/64 exactly as expected, correctly paired with their IPv4 subnets. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Gv3s5jckJKzh6JkMoi2Akz
This commit is contained in:
@@ -1469,16 +1469,28 @@ Source layout (all under `src/`):
|
||||
comparison generic over that byte length — IPv4 and IPv6 overlap checking
|
||||
are the same algorithm, not two parallel implementations.
|
||||
`allocate_ipv4_subnet()`/`allocate_ipv6_subnet()` (`commands.cpp`'s
|
||||
`create_network_command()`) scan `10.168.<n>.0/24`/`fd00:168:0:<n>::/64` for
|
||||
`n` in `0..255` and return the first one that doesn't overlap *any* existing
|
||||
network's subnet (via the overlap checks above, not just other
|
||||
auto-allocated ones — a manually `--subnet`-overridden network is checked
|
||||
too). The same `n` range for both is deliberate, so the common case (no
|
||||
manual overrides) allocates visibly paired v4/v6 blocks per network — though
|
||||
since IPv6 hextets are hexadecimal, `n >= 10` renders as a valid but
|
||||
numerically-different-from-`n` address (e.g. `n=15` becomes `...:15::/64`,
|
||||
which is hex `0x15` = 21) — purely cosmetic, allocation correctness doesn't
|
||||
depend on the two matching numerically. `ipv4_gateway_address()`/
|
||||
`create_network_command()`) scan `10.168.<n>.0/24`/
|
||||
`fdf0:f243:f06f:<168+n>::/64` for `n` in `0..255` and return the first one
|
||||
that doesn't overlap *any* existing network's subnet (via the overlap
|
||||
checks above, not just other auto-allocated ones — a manually
|
||||
`--subnet`-overridden network is checked too). `fdf0:f243:f06f::/48` is a
|
||||
randomly generated ULA (RFC 4193) — **replaced the original
|
||||
`fd00:168:0::/48`, which was never actually randomly generated, just a
|
||||
memorable placeholder, at the user's own request** ("since this is an
|
||||
ULA, let's use a randomly generated prefix"); the `168` offset on the
|
||||
subnet-id hextet (confirmed with the user via `AskUserQuestion`, over the
|
||||
alternative of dropping it and starting both at `0`) keeps the same
|
||||
project-recognizable stamp the old scheme's fixed 2nd hextet had, just as
|
||||
a constant offset now rather than a numerically-identical index — the
|
||||
same `n` range still drives both v4 and v6 allocation, so the common case
|
||||
(no manual overrides) still allocates deterministically paired blocks per
|
||||
network, just offset by `168` on the v6 side instead of matching exactly.
|
||||
Since IPv6 hextets are hexadecimal, `n + 168 >= 10` (i.e. always, given
|
||||
the offset) renders as a valid but numerically-different-from-`n + 168`
|
||||
address when read back as hex (e.g. `n=15` → `183` decimal → renders as
|
||||
`...:183::/64`, which is hex `0x183`, not `183`) — purely cosmetic,
|
||||
allocation correctness doesn't depend on this matching numerically at
|
||||
all. `ipv4_gateway_address()`/
|
||||
`ipv6_gateway_address()` (`network_bridge.cpp`'s `provision_bridge()`) and
|
||||
`ipv4_host_address()`/`ipv6_host_address()` (`network_join.cpp`'s
|
||||
`pick_free_address()`, see below — `n = 2, 3, ...` for individual
|
||||
|
||||
Reference in New Issue
Block a user