Repository navigation
[multicast, smf] validate SSM joins and rework the joiner service - #14
Merged
Merged
Conversation
We reject a source-less join on an SSM-range group (232.0.0.0/8, ff30::/12, RFC 4607 §1) at CLI validation. SSM defines no shared (*, G) tree, so such a join installs no usable listener state and could look like a network regression. Classification lives in ssm.rs and mirrors Nexus's is_ssm_address. The SMF manifest's start method pointed at mgd_method_script.sh, a copy-paste path nothing installs, so the service flapped between incomplete and running. It now points at method_script.sh (matching package-manifest.toml), and the script is reworked to spawn one joiner per configured multicast group (SSM encoded as group@src1,src2), pinning joins via multicast_iface (IPv4) and a new ipv6_scope property. The service idles when no groups are configured and restarts through the ctrun contract when any joiner exits, re-establishing every membership.
zeeshanlakhani
force-pushed
the
zl/multicast-joiner
branch
from
July 23, 2026 18:37
a37ef1c to
cb4cd0d
Compare
taspelund
reviewed
Jul 24, 2026
taspelund
reviewed
Jul 24, 2026
taspelund
reviewed
Jul 24, 2026
taspelund
reviewed
Jul 24, 2026
taspelund
reviewed
Jul 24, 2026
taspelund
reviewed
Jul 24, 2026
…dress First set of work is replacing the IPv4-only `--multicast-iface` address with an `InterfaceSelector` that accepts an interface name or an IP bound to one, resolved per group family. IPv4 groups use the interface's address for `IP_MULTICAST_IF` and joins. IPv6 groups use its `ifindex` for `IPV6_MULTICAST_IF` and joins, and as the bind scope for interface- and link-local groups. Ambiguous address selectors resolve to the first matching interface. `--scope` is now unicast-only, and the `ipv6_scope` SMF property has been removed. SSM validation collapses to a single `--multicast-iface` requirement. The method script reads one interface property and returns early when no groups are configured. Finally, this also addresses the review feedback around method-script checks, control flow, property handling, and header documentation.
zeeshanlakhani
force-pushed
the
zl/multicast-joiner
branch
from
July 24, 2026 12:13
fc5dd05 to
a134244
Compare
|
Overall I think the new changes look good. If you didn't want to maintain your own code for pulling IPs and converting ifnames and all that, I think libnet may have a fair amount of this already. https://github.com/oxidecomputer/netadm-sys/tree/main/libnet |
taspelund
approved these changes
Jul 24, 2026
Contributor
Author
totally forgot about this, let me see. ... Yeah, I feel like this is maybe too much for what we need; so, I'll keep this simple for now. |
Restrict the IPv6 SSM classifier to the RFC 4607 ff3x::/32 blocks (matching Nexus's `is_ssm_address`) and validate SSM destinations against the control plane's admission rules: the reserved 232.0.0.0/24, IPv6 group IDs below 0x80000000, and unusable multicast scopes. Reject broadcast and link-local multicast sources at parse time, matching Dendrite's source checks. We'll eventually oxnet all this (in a TODO), as that affects many repos.
This was referenced Aug 20, 2026
rcgoodfellow
approved these changes
Sep 29, 2026
…cleanup Our SSM validation now matches oxidecomputer/dendrite#396, which is the updated read on the RFCs for both group and source checking. We move the interface lookups onto `IfAddrs`/`IfAddr`, and add tests for source parsing and the interface-name handling. Also, we do a full run over the documentation to make this match up with the current stack of PRs going into prod.
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.
We (now) reject a source-less join on an address classified as SSM at CLI validation, and require
--multicast-ifacealongside--multicast-sourcefor an SSM join to always pin to a specific interface. Classification uses 232.0.0.0/8 for IPv4, andff3x::/32orffbx::/32with a zero prefix length for IPv6 (RFC 4607 §1, RFC 7371 §4.1.2).We also check SSM destinations the way dendrite does as of oxidecomputer/dendrite#396. Only the SSM null addresses (232.0.0.0, ff3x::4000:0, RFC 4607 §4.3) and IPv6 scopes 0-2 get rejected (dendrite loosened its earlier, stricter rules, for more flexibility and a closer RFC read).
--multicast-sourcehas to be an address that can actually send forwarded traffic (e.g., no broadcast, link-local, 0/8, 240/4, or v4-mapped/compatible v6). Otherwise, the join would just sit there receiving nothing, and that looks like a network regression.The SMF manifest's start method had pointed at
mgd_method_script.sh, a copy-paste path nothing installs to, so the service flapped between incomplete and running. It now points atmethod_script.sh(matchingpackage-manifest.toml), and the script is reworked to spawn one joiner per configured multicast group (SSM encoded asgroup@src1,src2). Multicast joins are pinned through a singlemulticast_ifaceproperty. The binary accepts an interface name or bound IP address and resolves it to the IPv4 address or IPv6 interface index required for each join. Interface- and link-local IPv6 groups also use this index as their bind scope.--scopeis now solely for unicast, and theipv6_scopeproperty has been removed.The service idles when no groups are configured. If any joiner exits, the service restarts through the
ctruncontract and every membership is re-joined.