Add ethernet feature-gate as default.

Disable ethernet-related features and framing based on a feature gate.

Add a no-ethernet option to Travis.

notes:
- allow(unused) is added when not using ethernet feature
- Don't run pretty-print doctest, ethernet is optional.

Closes: #308
Approved by: whitequark
v0.7.x
Ruben De Smet 2019-10-04 11:10:20 +02:00 committed by Homu
parent 0df7e51a9f
commit eebd8e431a
9 changed files with 48 additions and 23 deletions

View File

@ -12,32 +12,35 @@ matrix:
env: FEATURES='default' MODE='test'
### Test select feature permutations, chosen to be as orthogonal as possible
- rust: nightly
env: FEATURES='std phy-raw_socket proto-ipv6 socket-udp' MODE='test'
env: FEATURES='std ethernet phy-raw_socket proto-ipv6 socket-udp' MODE='test'
- rust: nightly
env: FEATURES='std phy-tap_interface proto-ipv6 socket-udp' MODE='test'
env: FEATURES='std ethernet phy-tap_interface proto-ipv6 socket-udp' MODE='test'
- rust: nightly
env: FEATURES='std proto-ipv4 proto-igmp socket-raw' MODE='test'
env: FEATURES='std ethernet proto-ipv4 proto-igmp socket-raw' MODE='test'
- rust: nightly
env: FEATURES='std proto-ipv4 socket-udp socket-tcp' MODE='test'
env: FEATURES='std ethernet proto-ipv4 socket-udp socket-tcp' MODE='test'
- rust: nightly
env: FEATURES='std proto-ipv4 proto-dhcpv4 socket-udp' MODE='test'
env: FEATURES='std ethernet proto-ipv4 proto-dhcpv4 socket-udp' MODE='test'
- rust: nightly
env: FEATURES='std proto-ipv6 socket-udp' MODE='test'
env: FEATURES='std ethernet proto-ipv6 socket-udp' MODE='test'
- rust: nightly
env: FEATURES='std proto-ipv6 socket-tcp' MODE='test'
env: FEATURES='std ethernet proto-ipv6 socket-tcp' MODE='test'
- rust: nightly
env: FEATURES='std proto-ipv4 socket-icmp socket-tcp' MODE='test'
env: FEATURES='std ethernet proto-ipv4 socket-icmp socket-tcp' MODE='test'
- rust: nightly
env: FEATURES='std proto-ipv6 socket-icmp socket-tcp' MODE='test'
env: FEATURES='std ethernet proto-ipv6 socket-icmp socket-tcp' MODE='test'
### Test select feature permutations, chosen to be as aggressive as possible
- rust: nightly
env: FEATURES='proto-ipv4 proto-ipv6 socket-raw socket-udp socket-tcp socket-icmp std'
env: FEATURES='ethernet proto-ipv4 proto-ipv6 socket-raw socket-udp socket-tcp socket-icmp std'
MODE='test'
- rust: nightly
env: FEATURES='ethernet proto-ipv4 proto-ipv6 socket-raw socket-udp socket-tcp socket-icmp alloc'
MODE='test'
- rust: nightly
env: FEATURES='proto-ipv4 proto-ipv6 socket-raw socket-udp socket-tcp socket-icmp alloc'
MODE='test'
- rust: nightly
env: FEATURES='proto-ipv4 proto-ipv6 proto-igmp proto-dhcpv4 socket-raw socket-udp socket-tcp socket-icmp'
env: FEATURES='ethernet proto-ipv4 proto-ipv6 proto-igmp proto-dhcpv4 socket-raw socket-udp socket-tcp socket-icmp'
MODE='build'
- rust: nightly
env: MODE='fuzz run' ARGS='packet_parser -- -max_len=1536 -max_total_time=30'

View File

@ -31,6 +31,7 @@ url = "1.0"
std = ["managed/std"]
alloc = ["managed/alloc"]
verbose = []
ethernet = []
"phy-raw_socket" = ["std", "libc"]
"phy-tap_interface" = ["std", "libc"]
"proto-ipv4" = []
@ -43,6 +44,7 @@ verbose = []
"socket-icmp" = []
default = [
"std", "log", # needed for `cargo test --no-default-features --features default` :/
"ethernet",
"phy-raw_socket", "phy-tap_interface",
"proto-ipv4", "proto-igmp", "proto-ipv6",
"socket-raw", "socket-icmp", "socket-udp", "socket-tcp"

View File

@ -4,13 +4,19 @@ The `iface` module deals with the *network interfaces*. It filters incoming fram
provides lookup and caching of hardware addresses, and handles management packets.
*/
#[cfg(feature = "ethernet")]
mod neighbor;
mod route;
#[cfg(feature = "ethernet")]
mod ethernet;
#[cfg(feature = "ethernet")]
pub use self::neighbor::Neighbor as Neighbor;
#[cfg(feature = "ethernet")]
pub(crate) use self::neighbor::Answer as NeighborAnswer;
#[cfg(feature = "ethernet")]
pub use self::neighbor::Cache as NeighborCache;
pub use self::route::{Route, Routes};
#[cfg(feature = "ethernet")]
pub use self::ethernet::{Interface as EthernetInterface,
InterfaceBuilder as EthernetInterfaceBuilder};

View File

@ -1,7 +1,7 @@
#![cfg_attr(feature = "alloc", feature(alloc))]
#![no_std]
#![deny(unsafe_code)]
#![cfg_attr(any(feature = "proto-ipv4", feature = "proto-ipv6"), deny(unused))]
#![cfg_attr(all(any(feature = "proto-ipv4", feature = "proto-ipv6"), feature = "ethernet"), deny(unused))]
//! The _smoltcp_ library is built in a layered structure, with the layers corresponding
//! to the levels of API abstraction. Only the highest layers would be used by a typical
@ -91,7 +91,7 @@ compile_error!("at least one socket needs to be enabled"); */
// FIXME(dlrobertson): clippy fails with this lint
#![cfg_attr(feature = "cargo-clippy", allow(if_same_then_else))]
#[cfg(feature = "proto-ipv6")]
#[cfg(all(feature = "proto-ipv6", feature = "ethernet"))]
#[macro_use]
extern crate bitflags;
extern crate byteorder;

View File

@ -3,7 +3,9 @@
use core::str::FromStr;
use core::result;
use wire::{EthernetAddress, IpAddress, IpCidr, IpEndpoint};
#[cfg(feature = "ethernet")]
use wire::EthernetAddress;
use wire::{IpAddress, IpCidr, IpEndpoint};
#[cfg(feature = "proto-ipv4")]
use wire::{Ipv4Address, Ipv4Cidr};
#[cfg(feature = "proto-ipv6")]
@ -116,6 +118,7 @@ impl<'a> Parser<'a> {
}
}
#[cfg(feature = "ethernet")]
fn accept_mac_joined_with(&mut self, separator: u8) -> Result<EthernetAddress> {
let mut octets = [0u8; 6];
for n in 0..6 {
@ -127,6 +130,7 @@ impl<'a> Parser<'a> {
Ok(EthernetAddress(octets))
}
#[cfg(feature = "ethernet")]
fn accept_mac(&mut self) -> Result<EthernetAddress> {
if let Some(mac) = self.try(|p| p.accept_mac_joined_with(b'-')) {
return Ok(mac)
@ -344,6 +348,7 @@ impl<'a> Parser<'a> {
}
}
#[cfg(feature = "ethernet")]
impl FromStr for EthernetAddress {
type Err = ();
@ -462,7 +467,7 @@ mod test {
}
#[test]
#[cfg(feature = "proto-ipv4")]
#[cfg(all(feature = "proto-ipv4", feature = "ethernet"))]
fn test_mac() {
assert_eq!(EthernetAddress::from_str(""), Err(()));
assert_eq!(EthernetAddress::from_str("02:00:00:00:00:00"),

View File

@ -115,6 +115,7 @@ pub use self::raw_socket::RawSocket;
#[cfg(all(feature = "phy-tap_interface", target_os = "linux"))]
pub use self::tap_interface::TapInterface;
#[cfg(feature = "ethernet")]
/// A tracer device for Ethernet frames.
pub type EthernetTracer<T> = Tracer<T, super::wire::EthernetFrame<&'static [u8]>>;

View File

@ -5,7 +5,9 @@ use {Error, Result};
use phy::ChecksumCapabilities;
use super::ip::checksum;
use super::{IpAddress, IpProtocol, Ipv6Packet, Ipv6Repr};
use super::{MldRepr, NdiscRepr};
use super::MldRepr;
#[cfg(feature = "ethernet")]
use super::NdiscRepr;
enum_with_unknown! {
/// Internet protocol control message type.
@ -537,6 +539,7 @@ pub enum Repr<'a> {
seq_no: u16,
data: &'a [u8]
},
#[cfg(feature = "ethernet")]
Ndisc(NdiscRepr<'a>),
Mld(MldRepr<'a>),
#[doc(hidden)]
@ -619,6 +622,7 @@ impl<'a> Repr<'a> {
data: packet.payload()
})
},
#[cfg(feature = "ethernet")]
(msg_type, 0) if msg_type.is_ndisc() => {
NdiscRepr::parse(packet).map(|repr| Repr::Ndisc(repr))
},
@ -640,6 +644,7 @@ impl<'a> Repr<'a> {
&Repr::EchoReply { data, .. } => {
field::ECHO_SEQNO.end + data.len()
},
#[cfg(feature = "ethernet")]
&Repr::Ndisc(ndisc) => {
ndisc.buffer_len()
},
@ -711,6 +716,7 @@ impl<'a> Repr<'a> {
packet.payload_mut()[..data_len].copy_from_slice(&data[..data_len])
},
#[cfg(feature = "ethernet")]
&Repr::Ndisc(ndisc) => {
ndisc.emit(packet)
},

View File

@ -77,8 +77,9 @@ mod field {
pub mod pretty_print;
#[cfg(feature = "ethernet")]
mod ethernet;
#[cfg(feature = "proto-ipv4")]
#[cfg(all(feature = "proto-ipv4", feature = "ethernet"))]
mod arp;
pub(crate) mod ip;
#[cfg(feature = "proto-ipv4")]
@ -101,9 +102,9 @@ mod icmpv6;
mod icmp;
#[cfg(feature = "proto-igmp")]
mod igmp;
#[cfg(feature = "proto-ipv6")]
#[cfg(all(feature = "proto-ipv6", feature = "ethernet"))]
mod ndisc;
#[cfg(feature = "proto-ipv6")]
#[cfg(all(feature = "proto-ipv6", feature = "ethernet"))]
mod ndiscoption;
#[cfg(feature = "proto-ipv6")]
mod mld;
@ -114,12 +115,13 @@ pub(crate) mod dhcpv4;
pub use self::pretty_print::PrettyPrinter;
#[cfg(feature = "ethernet")]
pub use self::ethernet::{EtherType as EthernetProtocol,
Address as EthernetAddress,
Frame as EthernetFrame,
Repr as EthernetRepr};
#[cfg(feature = "proto-ipv4")]
#[cfg(all(feature = "proto-ipv4", feature = "ethernet"))]
pub use self::arp::{Hardware as ArpHardware,
Operation as ArpOperation,
Packet as ArpPacket,
@ -190,12 +192,12 @@ pub use self::icmpv6::{Message as Icmpv6Message,
pub use self::icmp::Repr as IcmpRepr;
#[cfg(feature = "proto-ipv6")]
#[cfg(all(feature = "proto-ipv6", feature = "ethernet"))]
pub use self::ndisc::{Repr as NdiscRepr,
RouterFlags as NdiscRouterFlags,
NeighborFlags as NdiscNeighborFlags};
#[cfg(feature = "proto-ipv6")]
#[cfg(all(feature = "proto-ipv6", feature = "ethernet"))]
pub use self::ndiscoption::{NdiscOption,
Repr as NdiscOptionRepr,
Type as NdiscOptionType,

View File

@ -7,7 +7,7 @@ easily human readable packet listings.
A packet can be formatted using the `PrettyPrinter` wrapper:
```rust
```rust,ignore
use smoltcp::wire::*;
let buffer = vec![
// Ethernet II