fix: no IPv6 grant pattern that refuses part of its prefix; refuse a replica before changing it #50

Merged
marcos-mendez merged 2 commits from fix/grant-compressed-ipv6 into main 2026-09-30 04:42:47 -03:00
marcos-mendez commented 2026-09-30 04:21:36 -03:00 (Migrated from github.com)

Found in the Template B smoke test of 2026-09-30.

The grant

MariaDB matches a grant's host against the text of the client's address, which compresses zero groups. suggest-address prints fd3d:80b2:d0d7::/64, keel granted repl@'fd3d:80b2:d0d7:0:%', and the replica at fd3d:80b2:d0d7::2 was refused. Every overlay prefix suggest-address produces has a zero fourth group, so the documented prefix form failed on all of them.

Checked on mariadb-server 11.8.6 (Debian 13), in a throwaway LXC with a client network namespace:

host of the grant result
fd3d:80b2:d0d7:0:% refuses ::2, admits fd3d:80b2:d0d7:0:1::
fd3d:80b2:d0d7::/64, .../ffff:ffff:ffff:ffff::, expanded netmask match nothing
fd3d:80b2:d0d7:0:0:0:0:2 refuses fd3d:80b2:d0d7::2
FD3D:80B2:D0D7::2 admits it (case does not matter)
10.9.0.0/255.255.255.0, 10.9.0.% work; 10.9.0.0/24 does not

MariaDB has no IPv6 netmask, so the only form left is a LIKE pattern. g1:...:gn:% matches every address of the prefix, and no other, exactly when no prefix group can be compressed away: the last group is not zero and no two zero groups are next to each other. When some can, adding a second pattern with :: does not fix it in general, because % cannot count the groups :: stands for (2001::5:% matches 2001::5:a:b, which is outside 2001:0:0:5::/64).

So:

  • such a prefix, or a host pattern written that way, is refused by apply. The refusal names an address the pattern would miss and says to write each replica's address. Prefixes whose groups are all written (2804:710:d0:5::/64, 2001:db8:0:5::/64) keep their pattern.
  • an address is granted compressed and lower cased.
  • the spec is engine neutral and PostgreSQL takes any prefix, so validation does not change. The refusal is in the MariaDB apply path, next to the existing /56 refusal.

The grants keel now generates were run against the same server: fd3d:80b2:d0d7::2 (written expanded in the spec) admits ::2 and refuses ::3; 2001:db8:0:5::/64 admits ::9 and :a:b:c:d and refuses 2001:db8:0:6::1.

The replica refusal

A replica that apply declines to build (it holds databases and has no --destroy-local-database, has no credential, and so on) is now refused before the configuration step. The drop-in is not rewritten and MariaDB is not restarted. The message now says exactly that, where before it said "Nothing was changed" after the restart had already happened.

Also

  • docs/spec.md and docs/apply.md: the rule, the overlay example with exact addresses, and the corrected refusal output.
  • 0.11.1 changelog entry. require-changelog needs a greater version, so this is not added to 0.11.0.
  • confconsole's primary screen offers the /64 of the node's first IPv6 address, which is now refused for an overlay ULA. Keel-Linux/confconsole#14 offers the overlay peers' addresses instead.

Test plan

  • tests first (red, then green): the pattern is checked against the compressed text of addresses whose zero groups fall in every place they can, inside the prefix and in the /16 around it
  • set -o pipefail; coverage run -m pytest: 1636 passed, coverage 99%
  • real mariadb-server 11.8.6, throwaway LXC, destroyed afterwards
  • CI green
Found in the Template B smoke test of 2026-09-30. ## The grant MariaDB matches a grant's host against the text of the client's address, which compresses zero groups. `suggest-address` prints `fd3d:80b2:d0d7::/64`, keel granted `repl@'fd3d:80b2:d0d7:0:%'`, and the replica at `fd3d:80b2:d0d7::2` was refused. Every overlay prefix suggest-address produces has a zero fourth group, so the documented prefix form failed on all of them. Checked on mariadb-server 11.8.6 (Debian 13), in a throwaway LXC with a client network namespace: | host of the grant | result | | --- | --- | | `fd3d:80b2:d0d7:0:%` | refuses `::2`, admits `fd3d:80b2:d0d7:0:1::` | | `fd3d:80b2:d0d7::/64`, `.../ffff:ffff:ffff:ffff::`, expanded netmask | match nothing | | `fd3d:80b2:d0d7:0:0:0:0:2` | refuses `fd3d:80b2:d0d7::2` | | `FD3D:80B2:D0D7::2` | admits it (case does not matter) | | `10.9.0.0/255.255.255.0`, `10.9.0.%` | work; `10.9.0.0/24` does not | MariaDB has no IPv6 netmask, so the only form left is a LIKE pattern. `g1:...:gn:%` matches every address of the prefix, and no other, exactly when no prefix group can be compressed away: the last group is not zero and no two zero groups are next to each other. When some can, adding a second pattern with `::` does not fix it in general, because `%` cannot count the groups `::` stands for (`2001::5:%` matches `2001::5:a:b`, which is outside `2001:0:0:5::/64`). So: - such a prefix, or a host pattern written that way, is refused by apply. The refusal names an address the pattern would miss and says to write each replica's address. Prefixes whose groups are all written (`2804:710:d0:5::/64`, `2001:db8:0:5::/64`) keep their pattern. - an address is granted compressed and lower cased. - the spec is engine neutral and PostgreSQL takes any prefix, so validation does not change. The refusal is in the MariaDB apply path, next to the existing `/56` refusal. The grants keel now generates were run against the same server: `fd3d:80b2:d0d7::2` (written expanded in the spec) admits `::2` and refuses `::3`; `2001:db8:0:5::/64` admits `::9` and `:a:b:c:d` and refuses `2001:db8:0:6::1`. ## The replica refusal A replica that apply declines to build (it holds databases and has no `--destroy-local-database`, has no credential, and so on) is now refused before the configuration step. The drop-in is not rewritten and MariaDB is not restarted. The message now says exactly that, where before it said "Nothing was changed" after the restart had already happened. ## Also - docs/spec.md and docs/apply.md: the rule, the overlay example with exact addresses, and the corrected refusal output. - 0.11.1 changelog entry. `require-changelog` needs a greater version, so this is not added to 0.11.0. - confconsole's primary screen offers the /64 of the node's first IPv6 address, which is now refused for an overlay ULA. Keel-Linux/confconsole#14 offers the overlay peers' addresses instead. ## Test plan - [x] tests first (red, then green): the pattern is checked against the compressed text of addresses whose zero groups fall in every place they can, inside the prefix and in the /16 around it - [x] `set -o pipefail; coverage run -m pytest`: 1636 passed, coverage 99% - [x] real mariadb-server 11.8.6, throwaway LXC, destroyed afterwards - [ ] CI green
Sign in to join this conversation.
No description provided.