Add support for IP mediums.

- Add `medium` in `DeviceCapabilities`.
- Rename EthernetInterface to Interface.
- Add support to Interface for both Ethernet and IP mediums. The medium to use is detected from `device.capabilities().medium`.
- Ethernet-only features are gated behind the "ethernet" feature, as before.
- IP features are always enabled for now.
master
Dario Nieuwenhuis 2020-06-04 03:00:49 +02:00
parent bbecbf80c1
commit 9ac2cac075
16 changed files with 439 additions and 343 deletions

View File

@ -13,7 +13,7 @@ use log::debug;
use smoltcp::phy::wait as phy_wait; use smoltcp::phy::wait as phy_wait;
use smoltcp::wire::{EthernetAddress, IpAddress, IpCidr}; use smoltcp::wire::{EthernetAddress, IpAddress, IpCidr};
use smoltcp::iface::{NeighborCache, EthernetInterfaceBuilder}; use smoltcp::iface::{NeighborCache, InterfaceBuilder};
use smoltcp::socket::SocketSet; use smoltcp::socket::SocketSet;
use smoltcp::socket::{TcpSocket, TcpSocketBuffer}; use smoltcp::socket::{TcpSocket, TcpSocketBuffer};
use smoltcp::time::{Duration, Instant}; use smoltcp::time::{Duration, Instant};
@ -90,7 +90,7 @@ fn main() {
let ethernet_addr = EthernetAddress([0x02, 0x00, 0x00, 0x00, 0x00, 0x01]); let ethernet_addr = EthernetAddress([0x02, 0x00, 0x00, 0x00, 0x00, 0x01]);
let ip_addrs = [IpCidr::new(IpAddress::v4(192, 168, 69, 1), 24)]; let ip_addrs = [IpCidr::new(IpAddress::v4(192, 168, 69, 1), 24)];
let mut iface = EthernetInterfaceBuilder::new(device) let mut iface = InterfaceBuilder::new(device)
.ethernet_addr(ethernet_addr) .ethernet_addr(ethernet_addr)
.neighbor_cache(neighbor_cache) .neighbor_cache(neighbor_cache)
.ip_addrs(ip_addrs) .ip_addrs(ip_addrs)

View File

@ -7,7 +7,7 @@ use log::debug;
use smoltcp::phy::wait as phy_wait; use smoltcp::phy::wait as phy_wait;
use smoltcp::wire::{EthernetAddress, Ipv4Address, IpAddress, IpCidr}; use smoltcp::wire::{EthernetAddress, Ipv4Address, IpAddress, IpCidr};
use smoltcp::iface::{NeighborCache, EthernetInterfaceBuilder, Routes}; use smoltcp::iface::{NeighborCache, InterfaceBuilder, Routes};
use smoltcp::socket::{SocketSet, TcpSocket, TcpSocketBuffer}; use smoltcp::socket::{SocketSet, TcpSocket, TcpSocketBuffer};
use smoltcp::time::Instant; use smoltcp::time::Instant;
@ -39,7 +39,7 @@ fn main() {
let mut routes_storage = [None; 1]; let mut routes_storage = [None; 1];
let mut routes = Routes::new(&mut routes_storage[..]); let mut routes = Routes::new(&mut routes_storage[..]);
routes.add_default_ipv4_route(default_v4_gw).unwrap(); routes.add_default_ipv4_route(default_v4_gw).unwrap();
let mut iface = EthernetInterfaceBuilder::new(device) let mut iface = InterfaceBuilder::new(device)
.ethernet_addr(ethernet_addr) .ethernet_addr(ethernet_addr)
.neighbor_cache(neighbor_cache) .neighbor_cache(neighbor_cache)
.ip_addrs(ip_addrs) .ip_addrs(ip_addrs)

View File

@ -5,7 +5,7 @@ use std::collections::BTreeMap;
use std::os::unix::io::AsRawFd; use std::os::unix::io::AsRawFd;
use smoltcp::phy::wait as phy_wait; use smoltcp::phy::wait as phy_wait;
use smoltcp::wire::{EthernetAddress, Ipv4Address, IpCidr, Ipv4Cidr}; use smoltcp::wire::{EthernetAddress, Ipv4Address, IpCidr, Ipv4Cidr};
use smoltcp::iface::{NeighborCache, EthernetInterfaceBuilder, Routes}; use smoltcp::iface::{NeighborCache, InterfaceBuilder, Routes};
use smoltcp::socket::{SocketSet, RawSocketBuffer, RawPacketMetadata}; use smoltcp::socket::{SocketSet, RawSocketBuffer, RawPacketMetadata};
use smoltcp::time::Instant; use smoltcp::time::Instant;
use smoltcp::dhcp::Dhcpv4Client; use smoltcp::dhcp::Dhcpv4Client;
@ -28,7 +28,7 @@ fn main() {
let ip_addrs = [IpCidr::new(Ipv4Address::UNSPECIFIED.into(), 0)]; let ip_addrs = [IpCidr::new(Ipv4Address::UNSPECIFIED.into(), 0)];
let mut routes_storage = [None; 1]; let mut routes_storage = [None; 1];
let routes = Routes::new(&mut routes_storage[..]); let routes = Routes::new(&mut routes_storage[..]);
let mut iface = EthernetInterfaceBuilder::new(device) let mut iface = InterfaceBuilder::new(device)
.ethernet_addr(ethernet_addr) .ethernet_addr(ethernet_addr)
.neighbor_cache(neighbor_cache) .neighbor_cache(neighbor_cache)
.ip_addrs(ip_addrs) .ip_addrs(ip_addrs)

View File

@ -8,7 +8,7 @@ use log::debug;
use smoltcp::phy::wait as phy_wait; use smoltcp::phy::wait as phy_wait;
use smoltcp::wire::{EthernetAddress, Ipv4Address, Ipv6Address, IpAddress, IpCidr}; use smoltcp::wire::{EthernetAddress, Ipv4Address, Ipv6Address, IpAddress, IpCidr};
use smoltcp::iface::{NeighborCache, EthernetInterfaceBuilder, Routes}; use smoltcp::iface::{NeighborCache, InterfaceBuilder, Routes};
use smoltcp::socket::{SocketSet, TcpSocket, TcpSocketBuffer}; use smoltcp::socket::{SocketSet, TcpSocket, TcpSocketBuffer};
use smoltcp::time::Instant; use smoltcp::time::Instant;
@ -45,7 +45,7 @@ fn main() {
let mut routes = Routes::new(&mut routes_storage[..]); let mut routes = Routes::new(&mut routes_storage[..]);
routes.add_default_ipv4_route(default_v4_gw).unwrap(); routes.add_default_ipv4_route(default_v4_gw).unwrap();
routes.add_default_ipv6_route(default_v6_gw).unwrap(); routes.add_default_ipv6_route(default_v6_gw).unwrap();
let mut iface = EthernetInterfaceBuilder::new(device) let mut iface = InterfaceBuilder::new(device)
.ethernet_addr(ethernet_addr) .ethernet_addr(ethernet_addr)
.neighbor_cache(neighbor_cache) .neighbor_cache(neighbor_cache)
.ip_addrs(ip_addrs) .ip_addrs(ip_addrs)

View File

@ -9,9 +9,9 @@ mod utils;
use core::str; use core::str;
use log::{info, debug, error}; use log::{info, debug, error};
use smoltcp::phy::Loopback; use smoltcp::phy::{Loopback, Medium};
use smoltcp::wire::{EthernetAddress, IpAddress, IpCidr}; use smoltcp::wire::{EthernetAddress, IpAddress, IpCidr};
use smoltcp::iface::{NeighborCache, EthernetInterfaceBuilder}; use smoltcp::iface::{NeighborCache, InterfaceBuilder};
use smoltcp::socket::{SocketSet, TcpSocket, TcpSocketBuffer}; use smoltcp::socket::{SocketSet, TcpSocket, TcpSocketBuffer};
use smoltcp::time::{Duration, Instant}; use smoltcp::time::{Duration, Instant};
@ -65,7 +65,7 @@ mod mock {
fn main() { fn main() {
let clock = mock::Clock::new(); let clock = mock::Clock::new();
let device = Loopback::new(); let device = Loopback::new(Medium::Ethernet);
#[cfg(feature = "std")] #[cfg(feature = "std")]
let device = { let device = {
@ -83,7 +83,7 @@ fn main() {
let mut neighbor_cache = NeighborCache::new(&mut neighbor_cache_entries[..]); let mut neighbor_cache = NeighborCache::new(&mut neighbor_cache_entries[..]);
let mut ip_addrs = [IpCidr::new(IpAddress::v4(127, 0, 0, 1), 8)]; let mut ip_addrs = [IpCidr::new(IpAddress::v4(127, 0, 0, 1), 8)];
let mut iface = EthernetInterfaceBuilder::new(device) let mut iface = InterfaceBuilder::new(device)
.ethernet_addr(EthernetAddress::default()) .ethernet_addr(EthernetAddress::default())
.neighbor_cache(neighbor_cache) .neighbor_cache(neighbor_cache)
.ip_addrs(ip_addrs) .ip_addrs(ip_addrs)

View File

@ -7,7 +7,7 @@ use log::debug;
use smoltcp::phy::wait as phy_wait; use smoltcp::phy::wait as phy_wait;
use smoltcp::wire::{EthernetAddress, IpVersion, IpProtocol, IpAddress, IpCidr, Ipv4Address, use smoltcp::wire::{EthernetAddress, IpVersion, IpProtocol, IpAddress, IpCidr, Ipv4Address,
Ipv4Packet, IgmpPacket, IgmpRepr}; Ipv4Packet, IgmpPacket, IgmpRepr};
use smoltcp::iface::{NeighborCache, EthernetInterfaceBuilder}; use smoltcp::iface::{NeighborCache, InterfaceBuilder};
use smoltcp::socket::{SocketSet, use smoltcp::socket::{SocketSet,
RawSocket, RawSocketBuffer, RawPacketMetadata, RawSocket, RawSocketBuffer, RawPacketMetadata,
UdpSocket, UdpSocketBuffer, UdpPacketMetadata}; UdpSocket, UdpSocketBuffer, UdpPacketMetadata};
@ -37,7 +37,7 @@ fn main() {
let ethernet_addr = EthernetAddress([0x02, 0x00, 0x00, 0x00, 0x00, 0x02]); let ethernet_addr = EthernetAddress([0x02, 0x00, 0x00, 0x00, 0x00, 0x02]);
let ip_addr = IpCidr::new(IpAddress::from(local_addr), 24); let ip_addr = IpCidr::new(IpAddress::from(local_addr), 24);
let mut ipv4_multicast_storage = [None; 1]; let mut ipv4_multicast_storage = [None; 1];
let mut iface = EthernetInterfaceBuilder::new(device) let mut iface = InterfaceBuilder::new(device)
.ethernet_addr(ethernet_addr) .ethernet_addr(ethernet_addr)
.neighbor_cache(neighbor_cache) .neighbor_cache(neighbor_cache)
.ip_addrs([ip_addr]) .ip_addrs([ip_addr])

View File

@ -14,7 +14,7 @@ use smoltcp::phy::wait as phy_wait;
use smoltcp::wire::{EthernetAddress, IpAddress, IpCidr, use smoltcp::wire::{EthernetAddress, IpAddress, IpCidr,
Ipv6Address, Icmpv6Repr, Icmpv6Packet, Ipv6Address, Icmpv6Repr, Icmpv6Packet,
Ipv4Address, Icmpv4Repr, Icmpv4Packet}; Ipv4Address, Icmpv4Repr, Icmpv4Packet};
use smoltcp::iface::{NeighborCache, EthernetInterfaceBuilder, Routes}; use smoltcp::iface::{NeighborCache, InterfaceBuilder, Routes};
use smoltcp::socket::{SocketSet, IcmpSocket, IcmpSocketBuffer, IcmpPacketMetadata, IcmpEndpoint}; use smoltcp::socket::{SocketSet, IcmpSocket, IcmpSocketBuffer, IcmpPacketMetadata, IcmpEndpoint};
macro_rules! send_icmp_ping { macro_rules! send_icmp_ping {
@ -98,7 +98,7 @@ fn main() {
let mut routes = Routes::new(&mut routes_storage[..]); let mut routes = Routes::new(&mut routes_storage[..]);
routes.add_default_ipv4_route(default_v4_gw).unwrap(); routes.add_default_ipv4_route(default_v4_gw).unwrap();
routes.add_default_ipv6_route(default_v6_gw).unwrap(); routes.add_default_ipv6_route(default_v6_gw).unwrap();
let mut iface = EthernetInterfaceBuilder::new(device) let mut iface = InterfaceBuilder::new(device)
.ethernet_addr(ethernet_addr) .ethernet_addr(ethernet_addr)
.ip_addrs(ip_addrs) .ip_addrs(ip_addrs)
.routes(routes) .routes(routes)

View File

@ -8,7 +8,7 @@ use log::debug;
use smoltcp::phy::wait as phy_wait; use smoltcp::phy::wait as phy_wait;
use smoltcp::wire::{EthernetAddress, IpAddress, IpCidr}; use smoltcp::wire::{EthernetAddress, IpAddress, IpCidr};
use smoltcp::iface::{NeighborCache, EthernetInterfaceBuilder}; use smoltcp::iface::{NeighborCache, InterfaceBuilder};
use smoltcp::socket::SocketSet; use smoltcp::socket::SocketSet;
use smoltcp::socket::{UdpSocket, UdpSocketBuffer, UdpPacketMetadata}; use smoltcp::socket::{UdpSocket, UdpSocketBuffer, UdpPacketMetadata};
use smoltcp::socket::{TcpSocket, TcpSocketBuffer}; use smoltcp::socket::{TcpSocket, TcpSocketBuffer};
@ -54,7 +54,7 @@ fn main() {
IpCidr::new(IpAddress::v6(0xfdaa, 0, 0, 0, 0, 0, 0, 1), 64), IpCidr::new(IpAddress::v6(0xfdaa, 0, 0, 0, 0, 0, 0, 1), 64),
IpCidr::new(IpAddress::v6(0xfe80, 0, 0, 0, 0, 0, 0, 1), 64) IpCidr::new(IpAddress::v6(0xfe80, 0, 0, 0, 0, 0, 0, 1), 64)
]; ];
let mut iface = EthernetInterfaceBuilder::new(device) let mut iface = InterfaceBuilder::new(device)
.ethernet_addr(ethernet_addr) .ethernet_addr(ethernet_addr)
.neighbor_cache(neighbor_cache) .neighbor_cache(neighbor_cache)
.ip_addrs(ip_addrs) .ip_addrs(ip_addrs)

View File

@ -6,10 +6,10 @@ use std as core;
extern crate getopts; extern crate getopts;
use core::cmp; use core::cmp;
use smoltcp::phy::Loopback; use smoltcp::phy::{Loopback, Medium};
use smoltcp::wire::{EthernetAddress, EthernetFrame, EthernetProtocol}; use smoltcp::wire::{EthernetAddress, EthernetFrame, EthernetProtocol};
use smoltcp::wire::{IpAddress, IpCidr, Ipv4Packet, Ipv6Packet, TcpPacket}; use smoltcp::wire::{IpAddress, IpCidr, Ipv4Packet, Ipv6Packet, TcpPacket};
use smoltcp::iface::{NeighborCache, EthernetInterfaceBuilder}; use smoltcp::iface::{NeighborCache, InterfaceBuilder};
use smoltcp::socket::{SocketSet, TcpSocket, TcpSocketBuffer}; use smoltcp::socket::{SocketSet, TcpSocket, TcpSocketBuffer};
use smoltcp::time::{Duration, Instant}; use smoltcp::time::{Duration, Instant};
@ -118,7 +118,7 @@ fuzz_target!(|data: &[u8]| {
utils::add_middleware_options(&mut opts, &mut free); utils::add_middleware_options(&mut opts, &mut free);
let mut matches = utils::parse_options(&opts, free); let mut matches = utils::parse_options(&opts, free);
let device = utils::parse_middleware_options(&mut matches, Loopback::new(), let device = utils::parse_middleware_options(&mut matches, Loopback::new(Medium::Ethernet),
/*loopback=*/true); /*loopback=*/true);
smoltcp::phy::FuzzInjector::new(device, smoltcp::phy::FuzzInjector::new(device,
@ -130,7 +130,7 @@ fuzz_target!(|data: &[u8]| {
let neighbor_cache = NeighborCache::new(&mut neighbor_cache_entries[..]); let neighbor_cache = NeighborCache::new(&mut neighbor_cache_entries[..]);
let ip_addrs = [IpCidr::new(IpAddress::v4(127, 0, 0, 1), 8)]; let ip_addrs = [IpCidr::new(IpAddress::v4(127, 0, 0, 1), 8)];
let mut iface = EthernetInterfaceBuilder::new(device) let mut iface = InterfaceBuilder::new(device)
.ethernet_addr(EthernetAddress::default()) .ethernet_addr(EthernetAddress::default())
.neighbor_cache(neighbor_cache) .neighbor_cache(neighbor_cache)
.ip_addrs(ip_addrs) .ip_addrs(ip_addrs)

View File

@ -6,7 +6,7 @@ use crate::wire::{IpVersion, IpProtocol, IpEndpoint, IpAddress,
use crate::wire::dhcpv4::field as dhcpv4_field; use crate::wire::dhcpv4::field as dhcpv4_field;
use crate::socket::{SocketSet, SocketHandle, RawSocket, RawSocketBuffer}; use crate::socket::{SocketSet, SocketHandle, RawSocket, RawSocketBuffer};
use crate::phy::{Device, ChecksumCapabilities}; use crate::phy::{Device, ChecksumCapabilities};
use crate::iface::EthernetInterface as Interface; use crate::iface::Interface;
use crate::time::{Instant, Duration}; use crate::time::{Instant, Duration};
use super::{UDP_SERVER_PORT, UDP_CLIENT_PORT}; use super::{UDP_SERVER_PORT, UDP_CLIENT_PORT};

File diff suppressed because it is too large Load Diff

View File

@ -7,8 +7,7 @@ provides lookup and caching of hardware addresses, and handles management packet
#[cfg(feature = "ethernet")] #[cfg(feature = "ethernet")]
mod neighbor; mod neighbor;
mod route; mod route;
#[cfg(feature = "ethernet")] mod interface;
mod ethernet;
#[cfg(feature = "ethernet")] #[cfg(feature = "ethernet")]
pub use self::neighbor::Neighbor as Neighbor; pub use self::neighbor::Neighbor as Neighbor;
@ -17,6 +16,5 @@ pub(crate) use self::neighbor::Answer as NeighborAnswer;
#[cfg(feature = "ethernet")] #[cfg(feature = "ethernet")]
pub use self::neighbor::Cache as NeighborCache; pub use self::neighbor::Cache as NeighborCache;
pub use self::route::{Route, Routes}; pub use self::route::{Route, Routes};
#[cfg(feature = "ethernet")]
pub use self::ethernet::{Interface as EthernetInterface, pub use self::interface::{Interface, InterfaceBuilder};
InterfaceBuilder as EthernetInterfaceBuilder};

View File

@ -10,13 +10,14 @@ use alloc::collections::VecDeque;
use alloc::VecDeque; use alloc::VecDeque;
use crate::Result; use crate::Result;
use crate::phy::{self, Device, DeviceCapabilities}; use crate::phy::{self, Device, DeviceCapabilities, Medium};
use crate::time::Instant; use crate::time::Instant;
/// A loopback device. /// A loopback device.
#[derive(Debug)] #[derive(Debug)]
pub struct Loopback { pub struct Loopback {
queue: VecDeque<Vec<u8>>, queue: VecDeque<Vec<u8>>,
medium: Medium,
} }
#[allow(clippy::new_without_default)] #[allow(clippy::new_without_default)]
@ -25,9 +26,10 @@ impl Loopback {
/// ///
/// Every packet transmitted through this device will be received through it /// Every packet transmitted through this device will be received through it
/// in FIFO order. /// in FIFO order.
pub fn new() -> Loopback { pub fn new(medium: Medium) -> Loopback {
Loopback { Loopback {
queue: VecDeque::new(), queue: VecDeque::new(),
medium,
} }
} }
} }
@ -39,6 +41,7 @@ impl<'a> Device<'a> for Loopback {
fn capabilities(&self) -> DeviceCapabilities { fn capabilities(&self) -> DeviceCapabilities {
DeviceCapabilities { DeviceCapabilities {
max_transmission_unit: 65535, max_transmission_unit: 65535,
medium: self.medium,
..DeviceCapabilities::default() ..DeviceCapabilities::default()
} }
} }

View File

@ -10,7 +10,8 @@ and implementations of it:
* _adapters_ [RawSocket](struct.RawSocket.html) and * _adapters_ [RawSocket](struct.RawSocket.html) and
[TapInterface](struct.TapInterface.html), to transmit and receive frames [TapInterface](struct.TapInterface.html), to transmit and receive frames
on the host OS. on the host OS.
*/
#![cfg_attr(feature = "ethernet", doc = r##"
# Examples # Examples
An implementation of the [Device](trait.Device.html) trait for a simple hardware An implementation of the [Device](trait.Device.html) trait for a simple hardware
@ -18,7 +19,7 @@ Ethernet controller could look as follows:
```rust ```rust
use smoltcp::Result; use smoltcp::Result;
use smoltcp::phy::{self, DeviceCapabilities, Device}; use smoltcp::phy::{self, DeviceCapabilities, Device, Medium};
use smoltcp::time::Instant; use smoltcp::time::Instant;
struct StmPhy { struct StmPhy {
@ -52,6 +53,7 @@ impl<'a> phy::Device<'a> for StmPhy {
let mut caps = DeviceCapabilities::default(); let mut caps = DeviceCapabilities::default();
caps.max_transmission_unit = 1536; caps.max_transmission_unit = 1536;
caps.max_burst_size = Some(1); caps.max_burst_size = Some(1);
caps.medium = Medium::Ethernet;
caps caps
} }
} }
@ -82,7 +84,7 @@ impl<'a> phy::TxToken for StmPhyTxToken<'a> {
} }
} }
``` ```
*/ "##)]
use crate::Result; use crate::Result;
use crate::time::Instant; use crate::time::Instant;
@ -192,6 +194,13 @@ impl ChecksumCapabilities {
#[derive(Debug, Clone, Default)] #[derive(Debug, Clone, Default)]
#[non_exhaustive] #[non_exhaustive]
pub struct DeviceCapabilities { pub struct DeviceCapabilities {
/// Medium of the device.
///
/// This indicates what kind of packet the sent/received bytes are, and determines
/// some behaviors of Interface. For example, ARP/NDISC address resolution is only done
/// for Ethernet mediums.
pub medium: Medium,
/// Maximum transmission unit. /// Maximum transmission unit.
/// ///
/// The network device is unable to send or receive frames larger than the value returned /// The network device is unable to send or receive frames larger than the value returned
@ -222,6 +231,33 @@ pub struct DeviceCapabilities {
pub checksum: ChecksumCapabilities, pub checksum: ChecksumCapabilities,
} }
/// Type of medium of a device.
#[derive(Debug, Eq, PartialEq, Copy, Clone)]
pub enum Medium {
/// Ethernet medium. Devices of this type send and receive Ethernet frames,
/// and interfaces using it must do neighbor discovery via ARP or NDISC.
///
/// Examples of devices of this type are Ethernet, WiFi (802.11), Linux `tap`, and VPNs in tap (layer 2) mode.
#[cfg(feature = "ethernet")]
Ethernet,
/// IP medium. Devices of this type send and receive IP frames, without an
/// Ethernet header. MAC addresses are not used, and no neighbor discovery (ARP, NDISC) is done.
///
/// Examples of devices of this type are the Linux `tun`, PPP interfaces, VPNs in tun (layer 3) mode.
Ip,
}
impl Default for Medium {
fn default() -> Medium {
#[cfg(feature = "ethernet")]
return Medium::Ethernet;
#[cfg(not(feature = "ethernet"))]
return Medium::Ip;
}
}
/// An interface for sending and receiving raw network frames. /// An interface for sending and receiving raw network frames.
/// ///
/// The interface is based on _tokens_, which are types that allow to receive/transmit a /// The interface is based on _tokens_, which are types that allow to receive/transmit a

View File

@ -5,7 +5,7 @@ use std::io;
use std::os::unix::io::{RawFd, AsRawFd}; use std::os::unix::io::{RawFd, AsRawFd};
use crate::Result; use crate::Result;
use crate::phy::{self, sys, DeviceCapabilities, Device}; use crate::phy::{self, sys, DeviceCapabilities, Device, Medium};
use crate::time::Instant; use crate::time::Instant;
/// A socket that captures or transmits the complete frame. /// A socket that captures or transmits the complete frame.
@ -44,6 +44,7 @@ impl<'a> Device<'a> for RawSocket {
fn capabilities(&self) -> DeviceCapabilities { fn capabilities(&self) -> DeviceCapabilities {
DeviceCapabilities { DeviceCapabilities {
max_transmission_unit: self.mtu, max_transmission_unit: self.mtu,
medium: Medium::Ethernet,
..DeviceCapabilities::default() ..DeviceCapabilities::default()
} }
} }

View File

@ -5,7 +5,7 @@ use std::io;
use std::os::unix::io::{RawFd, AsRawFd}; use std::os::unix::io::{RawFd, AsRawFd};
use crate::Result; use crate::Result;
use crate::phy::{self, sys, DeviceCapabilities, Device}; use crate::phy::{self, sys, DeviceCapabilities, Device, Medium};
use crate::time::Instant; use crate::time::Instant;
/// A virtual Ethernet interface. /// A virtual Ethernet interface.
@ -45,6 +45,7 @@ impl<'a> Device<'a> for TapInterface {
fn capabilities(&self) -> DeviceCapabilities { fn capabilities(&self) -> DeviceCapabilities {
DeviceCapabilities { DeviceCapabilities {
max_transmission_unit: self.mtu, max_transmission_unit: self.mtu,
medium: Medium::Ethernet,
..DeviceCapabilities::default() ..DeviceCapabilities::default()
} }
} }