Skip to content

MLD support - #36

Open
zeeshanlakhani wants to merge 6 commits into
mainfrom
zl/mld
Open

MLD support#36
zeeshanlakhani wants to merge 6 commits into
mainfrom
zl/mld

Conversation

@zeeshanlakhani

Copy link
Copy Markdown
Contributor

This PR adds MLD support for RFC 2710 and RFC 3810, with related type and parsing fixes.

This includes:

  • Adding MLD support for RFC 2710 and RFC 3810.
  • Adding a refined multicast IPv6 address (type).
  • Validating address classes on MLD messages.
  • Bounding repeated subparses by a count expression, following RFC 3376 and RFC 3810.
  • Counting IGMPv3 auxiliary data in 32-bit words (per spec)
  • Dropping an eager alloc::format! from derived Emit.

RFC 3376 §4.2.6 gives Aux Data Len in 32-bit words, but the `var_len` expression
used it as bytes, so a record claiming two words consumed two octets and
desynchronised every record after it. Conforming senders always set zero
(§4.2.10), so this bites only on non-conforming input, where a snooper and
the guest stack then disagree about the same packet.

Also, we add the missing §4.2.12 record types `ALLOW_NEW_SOURCES` and
`BLOCK_OLD_SOURCES`.
`Result::expect` takes its message by value, so the generated
`.expect(&alloc::format!(...))` allocated a String on every owned emit,
success included. The string has no interpolation, so no format is
necessary.

Also, we now document the caller-owns-the-length-field invariant on the
`var_len` docs.
MLD constrains fields to multicast addresses. `MulticastIpv6Addr` wraps
an `Ipv6Addr` proven multicast, in the `CRStr` shape.

Refinement lives in constructor signatures only. The derive's Ref traits
share the field type between owned and zero-copy forms, so a refined field
would make a view assert an invariant its bytes were never checked
against. A received address stays `Ipv6Addr` until refined through `new`.

`NotMulticastError` keeps a generic message so a v4 counterpart can share
it.
This adds MLDv1 (RFC 2710 §3) and the MLDv2 Query, Report and Multicast Address
Record (RFC 3810 §5.1, §5.2) types, modelled on the igmp module.

MLDv1 and MLDv2 Queries share ICMPv6 type 130 and are told apart by length
(RFC 3810 §8.1), so a v2 `TooSmall` means retry as v1, not a malformed
packet. `MldV1` builds through general_query, address_specific_query,
report and done rather than `Default`, since type zero is RESERVED. The
group-taking constructors require `MulticastIpv6Addr`, to be more
specific. Decoders cover the §5.1.3 and §5.1.9 floating-point Max Resp
Code and QQIC.

Also, we rename `MULTICAST_LISTENER_{REPORT,DONE}` to the `V1_`-prefixed forms,
matching `IgmpMessageType`. This is why we move to v3.
`RepeatedView` previously parsed until buffer exhaustion, ignoring the
protocol's count field. That conflicts with RFC 3810 §5.2.11 and RFC 3376
§4.2.11, which allow additional data after the last record inside the IP
payload. The count is the only reliable way to distinguish records from that
additional data.

For example, an empty IGMPv3 Report is 46 octets on the wire. Ethernet padding
extends the frame to the 60-octet minimum, and exhaustion parsing interpreted
that padding as a record and failed the parse.

This adds `RepeatedView::parse_counted`, driven by the opt-in
`#[ingot(subparse(count = "<expr>"))]` attribute. Headers without the
attribute retain their existing generated behavior.

A short count or a non-advancing element is treated as an error. `Unwanted`
maps to `IllegalValue` so an enclosing choice cannot interpret an inner
malformed count as "not my header". Zero-width elements are rejected
explicitly.
```
`validate()` on the owned types checks what the RFCs constrain: the type
matches the message, groups are multicast (or unspecified in a General
Query, §5.1.5), sources are unicast (§5.1.11, §5.2.9) with `::`
excluded per RFC 4291 §2.5.2, and a General Query carries no sources at all
(§5.1.13). Loopback stays admissible, as rejecting it is forwarding policy.
@zeeshanlakhani zeeshanlakhani changed the title Zl/mld MLD support Aug 31, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant