fix(config): treat IPv4-mapped IPv6 as the address it maps to - #18
Draft
Ladas wants to merge 1 commit into
Draft
Conversation
Follow-ups to praxis-proxy#16, found by review after it merged. The host-binding registry compares bind addresses as `IpAddr`, which distinguishes an address by variant. `::ffff:127.0.0.1` and `127.0.0.1` name the same interface to the container runtime but never compared equal, so a cluster mapping and a service port using the two notations for one interface passed validation and then collided at `forge up` with the opaque "port is already allocated" the registry exists to prevent. `canonical_ip` collapses the mapped form before comparison. Two tests cover it: the mapped pair now conflicts, and `::1` against `127.0.0.1` still passes, because those are genuinely two addresses. Also: - The bind-address parse check was written twice, once for clusters and once for services, differing only in the error prefix. Folded into one `check_bind_address` taking a `PortOwner`, which already renders both prefixes. - `PortMapping::protocol` was documented as "tcp or udp". The field is shared by two validators that accept different values: cluster mappings take tcp, udp or sctp case-insensitively, matching KIND, and service ports take tcp only. The doc now says so, and the two protocol checks explain why they differ. - `generate_kind_config` claimed KIND only supports port mappings on control-plane nodes. KIND accepts the field on any node; one node is enough because kube-proxy makes a NodePort reachable through every node, and publishing the same host port from several would collide. Signed-off-by: Ladislav Smola <lsmola@redhat.com>
Ladas
force-pushed
the
fix/host-port-binding-followup
branch
from
September 7, 2026 11:20
494a5dd to
eb5a2a5
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why
Follow-ups to #16, found by a review pass after it merged. #16 landed at the
commit that was pushed, so these never made it in. Nothing here is urgent; two
of the four are statements #16 introduced that are simply not true.
The one behaviour change
The host-binding registry compares bind addresses as
IpAddr, whichdistinguishes them by variant.
::ffff:127.0.0.1and127.0.0.1name the sameinterface to the container runtime, but never compared equal.
Measured on
mainversus this branch, same config, two mappings on host port8080 written in the two notations:
And the collision is real, not theoretical — probed against Docker directly:
So
mainaccepts a config that then fails atforge upwith the opaque "portis already allocated" the registry exists to prevent.
canonical_ipcollapsesthe mapped form before comparison.
Two tests: the mapped pair now conflicts, and
127.0.0.1against::1stillpasses, because those genuinely are two addresses.
Honest scope note: this needs someone to both set
bindAddressand use theIPv4-mapped notation, which is rare. It is cheap insurance with tests, not a
fire.
Two comments that are wrong
PortMapping::protocolis documented as "tcp or udp". Since feat: add extraPortMappings support to ClusterSpec #16 the field isread by two validators that accept different values: cluster mappings take
tcp,udporsctpcase-insensitively, matching KIND; service ports taketcponly. The doc now says so, and the two protocol checks cross-referenceeach other so the divergence is visible where it is enforced.
generate_kind_configclaims "KIND only supports port mappings oncontrol-plane nodes". KIND accepts
extraPortMappingson any node. Using thefirst control-plane is our choice, and a sound one — kube-proxy makes a
NodePort reachable through every node, and publishing the same host port from
several nodes would collide — but it is a design decision, not a constraint
imposed by KIND.
One deduplication
The bind-address parse check was written twice, once for clusters and once for
services, differing only in the error prefix. Folded into one
check_bind_addresstaking thePortOwnerthat already renders both prefixes.Drop this commit if you would rather keep the diff to defects only.
Test plan
cargo clippy --all-targets -- -D warningscleancargo fmt --check,cargo doc --no-depscleanmainand pass here127.0.0.1/::1pair still accepted