iface: use heapless LinearMap for ipv4_multicast_groups

This commit is contained in:
Dario Nieuwenhuis 2022-12-23 18:23:06 +01:00
parent d9f5b4b3c2
commit 94a52d8baf
3 changed files with 18 additions and 22 deletions

View File

@ -35,12 +35,10 @@ fn main() {
let ip_addr = IpCidr::new(IpAddress::from(local_addr), 24); let ip_addr = IpCidr::new(IpAddress::from(local_addr), 24);
let mut ip_addrs = heapless::Vec::<IpCidr, 5>::new(); let mut ip_addrs = heapless::Vec::<IpCidr, 5>::new();
ip_addrs.push(ip_addr).unwrap(); ip_addrs.push(ip_addr).unwrap();
let mut ipv4_multicast_storage = [None; 1];
let mut iface = InterfaceBuilder::new() let mut iface = InterfaceBuilder::new()
.hardware_addr(ethernet_addr.into()) .hardware_addr(ethernet_addr.into())
.neighbor_cache(neighbor_cache) .neighbor_cache(neighbor_cache)
.ip_addrs(ip_addrs) .ip_addrs(ip_addrs)
.ipv4_multicast_groups(&mut ipv4_multicast_storage[..])
.finalize(&mut device); .finalize(&mut device);
let now = Instant::now(); let now = Instant::now();

View File

@ -17,8 +17,8 @@ mod ipv6;
use core::cmp; use core::cmp;
use core::marker::PhantomData; use core::marker::PhantomData;
use heapless::Vec; use heapless::{LinearMap, Vec};
use managed::{ManagedMap, ManagedSlice}; use managed::ManagedSlice;
#[cfg(any(feature = "proto-ipv4", feature = "proto-sixlowpan"))] #[cfg(any(feature = "proto-ipv4", feature = "proto-sixlowpan"))]
use super::fragmentation::PacketAssemblerSet; use super::fragmentation::PacketAssemblerSet;
@ -35,7 +35,9 @@ use crate::time::{Duration, Instant};
use crate::wire::*; use crate::wire::*;
use crate::{Error, Result}; use crate::{Error, Result};
const MAX_IP_ADDRS_NUM: usize = 5; const MAX_IP_ADDR_COUNT: usize = 5;
#[cfg(feature = "proto-igmp")]
const MAX_IPV4_MULTICAST_GROUPS: usize = 4;
pub(crate) struct FragmentsBuffer<'a> { pub(crate) struct FragmentsBuffer<'a> {
#[cfg(feature = "proto-ipv4-fragmentation")] #[cfg(feature = "proto-ipv4-fragmentation")]
@ -275,12 +277,12 @@ pub struct InterfaceInner<'a> {
sixlowpan_address_context: &'a [SixlowpanAddressContext<'a>], sixlowpan_address_context: &'a [SixlowpanAddressContext<'a>],
#[cfg(feature = "proto-sixlowpan-fragmentation")] #[cfg(feature = "proto-sixlowpan-fragmentation")]
tag: u16, tag: u16,
ip_addrs: Vec<IpCidr, MAX_IP_ADDRS_NUM>, ip_addrs: Vec<IpCidr, MAX_IP_ADDR_COUNT>,
#[cfg(feature = "proto-ipv4")] #[cfg(feature = "proto-ipv4")]
any_ip: bool, any_ip: bool,
routes: Routes, routes: Routes,
#[cfg(feature = "proto-igmp")] #[cfg(feature = "proto-igmp")]
ipv4_multicast_groups: ManagedMap<'a, Ipv4Address, ()>, ipv4_multicast_groups: LinearMap<Ipv4Address, (), MAX_IPV4_MULTICAST_GROUPS>,
/// When to report for (all or) the next multicast group membership via IGMP /// When to report for (all or) the next multicast group membership via IGMP
#[cfg(feature = "proto-igmp")] #[cfg(feature = "proto-igmp")]
igmp_report_state: IgmpReportState, igmp_report_state: IgmpReportState,
@ -296,13 +298,13 @@ pub struct InterfaceBuilder<'a> {
neighbor_cache: Option<NeighborCache>, neighbor_cache: Option<NeighborCache>,
#[cfg(feature = "medium-ieee802154")] #[cfg(feature = "medium-ieee802154")]
pan_id: Option<Ieee802154Pan>, pan_id: Option<Ieee802154Pan>,
ip_addrs: Vec<IpCidr, MAX_IP_ADDRS_NUM>, ip_addrs: Vec<IpCidr, MAX_IP_ADDR_COUNT>,
#[cfg(feature = "proto-ipv4")] #[cfg(feature = "proto-ipv4")]
any_ip: bool, any_ip: bool,
routes: Routes, routes: Routes,
/// Does not share storage with `ipv6_multicast_groups` to avoid IPv6 size overhead. /// Does not share storage with `ipv6_multicast_groups` to avoid IPv6 size overhead.
#[cfg(feature = "proto-igmp")] #[cfg(feature = "proto-igmp")]
ipv4_multicast_groups: ManagedMap<'a, Ipv4Address, ()>, ipv4_multicast_groups: LinearMap<Ipv4Address, (), MAX_IPV4_MULTICAST_GROUPS>,
random_seed: u64, random_seed: u64,
#[cfg(feature = "proto-ipv4-fragmentation")] #[cfg(feature = "proto-ipv4-fragmentation")]
@ -380,7 +382,7 @@ let iface = builder.finalize(&mut device);
any_ip: false, any_ip: false,
routes: Routes::new(), routes: Routes::new(),
#[cfg(feature = "proto-igmp")] #[cfg(feature = "proto-igmp")]
ipv4_multicast_groups: ManagedMap::Borrowed(&mut []), ipv4_multicast_groups: LinearMap::new(),
random_seed: 0, random_seed: 0,
#[cfg(feature = "proto-ipv4-fragmentation")] #[cfg(feature = "proto-ipv4-fragmentation")]
@ -443,7 +445,7 @@ let iface = builder.finalize(&mut device);
/// [ip_addrs]: struct.Interface.html#method.ip_addrs /// [ip_addrs]: struct.Interface.html#method.ip_addrs
pub fn ip_addrs<T>(mut self, ip_addrs: T) -> Self pub fn ip_addrs<T>(mut self, ip_addrs: T) -> Self
where where
T: Into<Vec<IpCidr, MAX_IP_ADDRS_NUM>>, T: Into<Vec<IpCidr, MAX_IP_ADDR_COUNT>>,
{ {
let ip_addrs = ip_addrs.into(); let ip_addrs = ip_addrs.into();
InterfaceInner::check_ip_addrs(&ip_addrs); InterfaceInner::check_ip_addrs(&ip_addrs);
@ -495,7 +497,7 @@ let iface = builder.finalize(&mut device);
#[cfg(feature = "proto-igmp")] #[cfg(feature = "proto-igmp")]
pub fn ipv4_multicast_groups<T>(mut self, ipv4_multicast_groups: T) -> Self pub fn ipv4_multicast_groups<T>(mut self, ipv4_multicast_groups: T) -> Self
where where
T: Into<ManagedMap<'a, Ipv4Address, ()>>, T: Into<LinearMap<Ipv4Address, (), MAX_IPV4_MULTICAST_GROUPS>>,
{ {
self.ipv4_multicast_groups = ipv4_multicast_groups.into(); self.ipv4_multicast_groups = ipv4_multicast_groups.into();
self self
@ -1014,7 +1016,7 @@ impl<'a> Interface<'a> {
/// ///
/// # Panics /// # Panics
/// This function panics if any of the addresses are not unicast. /// This function panics if any of the addresses are not unicast.
pub fn update_ip_addrs<F: FnOnce(&mut Vec<IpCidr, MAX_IP_ADDRS_NUM>)>(&mut self, f: F) { pub fn update_ip_addrs<F: FnOnce(&mut Vec<IpCidr, MAX_IP_ADDR_COUNT>)>(&mut self, f: F) {
f(&mut self.inner.ip_addrs); f(&mut self.inner.ip_addrs);
InterfaceInner::flush_cache(&mut self.inner); InterfaceInner::flush_cache(&mut self.inner);
InterfaceInner::check_ip_addrs(&self.inner.ip_addrs) InterfaceInner::check_ip_addrs(&self.inner.ip_addrs)
@ -1615,7 +1617,7 @@ impl<'a> InterfaceInner<'a> {
#[cfg(feature = "proto-igmp")] #[cfg(feature = "proto-igmp")]
igmp_report_state: IgmpReportState::Inactive, igmp_report_state: IgmpReportState::Inactive,
#[cfg(feature = "proto-igmp")] #[cfg(feature = "proto-igmp")]
ipv4_multicast_groups: ManagedMap::Borrowed(&mut []), ipv4_multicast_groups: LinearMap::new(),
} }
} }

View File

@ -42,7 +42,7 @@ fn create<'a>(medium: Medium) -> (Interface<'a>, SocketSet<'a>, Loopback) {
fn create_ip<'a>() -> (Interface<'a>, SocketSet<'a>, Loopback) { fn create_ip<'a>() -> (Interface<'a>, SocketSet<'a>, Loopback) {
// Create a basic device // Create a basic device
let mut device = Loopback::new(Medium::Ip); let mut device = Loopback::new(Medium::Ip);
let mut ip_addrs = heapless::Vec::<IpCidr, MAX_IP_ADDRS_NUM>::new(); let mut ip_addrs = heapless::Vec::<IpCidr, MAX_IP_ADDR_COUNT>::new();
#[cfg(feature = "proto-ipv4")] #[cfg(feature = "proto-ipv4")]
ip_addrs ip_addrs
.push(IpCidr::new(IpAddress::v4(127, 0, 0, 1), 8)) .push(IpCidr::new(IpAddress::v4(127, 0, 0, 1), 8))
@ -63,8 +63,6 @@ fn create_ip<'a>() -> (Interface<'a>, SocketSet<'a>, Loopback) {
.ipv4_reassembly_buffer(PacketAssemblerSet::new(vec![], BTreeMap::new())) .ipv4_reassembly_buffer(PacketAssemblerSet::new(vec![], BTreeMap::new()))
.ipv4_fragmentation_buffer(vec![]); .ipv4_fragmentation_buffer(vec![]);
#[cfg(feature = "proto-igmp")]
let iface_builder = iface_builder.ipv4_multicast_groups(BTreeMap::new());
let iface = iface_builder.finalize(&mut device); let iface = iface_builder.finalize(&mut device);
(iface, SocketSet::new(vec![]), device) (iface, SocketSet::new(vec![]), device)
@ -74,7 +72,7 @@ fn create_ip<'a>() -> (Interface<'a>, SocketSet<'a>, Loopback) {
fn create_ethernet<'a>() -> (Interface<'a>, SocketSet<'a>, Loopback) { fn create_ethernet<'a>() -> (Interface<'a>, SocketSet<'a>, Loopback) {
// Create a basic device // Create a basic device
let mut device = Loopback::new(Medium::Ethernet); let mut device = Loopback::new(Medium::Ethernet);
let mut ip_addrs = heapless::Vec::<IpCidr, MAX_IP_ADDRS_NUM>::new(); let mut ip_addrs = heapless::Vec::<IpCidr, MAX_IP_ADDR_COUNT>::new();
#[cfg(feature = "proto-ipv4")] #[cfg(feature = "proto-ipv4")]
ip_addrs ip_addrs
.push(IpCidr::new(IpAddress::v4(127, 0, 0, 1), 8)) .push(IpCidr::new(IpAddress::v4(127, 0, 0, 1), 8))
@ -103,8 +101,6 @@ fn create_ethernet<'a>() -> (Interface<'a>, SocketSet<'a>, Loopback) {
.ipv4_reassembly_buffer(PacketAssemblerSet::new(vec![], BTreeMap::new())) .ipv4_reassembly_buffer(PacketAssemblerSet::new(vec![], BTreeMap::new()))
.ipv4_fragmentation_buffer(vec![]); .ipv4_fragmentation_buffer(vec![]);
#[cfg(feature = "proto-igmp")]
let iface_builder = iface_builder.ipv4_multicast_groups(BTreeMap::new());
let iface = iface_builder.finalize(&mut device); let iface = iface_builder.finalize(&mut device);
(iface, SocketSet::new(vec![]), device) (iface, SocketSet::new(vec![]), device)
@ -114,7 +110,7 @@ fn create_ethernet<'a>() -> (Interface<'a>, SocketSet<'a>, Loopback) {
fn create_ieee802154<'a>() -> (Interface<'a>, SocketSet<'a>, Loopback) { fn create_ieee802154<'a>() -> (Interface<'a>, SocketSet<'a>, Loopback) {
// Create a basic device // Create a basic device
let mut device = Loopback::new(Medium::Ieee802154); let mut device = Loopback::new(Medium::Ieee802154);
let mut ip_addrs = heapless::Vec::<IpCidr, MAX_IP_ADDRS_NUM>::new(); let mut ip_addrs = heapless::Vec::<IpCidr, MAX_IP_ADDR_COUNT>::new();
#[cfg(feature = "proto-ipv6")] #[cfg(feature = "proto-ipv6")]
ip_addrs ip_addrs
.push(IpCidr::new(IpAddress::v6(0, 0, 0, 0, 0, 0, 0, 1), 128)) .push(IpCidr::new(IpAddress::v6(0, 0, 0, 0, 0, 0, 0, 1), 128))
@ -1063,7 +1059,7 @@ fn test_icmpv4_socket() {
#[cfg(feature = "proto-ipv6")] #[cfg(feature = "proto-ipv6")]
fn test_solicited_node_addrs() { fn test_solicited_node_addrs() {
let (mut iface, _, _device) = create(MEDIUM); let (mut iface, _, _device) = create(MEDIUM);
let mut new_addrs = heapless::Vec::<IpCidr, MAX_IP_ADDRS_NUM>::new(); let mut new_addrs = heapless::Vec::<IpCidr, MAX_IP_ADDR_COUNT>::new();
new_addrs new_addrs
.push(IpCidr::new(IpAddress::v6(0xfe80, 0, 0, 0, 1, 2, 0, 2), 64)) .push(IpCidr::new(IpAddress::v6(0xfe80, 0, 0, 0, 1, 2, 0, 2), 64))
.unwrap(); .unwrap();