Skip to content

Commit

Permalink
Move to new Error System ~ Failure and provide new result-based opera…
Browse files Browse the repository at this point in the history
…tors (#57)

* Move to new Error System ~ Failure and provide new result-based operators for transform and map
* error-chain -> failure
* return failure ERROR types as the wrapper, for auto causes and backtraces
* prints become logs
* `transform-errors` test to demonstrate handling results
* revise drop_packets: return result / log errors
  * updates the drop_packets trait function to return a result
* result-operators drop Err'ed packets from a batch
* create error_chain and warn_chain, etc... macros for use where we want to have backtraces + nicely formatted error strings + causes
  * under the hood, an error -> String fn for any log level to use though
* bit of added cleanup on graceful exits on configuration/startup errors
  • Loading branch information
zeeshanlakhani authored Mar 5, 2019
1 parent 4a50dab commit 7e628cd
Show file tree
Hide file tree
Showing 62 changed files with 840 additions and 386 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ Vagrantfile

# pcap
out.pcap
*.lnk

# logs
*.log
Expand Down
3 changes: 2 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ members=["framework",
"test/srv6-inject",
"test/tcp-checksum",
"test/icmpv6",
"test/mtu-too-big"
"test/mtu-too-big",
"test/transform-error"
# "test/delay-test",
# "test/chain-test",
# "test/shutdown-test",
Expand Down
1 change: 1 addition & 0 deletions examples.sh
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ export examples=(
test/tcp-checksum
test/icmpv6
test/mtu-too-big
test/transform-error
# test/delay-test
# test/chain-test
# test/shutdown-test
Expand Down
33 changes: 16 additions & 17 deletions framework/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,34 +8,33 @@ build = "build.rs"
doctest = false

[dependencies]
libc = ">= 0.2.4"
time = ">=0.1.0"
getopts = "*"
byteorder = "*"
clippy = { version = ">=0.0.197", optional = true }
crossbeam = "=0.4"
enum_primitive = "0.1.1"
failure = "0.1.5"
fnv = "*"
twox-hash = "*"
regex = "*"
generic-array = ">=0.11.0"
getopts = "*"
hex = "0.3.2"
lazy_static = "*"
libc = ">= 0.2.4"
log = { version = "0.4", features = ["std", "serde"]}
net2 = "*"
# NIX restricts us to just unix for now, we can fix this if someone cares at a later point.
nix = "*"
# Figure out if we want this permanently or just for now.
rust-sctp = { git="https://github.com/netsys/rust-sctp", optional = true}
toml = "*"
serde = "1.0"
serde_derive = "1.0"
# Hack for SHM
uuid = { version = "*", features=["v4"] }
error-chain = "0.12.0"
num = "0.1"
num-derive="0.2"
num-traits = "0.2"
generic-array = ">=0.11.0"
crossbeam = "=0.4"
rayon = "1.0.3"
hex = "0.3.2"
enum_primitive = "0.1.1"
regex = "*"
rust-sctp = { git="https://github.com/netsys/rust-sctp", optional = true}
serde = "1.0"
serde_derive = "1.0"
time = ">=0.1.0"
toml = "*"
twox-hash = "*"
uuid = { version = "*", features = ["v4"] }

[features]
default = []
Expand Down
202 changes: 108 additions & 94 deletions framework/src/common/errors.rs
Original file line number Diff line number Diff line change
@@ -1,98 +1,112 @@
error_chain! {
errors {
FailedAllocation {
description("Failed to allocate memory")
display("Failed to allocate memory")
}
FailedDeallocation {
description("Failed to deallocate memory")
display("Failed to deallocate memory")
}
FailedToInitializePort(port: i32) {
description("Failed to initialize port")
display("Failed to initialize port: {}", port)
}
BadQueue {
description("Invalid queue request")
display("Invalid queue request")
}
CannotSend {
description("Cannot send data out port")
display("Cannot send data out port")
}
BadDev(dev: String) {
description("Cannot find device")
display("Cannot find device: {}", dev)
}
BadVdev(vdev: String) {
description("Bad vdev specification")
display("Bad vdev specification: {}", vdev)
}
BadTxQueue(port: i32, queue: i32) {
description("Bad TX queue")
display("Bad TX queue {} for port {}", queue, port)
}
BadRxQueue(port: i32, queue: i32) {
description("Bad RX queue")
display("Bad RX queue {} for port {}", queue, port)
}
BadOffset(offset: usize) {
description("Attempt to access bad packet offset")
display("Attempt to access bad packet offset {}", offset)
}

MetadataTooLarge {
description("Metadata is too large")
display("Metadata is too large")
}

RingAllocationFailure {
description("Could not allocate ring")
display("Could not allocate ring")
}

InvalidRingSize(size: usize) {
description("Bad ring size, must be power of 2")
display("Bad ring size {}, must be a power of 2", size)
}

RingDuplicationFailure {
description("Address of second copy of ring does not match expected address")
display("Address of second copy of ring does not match expected address")
}

ConfigurationError(description: String) {
description("Configuration error")
display("Configuration error: {}", description)
}

NoRunningSchedulerOnCore(core: i32) {
description("No scheduler running on core")
display("No scheduler running on core {}", core)
}

FailedToInsertHeader {
description("Failed to insert header into packet")
display("Failed to insert header into packet")
}

FailedToSwapHeader(new_header: String) {
description("Failed to swap-in new header in packet")
display("Failed to swap-in new header - {} - in packet", new_header)
}

FailedToRemoveHeader {
description("Failed to remove header from packet")
display("Failed to remove header from packet")
}

FailedToParseMacAddress(s: String) {
description("Failed to parse MAC address")
display("Failed to parse MAC address: '{}'", s)
}
use failure::{Error, Fail};

pub type Result<T> = ::std::result::Result<T, Error>;

#[derive(Debug, Fail)]
pub enum NetBricksError {
#[fail(display = "Failed to allocate memory")]
FailedAllocation,

#[fail(display = "Failed to free memory buffer (mbuf) {}", _0)]
FailedToFreeMBuf(i32),

#[fail(display = "Failed to remove/drop packets from buffer")]
FailedToDropPackets,

#[fail(display = "Failed to deallocate memory")]
FailedDeallocation,

#[fail(display = "Failed to initialize port: {}", _0)]
FailedToInitializePort(i32),

#[fail(display = "Invalid queue request")]
BadQueue,

#[fail(display = "Cannot send data out port")]
CannotSend,

#[fail(display = "Cannot find device: {}", _0)]
BadDev(String),

#[fail(display = "Bad vdev specification: {}", _0)]
BadVdev(String),

#[fail(display = "Bad TX queue {} for port {}", _0, _1)]
BadTxQueue(i32, i32),

#[fail(display = "Bad RX queue {} for port {}", _0, _1)]
BadRxQueue(i32, i32),

#[fail(display = "Attempt to access bad packet offset {}", _0)]
BadOffset(usize),

#[fail(display = "Metadata is too large")]
MetadataTooLarge,

#[fail(display = "Could not allocate ring")]
RingAllocationFailure,

#[fail(display = "Address of second copy of ring does not match expected address")]
RingDuplicationFailure,

#[fail(display = "Bad ring size {}, must be a power of 2", _0)]
InvalidRingSize(usize),

#[fail(display = "Configuration error: {}", _0)]
ConfigurationError(String),

#[fail(display = "No scheduler running on core {}", _0)]
NoRunningSchedulerOnCore(i32),

#[fail(display = "Failed to insert header into packet")]
FailedToInsertHeader,

#[fail(
display = "Failed to swap-in new header - {} - in packet, new_header",
_0
)]
FailedToSwapHeader(String),

#[fail(display = "Failed to remove header from packet")]
FailedToRemoveHeader,

#[fail(display = "Failed to parse MAC address: '{}'", _0)]
FailedToParseMacAddress(String),

#[fail(display = "_")]
#[doc(hidden)]
__Nonexhaustive,
}

#[macro_export]
macro_rules! error_chain {
($error:expr) => {
error!("{}", $crate::common::errors::string_chain($error))
};
}

#[macro_export]
macro_rules! warn_chain {
($error:expr) => {
warn!("{}", $crate::common::errors::string_chain($error))
};
}

/// Read a `failure` `Error` and print out the causes and a backtrace as
/// `log::error`s
pub fn string_chain(e: &Error) -> String {
let mut error = e.to_string();

for cause in e.iter_causes() {
error.push_str(&format!("\nCaused by: {}", cause));
}

foreign_links {
Io(::std::io::Error);
if let Ok("1") = ::std::env::var("RUST_BACKTRACE")
.as_ref()
.map(|s| s.as_str())
{
error.push_str(&format!("\nBacktrace:\n{}", e.backtrace()))
}

error
}
14 changes: 3 additions & 11 deletions framework/src/common/mod.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,7 @@
mod errors;
pub use self::errors::*;

#[macro_use]
pub mod errors;

/// Null metadata associated with packets initially.
pub struct EmptyMetadata;

pub fn print_error(e: &Error) {
println!("Error: {}", e);
for e in e.iter().skip(1) {
println!("Cause: {}", e);
}
if let Some(backtrace) = e.backtrace() {
println!("Backtrace: {:?}", backtrace);
}
}
Loading

0 comments on commit 7e628cd

Please sign in to comment.