|
@@ -74,14 +74,7 @@ impl Interface {
|
|
|
#[cfg(feature = "proto-ipv6")]
|
|
|
IpAddress::Ipv6(addr) => {
|
|
|
// Build report packet containing this new address
|
|
|
- let initial_report_record: &[MldAddressRecordRepr] = &[MldAddressRecordRepr {
|
|
|
- num_srcs: 0,
|
|
|
- mcast_addr: addr,
|
|
|
- record_type: MldRecordType::ChangeToInclude,
|
|
|
- aux_data_len: 0,
|
|
|
- payload: &[],
|
|
|
- }];
|
|
|
-
|
|
|
+ let report_record = &[MldAddressRecordRepr::new(MldRecordType::ChangeToInclude, addr)];
|
|
|
let is_not_new = self
|
|
|
.inner
|
|
|
.ipv6_multicast_groups
|
|
@@ -90,7 +83,7 @@ impl Interface {
|
|
|
.is_some();
|
|
|
if is_not_new {
|
|
|
Ok(false)
|
|
|
- } else if let Some(pkt) = self.inner.mldv2_report_packet(initial_report_record) {
|
|
|
+ } else if let Some(pkt) = self.inner.mldv2_report_packet(report_record) {
|
|
|
// Send initial membership report
|
|
|
let tx_token = device
|
|
|
.transmit(timestamp)
|
|
@@ -147,9 +140,30 @@ impl Interface {
|
|
|
Ok(false)
|
|
|
}
|
|
|
}
|
|
|
- // Multicast is not yet implemented for other address families
|
|
|
+ #[cfg(feature = "proto-ipv6")]
|
|
|
+ IpAddress::Ipv6(addr) => {
|
|
|
+ let report_record = &[MldAddressRecordRepr::new(MldRecordType::ChangeToExclude, addr)];
|
|
|
+ let was_not_present = self.inner.ipv6_multicast_groups.remove(&addr).is_none();
|
|
|
+ if was_not_present {
|
|
|
+ Ok(false)
|
|
|
+ } else if let Some(pkt) = self.inner.mldv2_report_packet(report_record) {
|
|
|
+ // Send group leave packet
|
|
|
+ let tx_token = device
|
|
|
+ .transmit(timestamp)
|
|
|
+ .ok_or(MulticastError::Exhausted)?;
|
|
|
+
|
|
|
+ // NOTE(unwrap): packet destination is multicast, which is always routable and doesn't require neighbor discovery.
|
|
|
+ self.inner
|
|
|
+ .dispatch_ip(tx_token, PacketMeta::default(), pkt, &mut self.fragmenter)
|
|
|
+ .unwrap();
|
|
|
+
|
|
|
+ Ok(true)
|
|
|
+ } else {
|
|
|
+ Ok(false)
|
|
|
+ }
|
|
|
+ }
|
|
|
#[allow(unreachable_patterns)]
|
|
|
- _ => Err(MulticastError::Ipv6NotSupported),
|
|
|
+ _ => Err(MulticastError::Unaddressable),
|
|
|
}
|
|
|
}
|
|
|
|