Skip to content

Commit

Permalink
Experimental refactor
Browse files Browse the repository at this point in the history
  • Loading branch information
daniel-noland committed May 3, 2024
1 parent 76962a4 commit 73b5380
Show file tree
Hide file tree
Showing 11 changed files with 112 additions and 122 deletions.
2 changes: 2 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ pub use self::address_family_freebsd::AddressFamily;
target_os = "freebsd",
)))]
mod address_family_fallback;
mod net;

#[cfg(not(any(
target_os = "linux",
target_os = "fuchsia",
Expand Down
6 changes: 0 additions & 6 deletions src/tc/filters/arp.rs → src/net/arp.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
/// List from [iana.org][1]
///
/// [1]: https://www.iana.org/assignments/arp-parameters/arp-parameters.xhtml
use crate::tc::filters::ethernet::Mac;

const RESERVED: u8 = 0;
const REQUEST: u8 = 1;
Expand Down Expand Up @@ -136,8 +135,3 @@ impl From<Operation> for u8 {
*value.as_ref()
}
}

pub type Sha = Mac;
pub type ShaMask = Mac;
pub type Tha = Mac;
pub type ThaMask = Mac;
10 changes: 4 additions & 6 deletions src/tc/filters/ethernet.rs → src/net/ethernet.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
use anyhow::Error;

#[derive(Debug, PartialEq, Eq, Clone)]
pub struct Mac([u8; 6]);
pub type MacMask = Mac;
Expand Down Expand Up @@ -310,7 +308,7 @@ impl From<Ethertype> for u16 {
pub struct VlanId(u16);

impl VlanId {
pub fn try_new(id: u16) -> Result<Self, Error> {
pub fn try_new(id: u16) -> Result<Self, anyhow::Error> {
if id >= 4096 {
return Err(anyhow::anyhow!("VLAN ID must be less than 4096"));
}
Expand All @@ -319,7 +317,7 @@ impl VlanId {
}

impl TryFrom<u16> for VlanId {
type Error = Error;
type Error = anyhow::Error;

fn try_from(id: u16) -> Result<Self, Self::Error> {
Self::try_new(id)
Expand All @@ -342,7 +340,7 @@ impl From<VlanId> for u16 {
pub struct VlanPrio(u8);

impl VlanPrio {
pub fn try_new(prio: u8) -> Result<Self, Error> {
pub fn try_new(prio: u8) -> Result<Self, anyhow::Error> {
if prio > Self::HIGHEST.into() {
return Err(anyhow::anyhow!("VLAN priority must be less than 8"));
}
Expand All @@ -354,7 +352,7 @@ impl VlanPrio {
}

impl TryFrom<u8> for VlanPrio {
type Error = Error;
type Error = anyhow::Error;

fn try_from(prio: u8) -> Result<Self, Self::Error> {
Self::try_new(prio)
Expand Down
23 changes: 6 additions & 17 deletions src/tc/filters/icmpv4.rs → src/net/icmpv4.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,3 @@
#![deny(
clippy::all,
clippy::pedantic,
clippy::unwrap_used,
clippy::expect_used,
clippy::panic
)]

/// Lists sourced from [iana.org][1]
///
/// [1]: https://www.iana.org/assignments/icmp-parameters/icmp-parameters.xhtml
Expand Down Expand Up @@ -508,16 +500,16 @@ impl From<RouterSolicitation> for u8 {
#[non_exhaustive]
#[repr(u8)]
pub enum TimeExceeded {
TimeToLiveExceededInTransit = 0,
FragmentReassemblyTimeExceeded = 1,
TtlExceededInTransit = 0,
FragmentReassembly = 1,
Other(u8),
}

impl AsRef<u8> for TimeExceeded {
fn as_ref(&self) -> &u8 {
match self {
TimeExceeded::TimeToLiveExceededInTransit => &0,
TimeExceeded::FragmentReassemblyTimeExceeded => &1,
TimeExceeded::TtlExceededInTransit => &0,
TimeExceeded::FragmentReassembly => &1,
TimeExceeded::Other(x) => x,
}
}
Expand All @@ -526,8 +518,8 @@ impl AsRef<u8> for TimeExceeded {
impl From<u8> for TimeExceeded {
fn from(value: u8) -> Self {
match value {
0 => TimeExceeded::TimeToLiveExceededInTransit,
1 => TimeExceeded::FragmentReassemblyTimeExceeded,
0 => TimeExceeded::TtlExceededInTransit,
1 => TimeExceeded::FragmentReassembly,
x => TimeExceeded::Other(x),
}
}
Expand Down Expand Up @@ -1268,6 +1260,3 @@ impl AsRef<u8> for Code {
}
}
}

pub type TypeMask = u8;
pub type CodeMask = u8;
2 changes: 0 additions & 2 deletions src/tc/filters/icmpv6.rs → src/net/icmpv6.rs
Original file line number Diff line number Diff line change
Expand Up @@ -232,6 +232,4 @@ impl From<Type> for u8 {
}
}

pub type TypeMask = u8;
pub type Code = u8;
pub type CodeMask = u8;
15 changes: 15 additions & 0 deletions src/net/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// General purpose networking abstractions.
#![forbid(unsafe_code)]
#![deny(
clippy::all,
clippy::pedantic,
clippy::unwrap_used,
clippy::expect_used,
clippy::panic
)]

pub mod arp;
pub mod ethernet;
pub mod icmpv4;
pub mod icmpv6;
pub mod mpls;
69 changes: 69 additions & 0 deletions src/net/mpls.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
use std::convert::TryFrom;
use anyhow::Error;

#[derive(Debug, PartialEq, Eq, Clone, Copy, Ord, PartialOrd, Hash)]
#[repr(transparent)]
pub struct Label(u32);

/// Should we add handling for reserved labels as per [RFC 3032][1] (see page
/// 4)?
///
/// [1]: https://www.iana.org/assignments/mpls-label-values/mpls-label-values.xhtml
impl Label {
pub fn try_new(label: u32) -> Result<Self, Error> {
if label > 0xFFFFF {
Err(Error::msg("MPLS label must be less than 0xFFFFF"))?;
}
Ok(Self(label))
}
}

impl TryFrom<u32> for Label {
type Error = Error;

fn try_from(label: u32) -> Result<Self, Self::Error> {
Self::try_new(label)
}
}

impl From<Label> for u32 {
fn from(label: Label) -> u32 {
label.0
}
}

/// Bottom of stack flag.
///
/// The "bottom of stack" flag is only a single bit wide.
/// For this reason, we can get away without marking this as non-exhaustive.
/// It is represented as `u8` in the netlink message.
/// I take this to mean that it functions like a c boolean and that any non-zero
/// value is `Set`.
#[derive(Debug, PartialEq, Eq, Clone, Copy, Ord, PartialOrd, Hash)]
#[repr(u8)]
pub enum BottomOfStack {
Unset = 0,
Set = 1,
}

impl From<u8> for BottomOfStack {
fn from(bos: u8) -> Self {
match bos {
0 => BottomOfStack::Unset,
1 => BottomOfStack::Set,
_ => {
log::warn!(
"Invalid BottomOfStack value: {}, interpreting as Set",
bos
);
BottomOfStack::Set
}
}
}
}

impl From<BottomOfStack> for u8 {
fn from(value: BottomOfStack) -> Self {
value as u8
}
}
12 changes: 7 additions & 5 deletions src/tc/filters/cls_flower.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,13 @@ use netlink_packet_utils::{
DecodeError, Emitable,
};

use crate::tc::filters::ethernet;
use crate::net::mpls;
use crate::net::{ethernet, icmpv4, icmpv6};
use crate::tc::filters::flower::encap;
use crate::tc::filters::flower::mpls;
use crate::tc::{arp, icmpv4, icmpv6, TcAction, TcFlowerOptionFlags, TcHandle};
use crate::net::arp;
use crate::tc::{TcAction, TcFlowerOptionFlags, TcHandle};
use crate::{EncKeyId, IpProtocol};
use crate::tc::filters::flower;

pub(crate) const TCA_FLOWER_CLASSID: u16 = 1;
pub(crate) const TCA_FLOWER_INDEV: u16 = 2;
Expand Down Expand Up @@ -287,7 +289,7 @@ pub enum TcFilterFlowerOption {
KeyCtMarkMask(u32),
KeyCtLabels(u128),
KeyCtLabelsMask(u128),
KeyMplsOpts(mpls::Options),
KeyMplsOpts(flower::mpls::Options),
KeyHash(u32),
KeyHashMask(u32),
KeyNumOfVlans(u8),
Expand Down Expand Up @@ -1556,7 +1558,7 @@ impl<'a, T: AsRef<[u8]> + ?Sized> Parseable<NlaBuffer<&'a T>>
Self::KeyCtLabels(parse_u128_be(payload)?)
}
TCA_FLOWER_KEY_MPLS_OPTS => {
Self::KeyMplsOpts(mpls::Options::parse(buf)?)
Self::KeyMplsOpts(flower::mpls::Options::parse(buf)?)
}
TCA_FLOWER_KEY_HASH => Self::KeyHash(parse_u32(payload)?),
TCA_FLOWER_KEY_HASH_MASK => Self::KeyHash(parse_u32(payload)?),
Expand Down
82 changes: 5 additions & 77 deletions src/tc/filters/flower/mpls.rs
Original file line number Diff line number Diff line change
@@ -1,83 +1,11 @@
use crate::tc::filters::cls_flower::TCA_FLOWER_KEY_MPLS_OPTS;
use anyhow::Error;
use netlink_packet_utils::nla::{
DefaultNla, Nla, NlaBuffer, NlasIterator, NLA_F_NESTED,
};
use netlink_packet_utils::parsers::{parse_u32, parse_u8};
use netlink_packet_utils::{DecodeError, Emitable, Parseable};

// The "bottom of stack" flag is only a single bit wide.
// For this reason, we can get away without marking this as non-exhaustive.
// It is represented as `u8` in the netlink message.
// I take this to mean that it functions like a c boolean and that any non-zero
// value is `Set`. I
/// Bottom of stack flag.
///
/// The "bottom of stack" flag is only a single bit wide.
/// For this reason, we can get away without marking this as non-exhaustive.
/// It is represented as `u8` in the netlink message.
/// I take this to mean that it functions like a c boolean and that any non-zero
/// value is `Set`.
#[derive(Debug, PartialEq, Eq, Clone, Copy, Ord, PartialOrd, Hash)]
#[repr(u8)]
pub enum BottomOfStack {
Unset = 0,
Set = 1,
}

impl From<u8> for BottomOfStack {
fn from(bos: u8) -> Self {
match bos {
0 => BottomOfStack::Unset,
1 => BottomOfStack::Set,
_ => {
log::warn!(
"Invalid BottomOfStack value: {}, interpreting as Set",
bos
);
BottomOfStack::Set
}
}
}
}

impl From<BottomOfStack> for u8 {
fn from(value: BottomOfStack) -> Self {
value as u8
}
}


#[derive(Debug, PartialEq, Eq, Clone, Copy, Ord, PartialOrd, Hash)]
#[repr(transparent)]
pub struct Label(u32);

/// TODO: should we add handling for reserved labels as per [RFC 3032][1] (see
/// page 4)?
///
/// [1]: https://www.iana.org/assignments/mpls-label-values/mpls-label-values.xhtml
impl Label {
pub fn try_new(label: u32) -> Result<Self, Error> {
if label > 0xFFFFF {
Err(Error::msg("MPLS label must be less than 0xFFFFF"))?
}
Ok(Self(label))
}
}

impl TryFrom<u32> for Label {
type Error = Error;

fn try_from(label: u32) -> Result<Self, Self::Error> {
Self::try_new(label)
}
}

impl From<Label> for u32 {
fn from(label: Label) -> u32 {
label.0
}
}
use crate::net::mpls;

#[derive(Debug, PartialEq, Eq, Clone)]
#[non_exhaustive]
Expand All @@ -90,9 +18,9 @@ pub enum Options {
#[non_exhaustive]
pub enum LseOptions {
Depth(u8),
Label(Label),
Label(mpls::Label),
TrafficClass(u8),
BottomOfStack(BottomOfStack),
BottomOfStack(mpls::BottomOfStack),
Ttl(u8),
}

Expand Down Expand Up @@ -200,13 +128,13 @@ impl<'a, T: AsRef<[u8]> + ?Sized> Parseable<NlaBuffer<&'a T>> for LseOptions {
}
TCA_FLOWER_KEY_MPLS_OPT_LSE_TTL => Self::Ttl(parse_u8(payload)?),
TCA_FLOWER_KEY_MPLS_OPT_LSE_BOS => {
Self::BottomOfStack(BottomOfStack::from(parse_u8(payload)?))
Self::BottomOfStack(mpls::BottomOfStack::from(parse_u8(payload)?))
}
TCA_FLOWER_KEY_MPLS_OPT_LSE_TC => {
Self::TrafficClass(parse_u8(payload)?)
}
TCA_FLOWER_KEY_MPLS_OPT_LSE_LABEL => {
Self::Label(Label::try_from(parse_u32(payload)?)?)
Self::Label(mpls::Label::try_from(parse_u32(payload)?)?)
}
_ => Err(DecodeError::from("invalid mpls option kind"))?,
})
Expand Down
4 changes: 0 additions & 4 deletions src/tc/filters/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,9 @@ pub use self::matchall::{TcFilterMatchAll, TcFilterMatchAllOption};

pub mod flower;

pub mod arp;
mod cls_flags;
mod cls_flower;
mod cls_u32;
pub mod ethernet;
mod flower_flags;
pub mod icmpv4;
pub mod icmpv6;
mod matchall;
mod u32_flags;
9 changes: 4 additions & 5 deletions src/tc/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,10 @@ pub use self::actions::{
};
pub use self::attribute::TcAttribute;
pub use self::filters::{
arp, icmpv4, icmpv6, CfmAttribute, ConnectionTrackingFlags, L2Miss,
TcFilterFlower, TcFilterFlowerOption, TcFilterMatchAll,
TcFilterMatchAllOption, TcFilterU32, TcFilterU32Option,
TcFlowerOptionFlags, TcU32Key, TcU32OptionFlags, TcU32Selector,
TcU32SelectorFlags, TcpFlags,
CfmAttribute, ConnectionTrackingFlags, L2Miss, TcFilterFlower,
TcFilterFlowerOption, TcFilterMatchAll, TcFilterMatchAllOption,
TcFilterU32, TcFilterU32Option, TcFlowerOptionFlags, TcU32Key,
TcU32OptionFlags, TcU32Selector, TcU32SelectorFlags, TcpFlags,
};

pub use self::header::{TcHandle, TcHeader, TcMessageBuffer};
Expand Down

0 comments on commit 73b5380

Please sign in to comment.