Don't use Option for neighbor cache anymore

This commit is contained in:
Thibaut Vandervelden 2023-02-08 11:36:54 +01:00 committed by Dario Nieuwenhuis
parent 4aaab35b36
commit 099f5f7c2a
19 changed files with 192 additions and 164 deletions

View File

@ -88,11 +88,14 @@ fn main() {
let tcp2_tx_buffer = tcp::SocketBuffer::new(vec![0; 65535]);
let tcp2_socket = tcp::Socket::new(tcp2_rx_buffer, tcp2_tx_buffer);
let mut config = Config::new();
let mut config = match device.capabilities().medium {
Medium::Ethernet => {
Config::new(EthernetAddress([0x02, 0x00, 0x00, 0x00, 0x00, 0x01]).into())
}
Medium::Ip => Config::new(smoltcp::wire::HardwareAddress::Ip),
Medium::Ieee802154 => todo!(),
};
config.random_seed = rand::random();
if device.capabilities().medium == Medium::Ethernet {
config.hardware_addr = Some(EthernetAddress([0x02, 0x00, 0x00, 0x00, 0x00, 0x01]).into());
}
let mut iface = Interface::new(config, &mut device);
iface.update_ip_addrs(|ip_addrs| {

View File

@ -29,11 +29,14 @@ fn main() {
let port = u16::from_str(&matches.free[1]).expect("invalid port format");
// Create interface
let mut config = Config::new();
let mut config = match device.capabilities().medium {
Medium::Ethernet => {
Config::new(EthernetAddress([0x02, 0x00, 0x00, 0x00, 0x00, 0x01]).into())
}
Medium::Ip => Config::new(smoltcp::wire::HardwareAddress::Ip),
Medium::Ieee802154 => todo!(),
};
config.random_seed = rand::random();
if device.capabilities().medium == Medium::Ethernet {
config.hardware_addr = Some(EthernetAddress([0x02, 0x00, 0x00, 0x00, 0x00, 0x01]).into());
}
let mut iface = Interface::new(config, &mut device);
iface.update_ip_addrs(|ip_addrs| {

View File

@ -28,11 +28,14 @@ fn main() {
utils::parse_middleware_options(&mut matches, device, /*loopback=*/ false);
// Create interface
let mut config = Config::new();
let mut config = match device.capabilities().medium {
Medium::Ethernet => {
Config::new(EthernetAddress([0x02, 0x00, 0x00, 0x00, 0x00, 0x01]).into())
}
Medium::Ip => Config::new(smoltcp::wire::HardwareAddress::Ip),
Medium::Ieee802154 => todo!(),
};
config.random_seed = rand::random();
if device.capabilities().medium == Medium::Ethernet {
config.hardware_addr = Some(EthernetAddress([0x02, 0x00, 0x00, 0x00, 0x00, 0x01]).into());
}
let mut iface = Interface::new(config, &mut device);
// Create sockets

View File

@ -24,11 +24,14 @@ fn main() {
let name = &matches.free[0];
// Create interface
let mut config = Config::new();
let mut config = match device.capabilities().medium {
Medium::Ethernet => {
Config::new(EthernetAddress([0x02, 0x00, 0x00, 0x00, 0x00, 0x01]).into())
}
Medium::Ip => Config::new(smoltcp::wire::HardwareAddress::Ip),
Medium::Ieee802154 => todo!(),
};
config.random_seed = rand::random();
if device.capabilities().medium == Medium::Ethernet {
config.hardware_addr = Some(EthernetAddress([0x02, 0x00, 0x00, 0x00, 0x00, 0x01]).into());
}
let mut iface = Interface::new(config, &mut device);
iface.update_ip_addrs(|ip_addrs| {

View File

@ -29,11 +29,14 @@ fn main() {
let url = Url::parse(&matches.free[1]).expect("invalid url format");
// Create interface
let mut config = Config::new();
let mut config = match device.capabilities().medium {
Medium::Ethernet => {
Config::new(EthernetAddress([0x02, 0x00, 0x00, 0x00, 0x00, 0x01]).into())
}
Medium::Ip => Config::new(smoltcp::wire::HardwareAddress::Ip),
Medium::Ieee802154 => todo!(),
};
config.random_seed = rand::random();
if device.capabilities().medium == Medium::Ethernet {
config.hardware_addr = Some(EthernetAddress([0x02, 0x00, 0x00, 0x00, 0x00, 0x01]).into());
}
let mut iface = Interface::new(config, &mut device);
iface.update_ip_addrs(|ip_addrs| {

View File

@ -10,7 +10,7 @@ use core::str;
use log::{debug, error, info};
use smoltcp::iface::{Config, Interface, SocketSet};
use smoltcp::phy::{Loopback, Medium};
use smoltcp::phy::{Device, Loopback, Medium};
use smoltcp::socket::tcp;
use smoltcp::time::{Duration, Instant};
use smoltcp::wire::{EthernetAddress, IpAddress, IpCidr};
@ -83,8 +83,13 @@ fn main() {
};
// Create interface
let mut config = Config::new();
config.hardware_addr = Some(EthernetAddress([0x02, 0x00, 0x00, 0x00, 0x00, 0x01]).into());
let mut config = match device.capabilities().medium {
Medium::Ethernet => {
Config::new(EthernetAddress([0x02, 0x00, 0x00, 0x00, 0x00, 0x01]).into())
}
Medium::Ip => Config::new(smoltcp::wire::HardwareAddress::Ip),
Medium::Ieee802154 => todo!(),
};
let mut iface = Interface::new(config, &mut device);
iface.update_ip_addrs(|ip_addrs| {

View File

@ -28,11 +28,14 @@ fn main() {
utils::parse_middleware_options(&mut matches, device, /*loopback=*/ false);
// Create interface
let mut config = Config::new();
let mut config = match device.capabilities().medium {
Medium::Ethernet => {
Config::new(EthernetAddress([0x02, 0x00, 0x00, 0x00, 0x00, 0x01]).into())
}
Medium::Ip => Config::new(smoltcp::wire::HardwareAddress::Ip),
Medium::Ieee802154 => todo!(),
};
config.random_seed = rand::random();
if device.capabilities().medium == Medium::Ethernet {
config.hardware_addr = Some(EthernetAddress([0x02, 0x00, 0x00, 0x00, 0x00, 0x01]).into());
}
let mut iface = Interface::new(config, &mut device);
iface.update_ip_addrs(|ip_addrs| {

View File

@ -105,11 +105,14 @@ fn main() {
);
// Create interface
let mut config = Config::new();
let mut config = match device.capabilities().medium {
Medium::Ethernet => {
Config::new(EthernetAddress([0x02, 0x00, 0x00, 0x00, 0x00, 0x01]).into())
}
Medium::Ip => Config::new(smoltcp::wire::HardwareAddress::Ip),
Medium::Ieee802154 => todo!(),
};
config.random_seed = rand::random();
if device.capabilities().medium == Medium::Ethernet {
config.hardware_addr = Some(EthernetAddress([0x02, 0x00, 0x00, 0x00, 0x00, 0x01]).into());
}
let mut iface = Interface::new(config, &mut device);
iface.update_ip_addrs(|ip_addrs| {

View File

@ -24,11 +24,15 @@ fn main() {
utils::parse_middleware_options(&mut matches, device, /*loopback=*/ false);
// Create interface
let mut config = Config::new();
let mut config = match device.capabilities().medium {
Medium::Ethernet => {
Config::new(EthernetAddress([0x02, 0x00, 0x00, 0x00, 0x00, 0x01]).into())
}
Medium::Ip => Config::new(smoltcp::wire::HardwareAddress::Ip),
Medium::Ieee802154 => todo!(),
};
config.random_seed = rand::random();
if device.capabilities().medium == Medium::Ethernet {
config.hardware_addr = Some(EthernetAddress([0x02, 0x00, 0x00, 0x00, 0x00, 0x01]).into());
}
let mut iface = Interface::new(config, &mut device);
iface.update_ip_addrs(|ip_addrs| {

View File

@ -47,11 +47,11 @@ use std::os::unix::io::AsRawFd;
use std::str;
use smoltcp::iface::{Config, Interface, SocketSet};
use smoltcp::phy::{wait as phy_wait, Medium, RawSocket};
use smoltcp::phy::{wait as phy_wait, Device, Medium, RawSocket};
use smoltcp::socket::tcp;
use smoltcp::socket::udp;
use smoltcp::time::Instant;
use smoltcp::wire::{Ieee802154Address, Ieee802154Pan, IpAddress, IpCidr};
use smoltcp::wire::{EthernetAddress, Ieee802154Address, Ieee802154Pan, IpAddress, IpCidr};
fn main() {
utils::setup_logging("");
@ -67,10 +67,16 @@ fn main() {
utils::parse_middleware_options(&mut matches, device, /*loopback=*/ false);
// Create interface
let mut config = Config::new();
let mut config = match device.capabilities().medium {
Medium::Ethernet => {
Config::new(EthernetAddress([0x02, 0x00, 0x00, 0x00, 0x00, 0x01]).into())
}
Medium::Ip => Config::new(smoltcp::wire::HardwareAddress::Ip),
Medium::Ieee802154 => Config::new(
Ieee802154Address::Extended([0x1a, 0x0b, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42]).into(),
),
};
config.random_seed = rand::random();
config.hardware_addr =
Some(Ieee802154Address::Extended([0x1a, 0x0b, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42]).into());
config.pan_id = Some(Ieee802154Pan(0xbeef));
let mut iface = Interface::new(config, &mut device);

View File

@ -47,9 +47,9 @@ use std::os::unix::io::AsRawFd;
use std::str;
use smoltcp::iface::{Config, Interface, SocketSet};
use smoltcp::phy::{wait as phy_wait, Medium, RawSocket};
use smoltcp::phy::{wait as phy_wait, Device, Medium, RawSocket};
use smoltcp::socket::tcp;
use smoltcp::wire::{Ieee802154Address, Ieee802154Pan, IpAddress, IpCidr};
use smoltcp::wire::{EthernetAddress, Ieee802154Address, Ieee802154Pan, IpAddress, IpCidr};
//For benchmark
use smoltcp::time::{Duration, Instant};
@ -147,10 +147,16 @@ fn main() {
};
// Create interface
let mut config = Config::new();
let mut config = match device.capabilities().medium {
Medium::Ethernet => {
Config::new(EthernetAddress([0x02, 0x00, 0x00, 0x00, 0x00, 0x01]).into())
}
Medium::Ip => Config::new(smoltcp::wire::HardwareAddress::Ip),
Medium::Ieee802154 => Config::new(
Ieee802154Address::Extended([0x1a, 0x0b, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42]).into(),
),
};
config.random_seed = rand::random();
config.hardware_addr =
Some(Ieee802154Address::Extended([0x1a, 0x0b, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42]).into());
config.pan_id = Some(Ieee802154Pan(0xbeef));
let mut iface = Interface::new(config, &mut device);

View File

@ -22,7 +22,7 @@ impl InterfaceInner {
// Ignore any packets not directed to our hardware address or any of the multicast groups.
if !eth_frame.dst_addr().is_broadcast()
&& !eth_frame.dst_addr().is_multicast()
&& HardwareAddress::Ethernet(eth_frame.dst_addr()) != self.hardware_addr.unwrap()
&& HardwareAddress::Ethernet(eth_frame.dst_addr()) != self.hardware_addr
{
return None;
}
@ -64,7 +64,7 @@ impl InterfaceInner {
debug_assert!(tx_buffer.as_ref().len() == tx_len);
let mut frame = EthernetFrame::new_unchecked(tx_buffer);
let src_addr = self.hardware_addr.unwrap().ethernet_or_panic();
let src_addr = self.hardware_addr.ethernet_or_panic();
frame.set_src_addr(src_addr);
f(frame);

View File

@ -44,7 +44,7 @@ impl InterfaceInner {
packet: IpPacket,
frag: &mut Fragmenter,
) {
let ll_src_a = self.hardware_addr.unwrap().ieee802154_or_panic();
let ll_src_a = self.hardware_addr.ieee802154_or_panic();
// Create the IEEE802.15.4 header.
let ieee_repr = Ieee802154Repr {

View File

@ -74,7 +74,9 @@ impl InterfaceInner {
#[cfg(feature = "socket-dhcpv4")]
{
if ipv4_repr.next_header == IpProtocol::Udp && self.hardware_addr.is_some() {
if ipv4_repr.next_header == IpProtocol::Udp
&& matches!(self.caps.medium, Medium::Ethernet)
{
let udp_packet = check!(UdpPacket::new_checked(ip_payload));
if let Some(dhcp_socket) = sockets
.items_mut()
@ -206,17 +208,14 @@ impl InterfaceInner {
// We fill from requests too because if someone is requesting our address they
// are probably going to talk to us, so we avoid having to request their address
// when we later reply to them.
self.neighbor_cache.as_mut().unwrap().fill(
self.neighbor_cache.fill(
source_protocol_addr.into(),
source_hardware_addr.into(),
timestamp,
);
if operation == ArpOperation::Request {
let src_hardware_addr = match self.hardware_addr {
Some(HardwareAddress::Ethernet(addr)) => addr,
_ => unreachable!(),
};
let src_hardware_addr = self.hardware_addr.ethernet_or_panic();
Some(EthernetPacket::Arp(ArpRepr::EthernetIpv4 {
operation: ArpOperation::Reply,
@ -352,7 +351,7 @@ impl InterfaceInner {
let emit_ethernet = |repr: &IpRepr, tx_buffer: &mut [u8]| {
let mut frame = EthernetFrame::new_unchecked(tx_buffer);
let src_addr = self.hardware_addr.unwrap().ethernet_or_panic();
let src_addr = self.hardware_addr.ethernet_or_panic();
frame.set_src_addr(src_addr);
frame.set_dst_addr(frag.ipv4.dst_hardware_addr);

View File

@ -192,17 +192,9 @@ impl InterfaceInner {
return None;
}
if flags.contains(NdiscNeighborFlags::OVERRIDE)
|| !self
.neighbor_cache
.as_mut()
.unwrap()
.lookup(&ip_addr, self.now)
.found()
|| !self.neighbor_cache.lookup(&ip_addr, self.now).found()
{
self.neighbor_cache
.as_mut()
.unwrap()
.fill(ip_addr, lladdr, self.now)
self.neighbor_cache.fill(ip_addr, lladdr, self.now)
}
}
None
@ -217,11 +209,8 @@ impl InterfaceInner {
if !lladdr.is_unicast() || !target_addr.is_unicast() {
return None;
}
self.neighbor_cache.as_mut().unwrap().fill(
ip_repr.src_addr.into(),
lladdr,
self.now,
);
self.neighbor_cache
.fill(ip_repr.src_addr.into(), lladdr, self.now);
}
if self.has_solicited_node(ip_repr.dst_addr) && self.has_ip_addr(target_addr) {
@ -229,7 +218,7 @@ impl InterfaceInner {
flags: NdiscNeighborFlags::SOLICITED,
target_addr,
#[cfg(any(feature = "medium-ethernet", feature = "medium-ieee802154"))]
lladdr: Some(self.hardware_addr.unwrap().into()),
lladdr: Some(self.hardware_addr.into()),
});
let ip_repr = Ipv6Repr {
src_addr: target_addr,

View File

@ -240,9 +240,8 @@ pub struct InterfaceInner {
rand: Rand,
#[cfg(any(feature = "medium-ethernet", feature = "medium-ieee802154"))]
neighbor_cache: Option<NeighborCache>,
#[cfg(any(feature = "medium-ethernet", feature = "medium-ieee802154"))]
hardware_addr: Option<HardwareAddress>,
neighbor_cache: NeighborCache,
hardware_addr: HardwareAddress,
#[cfg(feature = "medium-ieee802154")]
sequence_no: u8,
#[cfg(feature = "medium-ieee802154")]
@ -280,8 +279,7 @@ pub struct Config {
///
/// # Panics
/// Creating the interface panics if the address is not unicast.
#[cfg(any(feature = "medium-ethernet", feature = "medium-ieee802154"))]
pub hardware_addr: Option<HardwareAddress>,
pub hardware_addr: HardwareAddress,
/// Set the IEEE802.15.4 PAN ID the interface will use.
///
@ -291,23 +289,16 @@ pub struct Config {
}
impl Config {
pub fn new() -> Self {
pub fn new(hardware_addr: HardwareAddress) -> Self {
Config {
random_seed: 0,
#[cfg(any(feature = "medium-ethernet", feature = "medium-ieee802154"))]
hardware_addr: None,
hardware_addr,
#[cfg(feature = "medium-ieee802154")]
pan_id: None,
}
}
}
impl Default for Config {
fn default() -> Self {
Self::new()
}
}
#[derive(Debug, PartialEq)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
#[cfg(feature = "medium-ethernet")]
@ -476,29 +467,11 @@ impl Interface {
{
let caps = device.capabilities();
#[cfg(any(feature = "medium-ethernet", feature = "medium-ieee802154"))]
let hardware_addr = match caps.medium {
#[cfg(feature = "medium-ethernet")]
Medium::Ethernet => Some(
config
.hardware_addr
.expect("hardware_addr required option was not set"),
),
#[cfg(feature = "medium-ip")]
Medium::Ip => {
assert!(
config.hardware_addr.is_none(),
"hardware_addr is set, but device medium is IP"
);
None
}
#[cfg(feature = "medium-ieee802154")]
Medium::Ieee802154 => Some(
config
.hardware_addr
.expect("hardware_addr required option was not set"),
),
};
assert_eq!(
config.hardware_addr.medium(),
caps.medium,
"The hardware address does not match the medium of the interface."
);
let mut rand = Rand::new(config.random_seed);
@ -548,14 +521,13 @@ impl Interface {
inner: InterfaceInner {
now: Instant::from_secs(0),
caps,
#[cfg(any(feature = "medium-ethernet", feature = "medium-ieee802154"))]
hardware_addr,
hardware_addr: config.hardware_addr,
ip_addrs: Vec::new(),
#[cfg(feature = "proto-ipv4")]
any_ip: false,
routes: Routes::new(),
#[cfg(any(feature = "medium-ethernet", feature = "medium-ieee802154"))]
neighbor_cache: Some(NeighborCache::new()),
neighbor_cache: NeighborCache::new(),
#[cfg(feature = "proto-igmp")]
ipv4_multicast_groups: LinearMap::new(),
#[cfg(feature = "proto-igmp")]
@ -599,7 +571,7 @@ impl Interface {
|| self.inner.caps.medium == Medium::Ieee802154
);
self.inner.hardware_addr.unwrap()
self.inner.hardware_addr
}
/// Set the HardwareAddress address of the interface.
@ -621,7 +593,7 @@ impl Interface {
);
InterfaceInner::check_hardware_addr(&addr);
self.inner.hardware_addr = Some(addr);
self.inner.hardware_addr = addr;
}
/// Get the IP addresses of the interface.
@ -1050,7 +1022,7 @@ impl InterfaceInner {
#[cfg(any(feature = "medium-ethernet", feature = "medium-ieee802154"))]
#[allow(unused)] // unused depending on which sockets are enabled
pub(crate) fn hardware_addr(&self) -> Option<HardwareAddress> {
pub(crate) fn hardware_addr(&self) -> HardwareAddress {
self.hardware_addr
}
@ -1169,19 +1141,31 @@ impl InterfaceInner {
#[cfg(feature = "proto-ipv4-fragmentation")]
ipv4_id: 1,
#[cfg(all(
feature = "medium-ip",
not(feature = "medium-ethernet"),
not(feature = "medium-ieee802154")
))]
hardware_addr: crate::wire::HardwareAddress::Ip,
#[cfg(feature = "medium-ethernet")]
hardware_addr: Some(crate::wire::HardwareAddress::Ethernet(
crate::wire::EthernetAddress([0x02, 0x02, 0x02, 0x02, 0x02, 0x02]),
)),
#[cfg(all(not(feature = "medium-ethernet"), feature = "medium-ieee802154"))]
hardware_addr: Some(crate::wire::HardwareAddress::Ieee802154(
hardware_addr: crate::wire::HardwareAddress::Ethernet(crate::wire::EthernetAddress([
0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
])),
#[cfg(all(
not(feature = "medium-ip"),
not(feature = "medium-ethernet"),
feature = "medium-ieee802154"
))]
hardware_addr: crate::wire::HardwareAddress::Ieee802154(
crate::wire::Ieee802154Address::Extended([
0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x2, 0x2,
]),
)),
),
#[cfg(any(feature = "medium-ethernet", feature = "medium-ieee802154"))]
neighbor_cache: None,
neighbor_cache: NeighborCache::new(),
#[cfg(feature = "proto-igmp")]
igmp_report_state: IgmpReportState::Inactive,
@ -1199,7 +1183,7 @@ impl InterfaceInner {
#[cfg(any(feature = "medium-ethernet", feature = "medium-ieee802154"))]
fn check_hardware_addr(addr: &HardwareAddress) {
if !addr.is_unicast() {
panic!("Ethernet address {addr} is not unicast")
panic!("Hardware address {addr} is not unicast")
}
}
@ -1503,19 +1487,9 @@ impl InterfaceInner {
match self.route(addr, self.now) {
Some(_routed_addr) => match self.caps.medium {
#[cfg(feature = "medium-ethernet")]
Medium::Ethernet => self
.neighbor_cache
.as_ref()
.unwrap()
.lookup(&_routed_addr, self.now)
.found(),
Medium::Ethernet => self.neighbor_cache.lookup(&_routed_addr, self.now).found(),
#[cfg(feature = "medium-ieee802154")]
Medium::Ieee802154 => self
.neighbor_cache
.as_ref()
.unwrap()
.lookup(&_routed_addr, self.now)
.found(),
Medium::Ieee802154 => self.neighbor_cache.lookup(&_routed_addr, self.now).found(),
#[cfg(feature = "medium-ip")]
Medium::Ip => true,
},
@ -1584,12 +1558,7 @@ impl InterfaceInner {
.route(dst_addr, self.now)
.ok_or(DispatchError::NoRoute)?;
match self
.neighbor_cache
.as_mut()
.unwrap()
.lookup(&dst_addr, self.now)
{
match self.neighbor_cache.lookup(&dst_addr, self.now) {
NeighborAnswer::Found(hardware_addr) => return Ok((hardware_addr, tx_token)),
NeighborAnswer::RateLimited => return Err(DispatchError::NeighborPending),
_ => (), // XXX
@ -1602,7 +1571,7 @@ impl InterfaceInner {
"address {} not in neighbor cache, sending ARP request",
dst_addr
);
let src_hardware_addr = self.hardware_addr.unwrap().ethernet_or_panic();
let src_hardware_addr = self.hardware_addr.ethernet_or_panic();
let arp_repr = ArpRepr::EthernetIpv4 {
operation: ArpOperation::Request,
@ -1634,7 +1603,7 @@ impl InterfaceInner {
let solicit = Icmpv6Repr::Ndisc(NdiscRepr::NeighborSolicit {
target_addr: dst_addr,
lladdr: Some(self.hardware_addr.unwrap().into()),
lladdr: Some(self.hardware_addr.into()),
});
let packet = IpPacket::Icmpv6((
@ -1659,15 +1628,13 @@ impl InterfaceInner {
}
// The request got dispatched, limit the rate on the cache.
self.neighbor_cache.as_mut().unwrap().limit_rate(self.now);
self.neighbor_cache.limit_rate(self.now);
Err(DispatchError::NeighborPending)
}
fn flush_cache(&mut self) {
#[cfg(any(feature = "medium-ethernet", feature = "medium-ieee802154"))]
if let Some(cache) = self.neighbor_cache.as_mut() {
cache.flush()
}
self.neighbor_cache.flush()
}
fn dispatch_ip<Tx: TxToken>(
@ -1722,8 +1689,7 @@ impl InterfaceInner {
frag,
)? {
(HardwareAddress::Ethernet(addr), tx_token) => (addr, tx_token),
#[cfg(feature = "medium-ieee802154")]
(HardwareAddress::Ieee802154(_), _) => unreachable!(),
(_, _) => unreachable!(),
}
}
_ => (EthernetAddress([0; 6]), tx_token),
@ -1734,7 +1700,7 @@ impl InterfaceInner {
let emit_ethernet = |repr: &IpRepr, tx_buffer: &mut [u8]| {
let mut frame = EthernetFrame::new_unchecked(tx_buffer);
let src_addr = self.hardware_addr.unwrap().ethernet_or_panic();
let src_addr = self.hardware_addr.ethernet_or_panic();
frame.set_src_addr(src_addr);
frame.set_dst_addr(dst_hardware_addr);

View File

@ -39,7 +39,7 @@ fn create_ip<'a>() -> (Interface, SocketSet<'a>, Loopback) {
// Create a basic device
let mut device = Loopback::new(Medium::Ip);
let mut config = Config::new();
let config = Config::new(HardwareAddress::Ip);
let mut iface = Interface::new(config, &mut device);
iface.update_ip_addrs(|ip_addrs| {
#[cfg(feature = "proto-ipv4")]
@ -64,8 +64,7 @@ fn create_ethernet<'a>() -> (Interface, SocketSet<'a>, Loopback) {
// Create a basic device
let mut device = Loopback::new(Medium::Ethernet);
let mut config = Config::new();
config.hardware_addr = Some(EthernetAddress::default().into());
let config = Config::new(HardwareAddress::Ethernet(EthernetAddress::default()));
let mut iface = Interface::new(config, &mut device);
iface.update_ip_addrs(|ip_addrs| {
#[cfg(feature = "proto-ipv4")]
@ -90,8 +89,7 @@ fn create_ieee802154<'a>() -> (Interface, SocketSet<'a>, Loopback) {
// Create a basic device
let mut device = Loopback::new(Medium::Ieee802154);
let mut config = Config::new();
config.hardware_addr = Some(Ieee802154Address::default().into());
let config = Config::new(HardwareAddress::Ieee802154(Ieee802154Address::default()));
let mut iface = Interface::new(config, &mut device);
iface.update_ip_addrs(|ip_addrs| {
#[cfg(feature = "proto-ipv6")]
@ -133,11 +131,11 @@ impl TxToken for MockTxToken {
}
#[test]
#[should_panic(expected = "hardware_addr required option was not set")]
#[cfg(all(feature = "medium-ethernet"))]
#[should_panic(expected = "The hardware address does not match the medium of the interface.")]
#[cfg(all(feature = "medium-ip", feature = "medium-ethernet"))]
fn test_new_panic() {
let mut device = Loopback::new(Medium::Ethernet);
let config = Config::new();
let config = Config::new(HardwareAddress::Ip);
Interface::new(config, &mut device);
}
@ -1377,7 +1375,7 @@ fn test_echo_request_sixlowpan_128_bytes() {
assert_eq!(iface.inner.caps.medium, Medium::Ieee802154);
let now = iface.inner.now();
iface.inner.neighbor_cache.as_mut().unwrap().fill(
iface.inner.neighbor_cache.fill(
Ipv6Address([0xfe, 0x80, 0, 0, 0, 0, 0, 0, 0x2, 0, 0, 0, 0, 0, 0, 0]).into(),
HardwareAddress::Ieee802154(Ieee802154Address::default()),
now,
@ -1503,7 +1501,7 @@ fn test_echo_request_sixlowpan_128_bytes() {
)))
);
iface.inner.neighbor_cache.as_mut().unwrap().fill(
iface.inner.neighbor_cache.fill(
IpAddress::Ipv6(Ipv6Address([
0xfe, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x40, 0x42, 0x42, 0x42, 0x42, 0x42, 0xb, 0x1a,
])),

View File

@ -317,7 +317,7 @@ impl<'a> Socket<'a> {
}
};
let Some(HardwareAddress::Ethernet(ethernet_addr)) = cx.hardware_addr() else {
let HardwareAddress::Ethernet(ethernet_addr) = cx.hardware_addr() else {
panic!("using DHCPv4 socket with a non-ethernet hardware address.");
};
@ -542,7 +542,7 @@ impl<'a> Socket<'a> {
{
// note: Dhcpv4Socket is only usable in ethernet mediums, so the
// unwrap can never fail.
let Some(HardwareAddress::Ethernet(ethernet_addr)) = cx.hardware_addr() else {
let HardwareAddress::Ethernet(ethernet_addr) = cx.hardware_addr() else {
panic!("using DHCPv4 socket with a non-ethernet hardware address.");
};

View File

@ -275,20 +275,32 @@ impl fmt::Display for Error {
pub type Result<T> = core::result::Result<T, Error>;
/// Representation of an hardware address, such as an Ethernet address or an IEEE802.15.4 address.
#[cfg(any(feature = "medium-ethernet", feature = "medium-ieee802154"))]
#[cfg(any(
feature = "medium-ip",
feature = "medium-ethernet",
feature = "medium-ieee802154"
))]
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub enum HardwareAddress {
#[cfg(feature = "medium-ip")]
Ip,
#[cfg(feature = "medium-ethernet")]
Ethernet(EthernetAddress),
#[cfg(feature = "medium-ieee802154")]
Ieee802154(Ieee802154Address),
}
#[cfg(any(feature = "medium-ethernet", feature = "medium-ieee802154"))]
#[cfg(any(
feature = "medium-ip",
feature = "medium-ethernet",
feature = "medium-ieee802154"
))]
impl HardwareAddress {
pub const fn as_bytes(&self) -> &[u8] {
match self {
#[cfg(feature = "medium-ip")]
HardwareAddress::Ip => unreachable!(),
#[cfg(feature = "medium-ethernet")]
HardwareAddress::Ethernet(addr) => addr.as_bytes(),
#[cfg(feature = "medium-ieee802154")]
@ -299,6 +311,8 @@ impl HardwareAddress {
/// Query wether the address is an unicast address.
pub fn is_unicast(&self) -> bool {
match self {
#[cfg(feature = "medium-ip")]
HardwareAddress::Ip => unreachable!(),
#[cfg(feature = "medium-ethernet")]
HardwareAddress::Ethernet(addr) => addr.is_unicast(),
#[cfg(feature = "medium-ieee802154")]
@ -309,6 +323,8 @@ impl HardwareAddress {
/// Query wether the address is a broadcast address.
pub fn is_broadcast(&self) -> bool {
match self {
#[cfg(feature = "medium-ip")]
HardwareAddress::Ip => unreachable!(),
#[cfg(feature = "medium-ethernet")]
HardwareAddress::Ethernet(addr) => addr.is_broadcast(),
#[cfg(feature = "medium-ieee802154")]
@ -333,12 +349,30 @@ impl HardwareAddress {
_ => panic!("HardwareAddress is not Ethernet."),
}
}
#[inline]
pub(crate) fn medium(&self) -> Medium {
match self {
#[cfg(feature = "medium-ip")]
HardwareAddress::Ip => Medium::Ip,
#[cfg(feature = "medium-ethernet")]
HardwareAddress::Ethernet(_) => Medium::Ethernet,
#[cfg(feature = "medium-ieee802154")]
HardwareAddress::Ieee802154(_) => Medium::Ieee802154,
}
}
}
#[cfg(any(feature = "medium-ethernet", feature = "medium-ieee802154"))]
#[cfg(any(
feature = "medium-ip",
feature = "medium-ethernet",
feature = "medium-ieee802154"
))]
impl core::fmt::Display for HardwareAddress {
fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
match self {
#[cfg(feature = "medium-ip")]
HardwareAddress::Ip => write!(f, "no hardware addr"),
#[cfg(feature = "medium-ethernet")]
HardwareAddress::Ethernet(addr) => write!(f, "{addr}"),
#[cfg(feature = "medium-ieee802154")]