Instead of eagerly sending the join/leave packet when the user calls join/leave,
we update internal state and send the packet when the interface is polled.
Advantages:
- If the device is exhausted, the packet gets sent later instead of just failing and returning an error to the user.
- Makes the API consistent with everything else in smoltcp: operations only update internal state, poll is what sends/receives packets.
- Enables wrappers to offer simpler APIs with less generics. See https://github.com/embassy-rs/embassy/pull/3329 for an example, which is my original motivation.
This patch rebases @jgallagher's to the tip of the main branch,
adding support for IPv6 multicast groups. As in the original PR,
it is only possible to join groups by sending an initial MLDv2
Report packet. It is not yet possible to resend the change report,
leave groups, respond to queries, etc.
Prevent panic when no suitable source address is found. If no suitable
address is found, the loopback address is used instead. The function can
still panic when the destination address is unspecified.
More tests are added:
- Tests when the interface has no addresses. The loopback address is
used as source address.
- Tests when the interface only has a link-local address. The link-local
address is used as source address, unless the destination address is
the loopback address. In this case, the loopback address is used as
source address.
Splitting the accept and process functions into separate functions for
IPv4 and IPv6 allows us to avoid the `IpRepr` enum and instead use the
`Ipv4Repr` and `Ipv6Repr` structs directly. This reduces the binary size
by 1.5 KiB.
RFC6724 defines how the source address should be selected when given a
destination address. Instead of selecting the first address in the list
of interface addresses, the source address is selected following the
standard.
Lookup is O(n) now. However, it previously did 32 (or 128 for ipv6!)
map lookups. Since the route table typically doesn't have that many
routes, the new code is likely faster even if it's O(n).
The current `'a` lifetime in the `Device` trait is essentially a workaround for lack of GATs.
I'm just experimenting how this would look like, it'll have to wait until GATs are stable to go in.
The main benefit is structs implementing `Device` can now borrow stuff. This wasn't possible
before because the `for<'d> T: Device<'d>` bounds would essentially imply `T: 'static`.
634: IPv4 fragmentation (for outgoing) r=Dirbaio a=thvdveld
Almost ready for review, just need to clean up some things 🎉
Co-authored-by: Thibaut Vandervelden <thvdveld@vub.be>