diff --git a/Cargo.toml b/Cargo.toml index cfd2f833..164d2578 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -15,13 +15,12 @@ description = "netlink packet types" rich_nlas = [] [dependencies] -anyhow = "1.0.31" bitflags = "2" byteorder = "1.3.2" libc = "0.2.66" log = { version = "0.4.20", features = ["std"] } -netlink-packet-core = { version = "0.7.0" } -netlink-packet-utils = { version = "0.5.2" } +netlink-packet-core = { git = "https://github.com/rust-netlink/netlink-packet-core.git", rev = "01e8dd1" } +netlink-packet-utils = { version = "0.6.0" } [[example]] name = "dump_packet_links" diff --git a/src/address/attribute.rs b/src/address/attribute.rs index e7b90dc1..815207b4 100644 --- a/src/address/attribute.rs +++ b/src/address/attribute.rs @@ -3,7 +3,6 @@ use std::mem::size_of; use std::net::{IpAddr, Ipv4Addr, Ipv6Addr}; -use anyhow::Context; use byteorder::{ByteOrder, NativeEndian}; use netlink_packet_utils::{ nla::{DefaultNla, Nla, NlaBuffer}, @@ -107,10 +106,10 @@ impl Nla for AddressAttribute { } } -impl<'a, T: AsRef<[u8]> + ?Sized> Parseable> - for AddressAttribute -{ - fn parse(buf: &NlaBuffer<&'a T>) -> Result { +impl + ?Sized> Parseable> for AddressAttribute { + type Error = DecodeError; + + fn parse(buf: &NlaBuffer<&T>) -> Result { let payload = buf.value(); Ok(match buf.kind() { IFA_ADDRESS => { @@ -147,9 +146,7 @@ impl<'a, T: AsRef<[u8]> + ?Sized> Parseable> ))); } } - IFA_LABEL => Self::Label( - parse_string(payload).context("invalid IFA_LABEL value")?, - ), + IFA_LABEL => Self::Label(parse_string(payload)?), IFA_BROADCAST => { if payload.len() == IPV4_ADDR_LEN { let mut data = [0u8; IPV4_ADDR_LEN]; @@ -176,10 +173,9 @@ impl<'a, T: AsRef<[u8]> + ?Sized> Parseable> ))); } } - IFA_CACHEINFO => Self::CacheInfo( - CacheInfo::parse(&CacheInfoBuffer::new(payload)) - .context(format!("Invalid IFA_CACHEINFO {:?}", payload))?, - ), + IFA_CACHEINFO => Self::CacheInfo(CacheInfo::parse( + &CacheInfoBuffer::new(payload), + )?), IFA_MULTICAST => { if payload.len() == IPV6_ADDR_LEN { let mut data = [0u8; IPV6_ADDR_LEN]; @@ -193,13 +189,10 @@ impl<'a, T: AsRef<[u8]> + ?Sized> Parseable> ))); } } - IFA_FLAGS => Self::Flags(AddressFlags::from_bits_retain( - parse_u32(payload).context("invalid IFA_FLAGS value")?, - )), - kind => Self::Other( - DefaultNla::parse(buf) - .context(format!("unknown NLA type {kind}"))?, - ), + IFA_FLAGS => { + Self::Flags(AddressFlags::from_bits_retain(parse_u32(payload)?)) + } + _ => Self::Other(DefaultNla::parse(buf)?), }) } } diff --git a/src/address/cache_info.rs b/src/address/cache_info.rs index b23edde1..5ef06186 100644 --- a/src/address/cache_info.rs +++ b/src/address/cache_info.rs @@ -24,7 +24,9 @@ buffer!(CacheInfoBuffer(ADDRESSS_CACHE_INFO_LEN) { }); impl> Parseable> for CacheInfo { - fn parse(buf: &CacheInfoBuffer) -> Result { + type Error = DecodeError; + + fn parse(buf: &CacheInfoBuffer) -> Result { Ok(CacheInfo { ifa_preferred: buf.ifa_preferred(), ifa_valid: buf.ifa_valid(), diff --git a/src/address/message.rs b/src/address/message.rs index d8d9bd0e..71022d51 100644 --- a/src/address/message.rs +++ b/src/address/message.rs @@ -1,8 +1,7 @@ // SPDX-License-Identifier: MIT -use anyhow::Context; use netlink_packet_utils::{ - nla::{NlaBuffer, NlasIterator}, + nla::{NlaBuffer, NlaError, NlasIterator}, traits::{Emitable, Parseable}, DecodeError, }; @@ -23,10 +22,10 @@ buffer!(AddressMessageBuffer(ADDRESS_HEADER_LEN) { payload: (slice, ADDRESS_HEADER_LEN..), }); -impl<'a, T: AsRef<[u8]> + ?Sized> AddressMessageBuffer<&'a T> { +impl + ?Sized> AddressMessageBuffer<&T> { pub fn attributes( &self, - ) -> impl Iterator, DecodeError>> { + ) -> impl Iterator, NlaError>> { NlasIterator::new(self.payload()) } } @@ -76,7 +75,9 @@ impl Emitable for AddressMessage { } impl> Parseable> for AddressHeader { - fn parse(buf: &AddressMessageBuffer) -> Result { + type Error = DecodeError; + + fn parse(buf: &AddressMessageBuffer) -> Result { Ok(Self { family: buf.family().into(), prefix_len: buf.prefix_len(), @@ -87,23 +88,23 @@ impl> Parseable> for AddressHeader { } } -impl<'a, T: AsRef<[u8]> + 'a> Parseable> - for AddressMessage -{ - fn parse(buf: &AddressMessageBuffer<&'a T>) -> Result { +impl> Parseable> for AddressMessage { + type Error = DecodeError; + + fn parse(buf: &AddressMessageBuffer<&T>) -> Result { Ok(AddressMessage { - header: AddressHeader::parse(buf) - .context("failed to parse address message header")?, - attributes: Vec::::parse(buf) - .context("failed to parse address message NLAs")?, + header: AddressHeader::parse(buf)?, + attributes: Vec::::parse(buf)?, }) } } -impl<'a, T: AsRef<[u8]> + 'a> Parseable> +impl> Parseable> for Vec { - fn parse(buf: &AddressMessageBuffer<&'a T>) -> Result { + type Error = DecodeError; + + fn parse(buf: &AddressMessageBuffer<&T>) -> Result { let mut attributes = vec![]; for nla_buf in buf.attributes() { attributes.push(AddressAttribute::parse(&nla_buf?)?); diff --git a/src/link/af_spec/bridge.rs b/src/link/af_spec/bridge.rs index 9b88712f..d5069a79 100644 --- a/src/link/af_spec/bridge.rs +++ b/src/link/af_spec/bridge.rs @@ -1,6 +1,5 @@ // SPDX-License-Identifier: MIT -use anyhow::Context; use byteorder::{ByteOrder, NativeEndian}; use netlink_packet_utils::{ nla::{DefaultNla, Nla, NlaBuffer, NlasIterator}, @@ -65,39 +64,26 @@ impl Nla for AfSpecBridge { } } -impl<'a, T: AsRef<[u8]> + ?Sized> Parseable> for AfSpecBridge { - fn parse(buf: &NlaBuffer<&'a T>) -> Result { +impl + ?Sized> Parseable> for AfSpecBridge { + type Error = DecodeError; + + fn parse(buf: &NlaBuffer<&T>) -> Result { let payload = buf.value(); Ok(match buf.kind() { - IFLA_BRIDGE_FLAGS => Self::Flags( - parse_u16(payload) - .context("Invalid IFLA_BRIDGE_FLAGS value")? - .into(), - ), - IFLA_BRIDGE_MODE => Self::Mode( - parse_u16(payload) - .context("Invalid IFLA_BRIDGE_MODE value")? - .into(), - ), - IFLA_BRIDGE_VLAN_INFO => Self::VlanInfo( - BridgeVlanInfo::try_from(payload) - .context("Invalid IFLA_BRIDGE_VLAN_INFO value")?, - ), + IFLA_BRIDGE_FLAGS => Self::Flags(parse_u16(payload)?.into()), + IFLA_BRIDGE_MODE => Self::Mode(parse_u16(payload)?.into()), + IFLA_BRIDGE_VLAN_INFO => { + Self::VlanInfo(BridgeVlanInfo::try_from(payload)?) + } IFLA_BRIDGE_VLAN_TUNNEL_INFO => { let mut nlas = Vec::new(); for nla in NlasIterator::new(payload) { - let nla = &nla.context(format!( - "Invalid IFLA_BRIDGE_VLAN_TUNNEL_INFO for {payload:?}" - ))?; - let parsed = BridgeVlanTunnelInfo::parse(nla)?; + let parsed = BridgeVlanTunnelInfo::parse(&nla?)?; nlas.push(parsed); } Self::VlanTunnelInfo(nlas) } - kind => Self::Other( - DefaultNla::parse(buf) - .context(format!("Unknown NLA type {kind}"))?, - ), + _ => Self::Other(DefaultNla::parse(buf)?), }) } } @@ -106,15 +92,13 @@ impl<'a, T: AsRef<[u8]> + ?Sized> Parseable> for AfSpecBridge { pub(crate) struct VecAfSpecBridge(pub(crate) Vec); #[cfg(any(target_os = "linux", target_os = "fuchsia"))] -impl<'a, T: AsRef<[u8]> + ?Sized> Parseable> - for VecAfSpecBridge -{ - fn parse(buf: &NlaBuffer<&'a T>) -> Result { +impl + ?Sized> Parseable> for VecAfSpecBridge { + type Error = DecodeError; + + fn parse(buf: &NlaBuffer<&T>) -> Result { let mut nlas = vec![]; - let err = "Invalid AF_INET NLA for IFLA_AF_SPEC(AF_BRIDGE)"; for nla in NlasIterator::new(buf.into_inner()) { - let nla = nla.context(err)?; - nlas.push(AfSpecBridge::parse(&nla).context(err)?); + nlas.push(AfSpecBridge::parse(&nla?)?); } Ok(Self(nlas)) } @@ -178,14 +162,10 @@ impl TryFrom<&[u8]> for BridgeVlanInfo { fn try_from(raw: &[u8]) -> Result { if raw.len() == 4 { Ok(Self { - flags: BridgeVlanInfoFlags::from_bits_retain( - parse_u16(&raw[0..2]).context(format!( - "Invalid IFLA_BRIDGE_VLAN_INFO value: {raw:?}" - ))?, - ), - vid: parse_u16(&raw[2..4]).context(format!( - "Invalid IFLA_BRIDGE_VLAN_INFO value: {raw:?}" - ))?, + flags: BridgeVlanInfoFlags::from_bits_retain(parse_u16( + &raw[0..2], + )?), + vid: parse_u16(&raw[2..4])?, }) } else { Err(DecodeError::from(format!( @@ -313,32 +293,20 @@ impl Nla for BridgeVlanTunnelInfo { } } -impl<'a, T: AsRef<[u8]> + ?Sized> Parseable> +impl + ?Sized> Parseable> for BridgeVlanTunnelInfo { - fn parse(buf: &NlaBuffer<&'a T>) -> Result { + type Error = DecodeError; + + fn parse(buf: &NlaBuffer<&T>) -> Result { let payload = buf.value(); Ok(match buf.kind() { - IFLA_BRIDGE_VLAN_TUNNEL_ID => { - Self::Id(parse_u32(payload).context(format!( - "Invalid IFLA_BRIDGE_VLAN_TUNNEL_ID {payload:?}" - ))?) - } - IFLA_BRIDGE_VLAN_TUNNEL_VID => { - Self::Vid(parse_u16(payload).context(format!( - "Invalid IFLA_BRIDGE_VLAN_TUNNEL_VID {payload:?}" - ))?) - } - IFLA_BRIDGE_VLAN_TUNNEL_FLAGS => { - Self::Flags(BridgeVlanInfoFlags::from_bits_retain( - parse_u16(payload).context(format!( - "Invalid IFLA_BRIDGE_VLAN_TUNNEL_VID {payload:?}" - ))?, - )) - } - _ => { - Self::Other(DefaultNla::parse(buf).context("Unknown NLA type")?) - } + IFLA_BRIDGE_VLAN_TUNNEL_ID => Self::Id(parse_u32(payload)?), + IFLA_BRIDGE_VLAN_TUNNEL_VID => Self::Vid(parse_u16(payload)?), + IFLA_BRIDGE_VLAN_TUNNEL_FLAGS => Self::Flags( + BridgeVlanInfoFlags::from_bits_retain(parse_u16(payload)?), + ), + _ => Self::Other(DefaultNla::parse(buf)?), }) } } diff --git a/src/link/af_spec/inet.rs b/src/link/af_spec/inet.rs index b151507f..d366bc1e 100644 --- a/src/link/af_spec/inet.rs +++ b/src/link/af_spec/inet.rs @@ -1,6 +1,5 @@ // SPDX-License-Identifier: MIT -use anyhow::Context; use netlink_packet_utils::{ nla::{self, DefaultNla, NlaBuffer, NlasIterator}, traits::{Emitable, Parseable}, @@ -24,15 +23,13 @@ pub enum AfSpecInet { pub(crate) struct VecAfSpecInet(pub(crate) Vec); -impl<'a, T: AsRef<[u8]> + ?Sized> Parseable> - for VecAfSpecInet -{ - fn parse(buf: &NlaBuffer<&'a T>) -> Result { +impl + ?Sized> Parseable> for VecAfSpecInet { + type Error = DecodeError; + + fn parse(buf: &NlaBuffer<&T>) -> Result { let mut nlas = vec![]; - let err = "Invalid AF_INET NLA for IFLA_AF_SPEC(AF_UNSPEC)"; for nla in NlasIterator::new(buf.into_inner()) { - let nla = nla.context(err)?; - nlas.push(AfSpecInet::parse(&nla)?); + nlas.push(AfSpecInet::parse(&nla?)?); } Ok(Self(nlas)) } @@ -64,8 +61,10 @@ impl nla::Nla for AfSpecInet { } } -impl<'a, T: AsRef<[u8]> + ?Sized> Parseable> for AfSpecInet { - fn parse(buf: &NlaBuffer<&'a T>) -> Result { +impl + ?Sized> Parseable> for AfSpecInet { + type Error = DecodeError; + + fn parse(buf: &NlaBuffer<&T>) -> Result { use self::AfSpecInet::*; let payload = buf.value(); @@ -80,9 +79,7 @@ impl<'a, T: AsRef<[u8]> + ?Sized> Parseable> for AfSpecInet { .as_slice(), ))?) } - kind => Other(DefaultNla::parse(buf).context(format!( - "Unknown NLA type {kind} for IFLA_AF_SPEC(inet)" - ))?), + _ => Other(DefaultNla::parse(buf)?), }) } } @@ -162,7 +159,9 @@ pub struct InetDevConf { } impl> Parseable> for InetDevConf { - fn parse(buf: &InetDevConfBuffer) -> Result { + type Error = DecodeError; + + fn parse(buf: &InetDevConfBuffer) -> Result { Ok(Self { forwarding: buf.forwarding(), mc_forwarding: buf.mc_forwarding(), diff --git a/src/link/af_spec/inet6.rs b/src/link/af_spec/inet6.rs index b4034888..b9d05b6c 100644 --- a/src/link/af_spec/inet6.rs +++ b/src/link/af_spec/inet6.rs @@ -2,7 +2,6 @@ use std::net::Ipv6Addr; -use anyhow::Context; use byteorder::{ByteOrder, NativeEndian}; use netlink_packet_utils::{ nla::{DefaultNla, Nla, NlaBuffer, NlasIterator}, @@ -50,15 +49,13 @@ pub enum AfSpecInet6 { pub(crate) struct VecAfSpecInet6(pub(crate) Vec); -impl<'a, T: AsRef<[u8]> + ?Sized> Parseable> - for VecAfSpecInet6 -{ - fn parse(buf: &NlaBuffer<&'a T>) -> Result { +impl + ?Sized> Parseable> for VecAfSpecInet6 { + type Error = DecodeError; + + fn parse(buf: &NlaBuffer<&T>) -> Result { let mut nlas = vec![]; - let err = "Invalid AF_INET6 NLA for IFLA_AF_SPEC(AF_UNSPEC)"; for nla in NlasIterator::new(buf.into_inner()) { - let nla = nla.context(err)?; - nlas.push(AfSpecInet6::parse(&nla).context(err)?); + nlas.push(AfSpecInet6::parse(&nla?)?); } Ok(Self(nlas)) } @@ -110,50 +107,40 @@ impl Nla for AfSpecInet6 { } } -impl<'a, T: AsRef<[u8]> + ?Sized> Parseable> for AfSpecInet6 { - fn parse(buf: &NlaBuffer<&'a T>) -> Result { +impl + ?Sized> Parseable> for AfSpecInet6 { + type Error = DecodeError; + + fn parse(buf: &NlaBuffer<&T>) -> Result { use self::AfSpecInet6::*; let payload = buf.value(); Ok(match buf.kind() { - IFLA_INET6_FLAGS => Flags(Inet6IfaceFlags::from_bits_retain( - parse_u32(payload).context("invalid IFLA_INET6_FLAGS value")?, - )), - IFLA_INET6_CACHEINFO => CacheInfo( - Inet6CacheInfo::parse(&Inet6CacheInfoBuffer::new(payload)) - .context(format!( - "invalid IFLA_INET6_CACHEINFO value {:?}", - payload - ))?, - ), - IFLA_INET6_CONF => DevConf( - Inet6DevConf::parse(&Inet6DevConfBuffer::new( + IFLA_INET6_FLAGS => { + Flags(Inet6IfaceFlags::from_bits_retain(parse_u32(payload)?)) + } + IFLA_INET6_CACHEINFO => CacheInfo(Inet6CacheInfo::parse( + &Inet6CacheInfoBuffer::new(payload), + )?), + IFLA_INET6_CONF => { + DevConf(Inet6DevConf::parse(&Inet6DevConfBuffer::new( expand_buffer_if_small( payload, LINK_INET6_DEV_CONF_LEN, "IFLA_INET6_CONF", ) .as_slice(), - )) - .context(format!( - "invalid IFLA_INET6_CONF value {:?}", - payload - ))?, - ), - IFLA_INET6_STATS => Stats( - Inet6Stats::parse(&Inet6StatsBuffer::new( + ))?) + } + IFLA_INET6_STATS => { + Stats(Inet6Stats::parse(&Inet6StatsBuffer::new( expand_buffer_if_small( payload, INET6_STATS_LEN, "IFLA_INET6_STATS", ) .as_slice(), - )) - .context(format!( - "invalid IFLA_INET6_STATS value {:?}", - payload - ))?, - ), + ))?) + } IFLA_INET6_ICMP6STATS => Icmp6Stats( super::super::Icmp6Stats::parse(&Icmp6StatsBuffer::new( expand_buffer_if_small( @@ -162,27 +149,12 @@ impl<'a, T: AsRef<[u8]> + ?Sized> Parseable> for AfSpecInet6 { "IFLA_INET6_ICMP6STATS", ) .as_slice(), - )) - .context(format!( - "invalid IFLA_INET6_ICMP6STATS value {:?}", - payload ))?, ), - IFLA_INET6_TOKEN => Token( - parse_ipv6_addr(payload) - .context("invalid IFLA_INET6_TOKEN value")?, - ), - IFLA_INET6_ADDR_GEN_MODE => AddrGenMode( - parse_u8(payload) - .context("invalid IFLA_INET6_ADDR_GEN_MODE value")?, - ), - IFLA_INET6_RA_MTU => RaMtu( - parse_u32(payload) - .context("invalid IFLA_INET6_RA_MTU value")?, - ), - kind => Other(DefaultNla::parse(buf).context(format!( - "unknown AF_INET6 NLA type {kind} for IFLA_AF_SPEC(AF_UNSPEC)" - ))?), + IFLA_INET6_TOKEN => Token(parse_ipv6_addr(payload)?), + IFLA_INET6_ADDR_GEN_MODE => AddrGenMode(parse_u8(payload)?), + IFLA_INET6_RA_MTU => RaMtu(parse_u32(payload)?), + _ => Other(DefaultNla::parse(buf)?), }) } } diff --git a/src/link/af_spec/inet6_cache.rs b/src/link/af_spec/inet6_cache.rs index 8d28710d..40678ca6 100644 --- a/src/link/af_spec/inet6_cache.rs +++ b/src/link/af_spec/inet6_cache.rs @@ -24,7 +24,9 @@ buffer!(Inet6CacheInfoBuffer(LINK_INET6_CACHE_INFO_LEN) { }); impl> Parseable> for Inet6CacheInfo { - fn parse(buf: &Inet6CacheInfoBuffer) -> Result { + type Error = DecodeError; + + fn parse(buf: &Inet6CacheInfoBuffer) -> Result { Ok(Self { max_reasm_len: buf.max_reasm_len(), tstamp: buf.tstamp(), diff --git a/src/link/af_spec/inet6_devconf.rs b/src/link/af_spec/inet6_devconf.rs index f79f82f3..d94bdbf1 100644 --- a/src/link/af_spec/inet6_devconf.rs +++ b/src/link/af_spec/inet6_devconf.rs @@ -72,7 +72,9 @@ buffer!(Inet6DevConfBuffer(LINK_INET6_DEV_CONF_LEN) { }); impl> Parseable> for Inet6DevConf { - fn parse(buf: &Inet6DevConfBuffer) -> Result { + type Error = DecodeError; + + fn parse(buf: &Inet6DevConfBuffer) -> Result { Ok(Self { forwarding: buf.forwarding(), hoplimit: buf.hoplimit(), diff --git a/src/link/af_spec/inet6_icmp.rs b/src/link/af_spec/inet6_icmp.rs index dc2918eb..f343f110 100644 --- a/src/link/af_spec/inet6_icmp.rs +++ b/src/link/af_spec/inet6_icmp.rs @@ -28,7 +28,9 @@ buffer!(Icmp6StatsBuffer(ICMP6_STATS_LEN) { }); impl> Parseable> for Icmp6Stats { - fn parse(buf: &Icmp6StatsBuffer) -> Result { + type Error = DecodeError; + + fn parse(buf: &Icmp6StatsBuffer) -> Result { Ok(Self { num: buf.num(), in_msgs: buf.in_msgs(), diff --git a/src/link/af_spec/inet6_stats.rs b/src/link/af_spec/inet6_stats.rs index c850278e..163b0753 100644 --- a/src/link/af_spec/inet6_stats.rs +++ b/src/link/af_spec/inet6_stats.rs @@ -92,7 +92,9 @@ pub struct Inet6Stats { } impl> Parseable> for Inet6Stats { - fn parse(buf: &Inet6StatsBuffer) -> Result { + type Error = DecodeError; + + fn parse(buf: &Inet6StatsBuffer) -> Result { Ok(Self { num: buf.num(), in_pkts: buf.in_pkts(), diff --git a/src/link/af_spec/unspec.rs b/src/link/af_spec/unspec.rs index 57de4f85..ecff25b9 100644 --- a/src/link/af_spec/unspec.rs +++ b/src/link/af_spec/unspec.rs @@ -1,6 +1,5 @@ // SPDX-License-Identifier: MIT -use anyhow::Context; use netlink_packet_utils::{ nla::{DefaultNla, Nla, NlaBuffer, NlasIterator}, traits::{Emitable, Parseable}, @@ -48,37 +47,30 @@ pub(crate) struct VecAfSpecUnspec(pub(crate) Vec); impl<'a, T: AsRef<[u8]> + ?Sized> Parseable> for VecAfSpecUnspec { - fn parse(buf: &NlaBuffer<&'a T>) -> Result { + type Error = DecodeError; + + fn parse(buf: &NlaBuffer<&'a T>) -> Result { let mut nlas = vec![]; - let err = "Invalid NLA for IFLA_AF_SPEC(AF_UNSPEC)"; for nla in NlasIterator::new(buf.into_inner()) { - let nla = nla.context(err)?; + let nla = nla?; nlas.push(match nla.kind() { k if k == u8::from(AddressFamily::Inet) as u16 => { AfSpecUnspec::Inet( - VecAfSpecInet::parse( - &NlaBuffer::new_checked(&nla.value()) - .context(err)?, - ) - .context(err)? + VecAfSpecInet::parse(&NlaBuffer::new_checked( + &nla.value(), + )?)? .0, ) } k if k == u8::from(AddressFamily::Inet6) as u16 => { AfSpecUnspec::Inet6( - VecAfSpecInet6::parse( - &NlaBuffer::new_checked(&nla.value()) - .context(err)?, - ) - .context(err)? + VecAfSpecInet6::parse(&NlaBuffer::new_checked( + &nla.value(), + )?)? .0, ) } - kind => AfSpecUnspec::Other(DefaultNla::parse(&nla).context( - format!( - "Unknown AF_XXX type {kind} for IFLA_AF_SPEC(AF_UNSPEC)" - ), - )?), + _ => AfSpecUnspec::Other(DefaultNla::parse(&nla)?), }) } Ok(Self(nlas)) diff --git a/src/link/attribute.rs b/src/link/attribute.rs index cfbe3f8c..7032f4e9 100644 --- a/src/link/attribute.rs +++ b/src/link/attribute.rs @@ -2,7 +2,6 @@ use std::os::unix::io::RawFd; -use anyhow::Context; use byteorder::{ByteOrder, NativeEndian}; use netlink_packet_utils::{ nla::{DefaultNla, Nla, NlaBuffer, NlasIterator, NLA_F_NESTED}, @@ -364,25 +363,23 @@ impl Nla for LinkAttribute { } } -impl<'a, T: AsRef<[u8]> + ?Sized> - ParseableParametrized, AddressFamily> for LinkAttribute +impl + ?Sized> + ParseableParametrized, AddressFamily> for LinkAttribute { + type Error = DecodeError; + fn parse_with_param( - buf: &NlaBuffer<&'a T>, + buf: &NlaBuffer<&T>, interface_family: AddressFamily, - ) -> Result { + ) -> Result { let payload = buf.value(); Ok(match buf.kind() { IFLA_VFINFO_LIST => { - let err = - |payload| format!("invalid IFLA_VFINFO_LIST {payload:?}"); if !payload.is_empty() { Self::VfInfoList( - VecLinkVfInfo::parse( - &NlaBuffer::new_checked(payload) - .context(err(payload))?, - ) - .context(err(payload))? + VecLinkVfInfo::parse(&NlaBuffer::new_checked( + payload, + )?)? .0, ) } else { @@ -391,102 +388,46 @@ impl<'a, T: AsRef<[u8]> + ?Sized> Self::VfInfoList(vec![]) } } - IFLA_VF_PORTS => { - let err = - |payload| format!("invalid IFLA_VF_PORTS {payload:?}"); - Self::VfPorts( - VecLinkVfPort::parse( - &NlaBuffer::new_checked(payload) - .context(err(payload))?, - ) - .context(err(payload))? - .0, - ) - } - IFLA_PORT_SELF => { - let err = - |payload| format!("invalid IFLA_PORT_SELF {payload:?}"); - Self::PortSelf( - LinkVfPort::parse( - &NlaBuffer::new_checked(payload) - .context(err(payload))?, - ) - .context(err(payload))?, - ) - } - IFLA_PHYS_PORT_ID => { - Self::PhysPortId(LinkPhysId::parse(payload).context( - format!("invalid IFLA_PHYS_PORT_ID value {payload:?}"), - )?) - } + IFLA_VF_PORTS => Self::VfPorts( + VecLinkVfPort::parse(&NlaBuffer::new_checked(payload)?)?.0, + ), + IFLA_PORT_SELF => Self::PortSelf(LinkVfPort::parse( + &NlaBuffer::new_checked(payload)?, + )?), + IFLA_PHYS_PORT_ID => Self::PhysPortId(LinkPhysId::parse(payload)?), IFLA_PHYS_SWITCH_ID => { - Self::PhysSwitchId(LinkPhysId::parse(payload).context( - format!("invalid IFLA_PHYS_SWITCH_ID value {payload:?}"), - )?) + Self::PhysSwitchId(LinkPhysId::parse(payload)?) } - IFLA_WIRELESS => Self::Wireless( - LinkWirelessEvent::parse(payload) - .context(format!("invalid IFLA_WIRELESS {payload:?}"))?, - ), - IFLA_PROTINFO => { - let err = |payload| { - format!("invalid IFLA_PROTINFO for AF_INET6 {payload:?}") - }; - match interface_family { - AddressFamily::Inet6 => Self::ProtoInfoInet6( - VecLinkProtoInfoInet6::parse( - &NlaBuffer::new_checked(payload) - .context(err(payload))?, - ) - .context(err(payload))? - .0, - ), - #[cfg(any(target_os = "linux", target_os = "fuchsia",))] - AddressFamily::Bridge => Self::ProtoInfoBridge( - VecLinkProtoInfoBridge::parse(&NlaBuffer::new_checked( - payload, - )?) - .context(format!( - "invalid IFLA_PROTINFO for AF_INET6 {payload:?}" - ))? - .0, - ), - _ => Self::ProtoInfoUnknown( - DefaultNla::parse(buf).context(format!( - "invalid IFLA_PROTINFO for \ - {interface_family:?}: {payload:?}" - ))?, - ), - } + IFLA_WIRELESS => Self::Wireless(LinkWirelessEvent::parse(payload)?), + IFLA_PROTINFO => match interface_family { + AddressFamily::Inet6 => Self::ProtoInfoInet6( + VecLinkProtoInfoInet6::parse(&NlaBuffer::new_checked( + payload, + )?)? + .0, + ), + #[cfg(any(target_os = "linux", target_os = "fuchsia",))] + AddressFamily::Bridge => Self::ProtoInfoBridge( + VecLinkProtoInfoBridge::parse(&NlaBuffer::new_checked( + payload, + )?)? + .0, + ), + _ => Self::ProtoInfoUnknown(DefaultNla::parse(buf)?), + }, + IFLA_EVENT => Self::Event(LinkEvent::parse(payload)?), + IFLA_NEW_NETNSID => Self::NewNetnsId(parse_i32(payload)?), + IFLA_IF_NETNSID => Self::IfNetnsId(parse_i32(payload)?), + IFLA_CARRIER_UP_COUNT => Self::CarrierUpCount(parse_u32(payload)?), + IFLA_CARRIER_DOWN_COUNT => { + Self::CarrierDownCount(parse_u32(payload)?) } - IFLA_EVENT => Self::Event( - LinkEvent::parse(payload) - .context(format!("invalid IFLA_EVENT {payload:?}"))?, - ), - IFLA_NEW_NETNSID => Self::NewNetnsId( - parse_i32(payload).context("invalid IFLA_NEW_NETNSID value")?, - ), - IFLA_IF_NETNSID => Self::IfNetnsId( - parse_i32(payload).context("invalid IFLA_IF_NETNSID value")?, - ), - IFLA_CARRIER_UP_COUNT => Self::CarrierUpCount( - parse_u32(payload) - .context("invalid IFLA_CARRIER_UP_COUNT value")?, - ), - IFLA_CARRIER_DOWN_COUNT => Self::CarrierDownCount( - parse_u32(payload) - .context("invalid IFLA_CARRIER_DOWN_COUNT value")?, - ), - IFLA_NEW_IFINDEX => Self::NewIfIndex( - parse_i32(payload).context("invalid IFLA_NEW_IFINDEX value")?, - ), + IFLA_NEW_IFINDEX => Self::NewIfIndex(parse_i32(payload)?), IFLA_PROP_LIST => { - let error_msg = "invalid IFLA_PROP_LIST value"; let mut nlas = vec![]; for nla in NlasIterator::new(payload) { - let nla = &nla.context(error_msg)?; - let parsed = Prop::parse(nla).context(error_msg)?; + let parsed = Prop::parse(&nla?)?; nlas.push(parsed); } Self::PropList(nlas) @@ -494,9 +435,7 @@ impl<'a, T: AsRef<[u8]> + ?Sized> IFLA_PROTO_DOWN_REASON => { let mut nlas = vec![]; for nla in NlasIterator::new(payload) { - let nla = - &nla.context("invalid IFLA_PROTO_DOWN_REASON value")?; - let parsed = LinkProtocolDownReason::parse(nla)?; + let parsed = LinkProtocolDownReason::parse(&nla?)?; nlas.push(parsed); } Self::ProtoDownReason(nlas) @@ -508,181 +447,76 @@ impl<'a, T: AsRef<[u8]> + ?Sized> IFLA_BROADCAST => Self::Broadcast(payload.to_vec()), IFLA_PERM_ADDRESS => Self::PermAddress(payload.to_vec()), // String - IFLA_IFNAME => Self::IfName( - parse_string(payload).context("invalid IFLA_IFNAME value")?, - ), - IFLA_QDISC => Self::Qdisc( - parse_string(payload).context("invalid IFLA_QDISC value")?, - ), - IFLA_IFALIAS => Self::IfAlias( - parse_string(payload).context("invalid IFLA_IFALIAS value")?, - ), - IFLA_PHYS_PORT_NAME => Self::PhysPortName( - parse_string(payload) - .context("invalid IFLA_PHYS_PORT_NAME value")?, - ), - IFLA_LINKMODE => Self::Mode( - parse_u8(payload).context("invalid IFLA_LINKMODE value")?, - ), - IFLA_CARRIER => Self::Carrier( - parse_u8(payload).context("invalid IFLA_CARRIER value")?, - ), - IFLA_PROTO_DOWN => Self::ProtoDown( - parse_u8(payload).context("invalid IFLA_PROTO_DOWN value")?, - ), + IFLA_IFNAME => Self::IfName(parse_string(payload)?), + IFLA_QDISC => Self::Qdisc(parse_string(payload)?), + IFLA_IFALIAS => Self::IfAlias(parse_string(payload)?), + IFLA_PHYS_PORT_NAME => Self::PhysPortName(parse_string(payload)?), + IFLA_LINKMODE => Self::Mode(parse_u8(payload)?), + IFLA_CARRIER => Self::Carrier(parse_u8(payload)?), + IFLA_PROTO_DOWN => Self::ProtoDown(parse_u8(payload)?), - IFLA_MTU => { - Self::Mtu(parse_u32(payload).context("invalid IFLA_MTU value")?) + IFLA_MTU => Self::Mtu(parse_u32(payload)?), + IFLA_LINK => Self::Link(parse_u32(payload)?), + IFLA_MASTER => Self::Controller(parse_u32(payload)?), + IFLA_TXQLEN => Self::TxQueueLen(parse_u32(payload)?), + IFLA_NET_NS_PID => Self::NetNsPid(parse_u32(payload)?), + IFLA_NUM_VF => Self::NumVf(parse_u32(payload)?), + IFLA_GROUP => Self::Group(parse_u32(payload)?), + IFLA_NET_NS_FD => Self::NetNsFd(parse_i32(payload)?), + IFLA_EXT_MASK => { + Self::ExtMask(VecLinkExtentMask::from(parse_u32(payload)?).0) } - IFLA_LINK => Self::Link( - parse_u32(payload).context("invalid IFLA_LINK value")?, - ), - IFLA_MASTER => Self::Controller( - parse_u32(payload).context("invalid IFLA_MASTER value")?, - ), - IFLA_TXQLEN => Self::TxQueueLen( - parse_u32(payload).context("invalid IFLA_TXQLEN value")?, - ), - IFLA_NET_NS_PID => Self::NetNsPid( - parse_u32(payload).context("invalid IFLA_NET_NS_PID value")?, - ), - IFLA_NUM_VF => Self::NumVf( - parse_u32(payload).context("invalid IFLA_NUM_VF value")?, - ), - IFLA_GROUP => Self::Group( - parse_u32(payload).context("invalid IFLA_GROUP value")?, - ), - IFLA_NET_NS_FD => Self::NetNsFd( - parse_i32(payload).context("invalid IFLA_NET_NS_FD value")?, - ), - IFLA_EXT_MASK => Self::ExtMask( - VecLinkExtentMask::from( - parse_u32(payload) - .context("invalid IFLA_EXT_MASK value")?, - ) - .0, - ), - IFLA_PROMISCUITY => Self::Promiscuity( - parse_u32(payload).context("invalid IFLA_PROMISCUITY value")?, - ), - IFLA_NUM_TX_QUEUES => Self::NumTxQueues( - parse_u32(payload) - .context("invalid IFLA_NUM_TX_QUEUES value")?, - ), - IFLA_NUM_RX_QUEUES => Self::NumRxQueues( - parse_u32(payload) - .context("invalid IFLA_NUM_RX_QUEUES value")?, - ), - IFLA_CARRIER_CHANGES => Self::CarrierChanges( - parse_u32(payload) - .context("invalid IFLA_CARRIER_CHANGES value")?, - ), - IFLA_GSO_MAX_SEGS => Self::GsoMaxSegs( - parse_u32(payload) - .context("invalid IFLA_GSO_MAX_SEGS value")?, - ), - IFLA_GSO_MAX_SIZE => Self::GsoMaxSize( - parse_u32(payload) - .context("invalid IFLA_GSO_MAX_SIZE value")?, - ), - IFLA_MIN_MTU => Self::MinMtu( - parse_u32(payload).context("invalid IFLA_MIN_MTU value")?, - ), - IFLA_MAX_MTU => Self::MaxMtu( - parse_u32(payload).context("invalid IFLA_MAX_MTU value")?, - ), - IFLA_LINK_NETNSID => Self::LinkNetNsId( - parse_i32(payload) - .context("invalid IFLA_LINK_NETNSID value")?, - ), - IFLA_OPERSTATE => Self::OperState( - parse_u8(payload) - .context("invalid IFLA_OPERSTATE value")? - .into(), - ), + IFLA_PROMISCUITY => Self::Promiscuity(parse_u32(payload)?), + IFLA_NUM_TX_QUEUES => Self::NumTxQueues(parse_u32(payload)?), + IFLA_NUM_RX_QUEUES => Self::NumRxQueues(parse_u32(payload)?), + IFLA_CARRIER_CHANGES => Self::CarrierChanges(parse_u32(payload)?), + IFLA_GSO_MAX_SEGS => Self::GsoMaxSegs(parse_u32(payload)?), + IFLA_GSO_MAX_SIZE => Self::GsoMaxSize(parse_u32(payload)?), + IFLA_MIN_MTU => Self::MinMtu(parse_u32(payload)?), + IFLA_MAX_MTU => Self::MaxMtu(parse_u32(payload)?), + IFLA_LINK_NETNSID => Self::LinkNetNsId(parse_i32(payload)?), + IFLA_OPERSTATE => Self::OperState(parse_u8(payload)?.into()), IFLA_MAP => { - let err = - |payload| format!("Invalid IFLA_MAP value {:?}", payload); - Self::Map( - super::Map::parse( - &MapBuffer::new_checked(payload) - .context(err(payload))?, - ) - .context(err(payload))?, - ) + Self::Map(super::Map::parse(&MapBuffer::new_checked(payload)?)?) } - IFLA_STATS => Self::Stats( - super::Stats::parse(&StatsBuffer::new( - expand_buffer_if_small( - payload, - LINK_STATS_LEN, - "IFLA_STATS", - ) + IFLA_STATS => Self::Stats(super::Stats::parse(&StatsBuffer::new( + expand_buffer_if_small(payload, LINK_STATS_LEN, "IFLA_STATS") .as_slice(), - )) - .context(format!("Invalid IFLA_STATS value {:?}", payload))?, - ), + ))?), IFLA_STATS64 => { let payload = expand_buffer_if_small( payload, LINK_STATS64_LEN, "IFLA_STATS64", ); - Self::Stats64( - super::Stats64::parse(&Stats64Buffer::new( - payload.as_slice(), - )) - .context(format!( - "Invalid IFLA_STATS64 value {:?}", - payload - ))?, - ) + Self::Stats64(super::Stats64::parse(&Stats64Buffer::new( + payload.as_slice(), + ))?) } IFLA_AF_SPEC => match interface_family { - AddressFamily::Unspec => { - let err = "invalid IFLA_AF_SPEC value for AF_UNSPEC"; - Self::AfSpecUnspec( - VecAfSpecUnspec::parse( - &NlaBuffer::new_checked(&buf.value()) - .context(err)?, - ) - .context(err)? - .0, - ) - } + AddressFamily::Unspec => Self::AfSpecUnspec( + VecAfSpecUnspec::parse(&NlaBuffer::new_checked( + &buf.value(), + )?)? + .0, + ), #[cfg(any(target_os = "linux", target_os = "fuchsia",))] - AddressFamily::Bridge => { - let err = "invalid IFLA_AF_SPEC value for AF_BRIDGE"; - Self::AfSpecBridge( - VecAfSpecBridge::parse( - &NlaBuffer::new_checked(&buf.value()) - .context(err)?, - ) - .context(err)? - .0, - ) - } + AddressFamily::Bridge => Self::AfSpecBridge( + VecAfSpecBridge::parse(&NlaBuffer::new_checked( + &buf.value(), + )?)? + .0, + ), _ => Self::AfSpecUnknown(payload.to_vec()), }, - IFLA_LINKINFO => { - let err = "invalid IFLA_LINKINFO value"; - Self::LinkInfo( - VecLinkInfo::parse( - &NlaBuffer::new_checked(&buf.value()).context(err)?, - ) - .context(err)? - .0, - ) - } + IFLA_LINKINFO => Self::LinkInfo( + VecLinkInfo::parse(&NlaBuffer::new_checked(&buf.value())?)?.0, + ), IFLA_XDP => { - let err = "invalid IFLA_XDP value"; - let buf = NlaBuffer::new_checked(payload).context(err)?; - Self::Xdp(VecLinkXdp::parse(&buf).context(err)?.0) + let buf = NlaBuffer::new_checked(payload)?; + Self::Xdp(VecLinkXdp::parse(&buf)?.0) } - kind => Self::Other( - DefaultNla::parse(buf) - .context(format!("unknown NLA type {kind}"))?, - ), + _ => Self::Other(DefaultNla::parse(buf)?), }) } } diff --git a/src/link/down_reason.rs b/src/link/down_reason.rs index a542e8fb..34bf31b1 100644 --- a/src/link/down_reason.rs +++ b/src/link/down_reason.rs @@ -1,6 +1,5 @@ // SPDX-License-Identifier: MIT -use anyhow::Context; use byteorder::{ByteOrder, NativeEndian}; use netlink_packet_utils::{ nla::{DefaultNla, Nla, NlaBuffer}, @@ -19,26 +18,17 @@ pub enum LinkProtocolDownReason { Other(DefaultNla), } -impl<'a, T: AsRef<[u8]> + ?Sized> Parseable> +impl + ?Sized> Parseable> for LinkProtocolDownReason { - fn parse(buf: &NlaBuffer<&'a T>) -> Result { + type Error = DecodeError; + + fn parse(buf: &NlaBuffer<&T>) -> Result { let payload = buf.value(); Ok(match buf.kind() { - IFLA_PROTO_DOWN_REASON_MASK => { - Self::Mask(parse_u32(payload).context(format!( - "invalid IFLA_PROTO_DOWN_REASON_MASK {payload:?}" - ))?) - } - IFLA_PROTO_DOWN_REASON_VALUE => { - Self::Value(parse_u32(payload).context(format!( - "invalid IFLA_PROTO_DOWN_REASON_MASK {payload:?}" - ))?) - } - kind => Self::Other(DefaultNla::parse(buf).context(format!( - "unknown NLA type {kind} for IFLA_PROTO_DOWN_REASON: \ - {payload:?}" - ))?), + IFLA_PROTO_DOWN_REASON_MASK => Self::Mask(parse_u32(payload)?), + IFLA_PROTO_DOWN_REASON_VALUE => Self::Value(parse_u32(payload)?), + _ => Self::Other(DefaultNla::parse(buf)?), }) } } diff --git a/src/link/event.rs b/src/link/event.rs index 634ff91e..1c433ea4 100644 --- a/src/link/event.rs +++ b/src/link/event.rs @@ -1,6 +1,5 @@ // SPDX-License-Identifier: MIT -use anyhow::Context; use byteorder::{ByteOrder, NativeEndian}; use netlink_packet_utils::{ parsers::parse_u32, DecodeError, Emitable, Parseable, @@ -59,10 +58,10 @@ impl From for u32 { } impl + ?Sized> Parseable for LinkEvent { - fn parse(buf: &T) -> Result { - Ok(LinkEvent::from( - parse_u32(buf.as_ref()).context("invalid IFLA_EVENT value")?, - )) + type Error = DecodeError; + + fn parse(buf: &T) -> Result { + Ok(LinkEvent::from(parse_u32(buf.as_ref())?)) } } diff --git a/src/link/header.rs b/src/link/header.rs index d92a642f..c8b5d757 100644 --- a/src/link/header.rs +++ b/src/link/header.rs @@ -1,7 +1,7 @@ // SPDX-License-Identifier: MIT use netlink_packet_utils::{ - nla::{NlaBuffer, NlasIterator}, + nla::{NlaBuffer, NlaError, NlasIterator}, traits::{Emitable, Parseable}, DecodeError, }; @@ -25,7 +25,7 @@ buffer!(LinkMessageBuffer(LINK_HEADER_LEN) { impl<'a, T: AsRef<[u8]> + ?Sized> LinkMessageBuffer<&'a T> { pub fn attributes( &self, - ) -> impl Iterator, DecodeError>> { + ) -> impl Iterator, NlaError>> { NlasIterator::new(self.payload()) } } @@ -86,7 +86,9 @@ impl Emitable for LinkHeader { } impl> Parseable> for LinkHeader { - fn parse(buf: &LinkMessageBuffer) -> Result { + type Error = DecodeError; + + fn parse(buf: &LinkMessageBuffer) -> Result { Ok(Self { interface_family: buf.interface_family().into(), link_layer_type: buf.link_layer_type().into(), diff --git a/src/link/link_info/bond.rs b/src/link/link_info/bond.rs index e6c225b6..e21800e6 100644 --- a/src/link/link_info/bond.rs +++ b/src/link/link_info/bond.rs @@ -5,7 +5,6 @@ use std::{ ops::Deref, }; -use anyhow::Context; use byteorder::{ByteOrder, NativeEndian}; use netlink_packet_utils::{ nla::{DefaultNla, Nla, NlaBuffer, NlasIterator}, @@ -118,34 +117,24 @@ impl Nla for BondAdInfo { } } -impl<'a, T: AsRef<[u8]> + ?Sized> Parseable> for BondAdInfo { - fn parse(buf: &NlaBuffer<&'a T>) -> Result { +impl + ?Sized> Parseable> for BondAdInfo { + type Error = DecodeError; + + fn parse(buf: &NlaBuffer<&T>) -> Result { let payload = buf.value(); Ok(match buf.kind() { - IFLA_BOND_AD_INFO_AGGREGATOR => Self::Aggregator( - parse_u16(payload) - .context("invalid IFLA_BOND_AD_INFO_AGGREGATOR value")?, - ), - IFLA_BOND_AD_INFO_NUM_PORTS => Self::NumPorts( - parse_u16(payload) - .context("invalid IFLA_BOND_AD_INFO_NUM_PORTS value")?, - ), - IFLA_BOND_AD_INFO_ACTOR_KEY => Self::ActorKey( - parse_u16(payload) - .context("invalid IFLA_BOND_AD_INFO_ACTOR_KEY value")?, - ), - IFLA_BOND_AD_INFO_PARTNER_KEY => Self::PartnerKey( - parse_u16(payload) - .context("invalid IFLA_BOND_AD_INFO_PARTNER_KEY value")?, - ), - IFLA_BOND_AD_INFO_PARTNER_MAC => Self::PartnerMac( - parse_mac(payload) - .context("invalid IFLA_BOND_AD_INFO_PARTNER_MAC value")?, - ), - _ => Self::Other(DefaultNla::parse(buf).context(format!( - "invalid NLA for {}: {payload:?}", - buf.kind() - ))?), + IFLA_BOND_AD_INFO_AGGREGATOR => { + Self::Aggregator(parse_u16(payload)?) + } + IFLA_BOND_AD_INFO_NUM_PORTS => Self::NumPorts(parse_u16(payload)?), + IFLA_BOND_AD_INFO_ACTOR_KEY => Self::ActorKey(parse_u16(payload)?), + IFLA_BOND_AD_INFO_PARTNER_KEY => { + Self::PartnerKey(parse_u16(payload)?) + } + IFLA_BOND_AD_INFO_PARTNER_MAC => { + Self::PartnerMac(parse_mac(payload)?) + } + _ => Self::Other(DefaultNla::parse(buf)?), }) } } @@ -500,159 +489,87 @@ impl Nla for InfoBond { } } -impl<'a, T: AsRef<[u8]> + ?Sized> Parseable> for InfoBond { - fn parse(buf: &NlaBuffer<&'a T>) -> Result { +impl + ?Sized> Parseable> for InfoBond { + type Error = DecodeError; + + fn parse(buf: &NlaBuffer<&T>) -> Result { let payload = buf.value(); Ok(match buf.kind() { - IFLA_BOND_MODE => Self::Mode( - parse_u8(payload) - .context("invalid IFLA_BOND_MODE value")? - .into(), - ), - IFLA_BOND_ACTIVE_PORT => Self::ActivePort( - parse_u32(payload) - .context("invalid IFLA_BOND_ACTIVE_PORT value")?, - ), - IFLA_BOND_MIIMON => Self::MiiMon( - parse_u32(payload).context("invalid IFLA_BOND_MIIMON value")?, - ), - IFLA_BOND_UPDELAY => Self::UpDelay( - parse_u32(payload) - .context("invalid IFLA_BOND_UPDELAY value")?, - ), - IFLA_BOND_DOWNDELAY => Self::DownDelay( - parse_u32(payload) - .context("invalid IFLA_BOND_DOWNDELAY value")?, - ), - IFLA_BOND_USE_CARRIER => Self::UseCarrier( - parse_u8(payload) - .context("invalid IFLA_BOND_USE_CARRIER value")?, - ), - IFLA_BOND_ARP_INTERVAL => Self::ArpInterval( - parse_u32(payload) - .context("invalid IFLA_BOND_ARP_INTERVAL value")?, - ), + IFLA_BOND_MODE => Self::Mode(parse_u8(payload)?.into()), + IFLA_BOND_ACTIVE_PORT => Self::ActivePort(parse_u32(payload)?), + IFLA_BOND_MIIMON => Self::MiiMon(parse_u32(payload)?), + IFLA_BOND_UPDELAY => Self::UpDelay(parse_u32(payload)?), + IFLA_BOND_DOWNDELAY => Self::DownDelay(parse_u32(payload)?), + IFLA_BOND_USE_CARRIER => Self::UseCarrier(parse_u8(payload)?), + IFLA_BOND_ARP_INTERVAL => Self::ArpInterval(parse_u32(payload)?), IFLA_BOND_ARP_IP_TARGET => { let mut addrs = Vec::::new(); for nla in NlasIterator::new(payload) { - let nla = - &nla.context("invalid IFLA_BOND_ARP_IP_TARGET value")?; - if let Ok(IpAddr::V4(addr)) = parse_ip(nla.value()) { + if let Ok(IpAddr::V4(addr)) = parse_ip(nla?.value()) { addrs.push(addr); } } Self::ArpIpTarget(addrs) } - IFLA_BOND_ARP_VALIDATE => Self::ArpValidate( - parse_u32(payload) - .context("invalid IFLA_BOND_ARP_VALIDATE value")? - .into(), - ), - IFLA_BOND_ARP_ALL_TARGETS => Self::ArpAllTargets( - parse_u32(payload) - .context("invalid IFLA_BOND_ARP_ALL_TARGETS value")?, - ), - IFLA_BOND_PRIMARY => Self::Primary( - parse_u32(payload) - .context("invalid IFLA_BOND_PRIMARY value")?, - ), - IFLA_BOND_PRIMARY_RESELECT => Self::PrimaryReselect( - parse_u8(payload) - .context("invalid IFLA_BOND_PRIMARY_RESELECT value")?, - ), - IFLA_BOND_FAIL_OVER_MAC => Self::FailOverMac( - parse_u8(payload) - .context("invalid IFLA_BOND_FAIL_OVER_MAC value")?, - ), - IFLA_BOND_XMIT_HASH_POLICY => Self::XmitHashPolicy( - parse_u8(payload) - .context("invalid IFLA_BOND_XMIT_HASH_POLICY value")?, - ), - IFLA_BOND_RESEND_IGMP => Self::ResendIgmp( - parse_u32(payload) - .context("invalid IFLA_BOND_RESEND_IGMP value")?, - ), - IFLA_BOND_NUM_PEER_NOTIF => Self::NumPeerNotif( - parse_u8(payload) - .context("invalid IFLA_BOND_NUM_PEER_NOTIF value")?, - ), - IFLA_BOND_ALL_PORTS_ACTIVE => Self::AllPortsActive( - parse_u8(payload) - .context("invalid IFLA_BOND_ALL_PORTS_ACTIVE value")?, - ), - IFLA_BOND_MIN_LINKS => Self::MinLinks( - parse_u32(payload) - .context("invalid IFLA_BOND_MIN_LINKS value")?, - ), - IFLA_BOND_LP_INTERVAL => Self::LpInterval( - parse_u32(payload) - .context("invalid IFLA_BOND_LP_INTERVAL value")?, - ), - IFLA_BOND_PACKETS_PER_PORT => Self::PacketsPerPort( - parse_u32(payload) - .context("invalid IFLA_BOND_PACKETS_PER_PORT value")?, - ), - IFLA_BOND_AD_LACP_RATE => Self::AdLacpRate( - parse_u8(payload) - .context("invalid IFLA_BOND_AD_LACP_RATE value")?, - ), - IFLA_BOND_AD_SELECT => Self::AdSelect( - parse_u8(payload) - .context("invalid IFLA_BOND_AD_SELECT value")?, - ), + IFLA_BOND_ARP_VALIDATE => { + Self::ArpValidate(parse_u32(payload)?.into()) + } + IFLA_BOND_ARP_ALL_TARGETS => { + Self::ArpAllTargets(parse_u32(payload)?) + } + IFLA_BOND_PRIMARY => Self::Primary(parse_u32(payload)?), + IFLA_BOND_PRIMARY_RESELECT => { + Self::PrimaryReselect(parse_u8(payload)?) + } + IFLA_BOND_FAIL_OVER_MAC => Self::FailOverMac(parse_u8(payload)?), + IFLA_BOND_XMIT_HASH_POLICY => { + Self::XmitHashPolicy(parse_u8(payload)?) + } + IFLA_BOND_RESEND_IGMP => Self::ResendIgmp(parse_u32(payload)?), + IFLA_BOND_NUM_PEER_NOTIF => Self::NumPeerNotif(parse_u8(payload)?), + IFLA_BOND_ALL_PORTS_ACTIVE => { + Self::AllPortsActive(parse_u8(payload)?) + } + IFLA_BOND_MIN_LINKS => Self::MinLinks(parse_u32(payload)?), + IFLA_BOND_LP_INTERVAL => Self::LpInterval(parse_u32(payload)?), + IFLA_BOND_PACKETS_PER_PORT => { + Self::PacketsPerPort(parse_u32(payload)?) + } + IFLA_BOND_AD_LACP_RATE => Self::AdLacpRate(parse_u8(payload)?), + IFLA_BOND_AD_SELECT => Self::AdSelect(parse_u8(payload)?), IFLA_BOND_AD_INFO => { let mut infos = Vec::new(); - let err = "failed to parse IFLA_BOND_AD_INFO"; for nla in NlasIterator::new(payload) { - let nla = &nla.context(err)?; - let info = BondAdInfo::parse(nla).context(err)?; + let info = BondAdInfo::parse(&nla?)?; infos.push(info); } Self::AdInfo(infos) } - IFLA_BOND_AD_ACTOR_SYS_PRIO => Self::AdActorSysPrio( - parse_u16(payload) - .context("invalid IFLA_BOND_AD_ACTOR_SYS_PRIO value")?, - ), - IFLA_BOND_AD_USER_PORT_KEY => Self::AdUserPortKey( - parse_u16(payload) - .context("invalid IFLA_BOND_AD_USER_PORT_KEY value")?, - ), - IFLA_BOND_AD_ACTOR_SYSTEM => Self::AdActorSystem( - parse_mac(payload) - .context("invalid IFLA_BOND_AD_ACTOR_SYSTEM value")?, - ), - IFLA_BOND_TLB_DYNAMIC_LB => Self::TlbDynamicLb( - parse_u8(payload) - .context("invalid IFLA_BOND_TLB_DYNAMIC_LB value")?, - ), - IFLA_BOND_PEER_NOTIF_DELAY => Self::PeerNotifDelay( - parse_u32(payload) - .context("invalid IFLA_BOND_PEER_NOTIF_DELAY value")?, - ), - IFLA_BOND_AD_LACP_ACTIVE => Self::AdLacpActive( - parse_u8(payload) - .context("invalid IFLA_BOND_AD_LACP_ACTIVE value")?, - ), - IFLA_BOND_MISSED_MAX => Self::MissedMax( - parse_u8(payload) - .context("invalid IFLA_BOND_MISSED_MAX value")?, - ), + IFLA_BOND_AD_ACTOR_SYS_PRIO => { + Self::AdActorSysPrio(parse_u16(payload)?) + } + IFLA_BOND_AD_USER_PORT_KEY => { + Self::AdUserPortKey(parse_u16(payload)?) + } + IFLA_BOND_AD_ACTOR_SYSTEM => { + Self::AdActorSystem(parse_mac(payload)?) + } + IFLA_BOND_TLB_DYNAMIC_LB => Self::TlbDynamicLb(parse_u8(payload)?), + IFLA_BOND_PEER_NOTIF_DELAY => { + Self::PeerNotifDelay(parse_u32(payload)?) + } + IFLA_BOND_AD_LACP_ACTIVE => Self::AdLacpActive(parse_u8(payload)?), + IFLA_BOND_MISSED_MAX => Self::MissedMax(parse_u8(payload)?), IFLA_BOND_NS_IP6_TARGET => { let mut addrs = Vec::::new(); for nla in NlasIterator::new(payload) { - let nla = - &nla.context("invalid IFLA_BOND_NS_IP6_TARGET value")?; - if let Ok(IpAddr::V6(addr)) = parse_ip(nla.value()) { + if let Ok(IpAddr::V6(addr)) = parse_ip(&nla?.value()) { addrs.push(addr); } } Self::NsIp6Target(addrs) } - _ => Self::Other(DefaultNla::parse(buf).context(format!( - "invalid NLA for {}: {payload:?}", - buf.kind() - ))?), + _ => Self::Other(DefaultNla::parse(buf)?), }) } } diff --git a/src/link/link_info/bond_port.rs b/src/link/link_info/bond_port.rs index 62206818..f940d33d 100644 --- a/src/link/link_info/bond_port.rs +++ b/src/link/link_info/bond_port.rs @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -use anyhow::Context; + use byteorder::{ByteOrder, NativeEndian}; use netlink_packet_utils::{ nla::{DefaultNla, Nla, NlaBuffer}, @@ -157,39 +157,22 @@ impl Nla for InfoBondPort { } } -impl<'a, T: AsRef<[u8]> + ?Sized> Parseable> for InfoBondPort { - fn parse(buf: &NlaBuffer<&'a T>) -> Result { +impl + ?Sized> Parseable> for InfoBondPort { + type Error = DecodeError; + + fn parse(buf: &NlaBuffer<&T>) -> Result { use self::InfoBondPort::*; let payload = buf.value(); Ok(match buf.kind() { IFLA_BOND_PORT_LINK_FAILURE_COUNT => { - LinkFailureCount(parse_u32(payload).context( - "invalid IFLA_BOND_PORT_LINK_FAILURE_COUNT value", - )?) + LinkFailureCount(parse_u32(payload)?) } - IFLA_BOND_PORT_MII_STATUS => MiiStatus( - parse_u8(payload) - .context("invalid IFLA_BOND_PORT_MII_STATUS value")? - .into(), - ), + IFLA_BOND_PORT_MII_STATUS => MiiStatus(parse_u8(payload)?.into()), IFLA_BOND_PORT_PERM_HWADDR => PermHwaddr(payload.to_vec()), - IFLA_BOND_PORT_PRIO => Prio( - parse_i32(payload) - .context("invalid IFLA_BOND_PORT_PRIO value")?, - ), - IFLA_BOND_PORT_QUEUE_ID => QueueId( - parse_u16(payload) - .context("invalid IFLA_BOND_PORT_QUEUE_ID value")?, - ), - IFLA_BOND_PORT_STATE => BondPortState( - parse_u8(payload) - .context("invalid IFLA_BOND_PORT_STATE value")? - .into(), - ), - kind => Other( - DefaultNla::parse(buf) - .context(format!("unknown NLA type {kind}"))?, - ), + IFLA_BOND_PORT_PRIO => Prio(parse_i32(payload)?), + IFLA_BOND_PORT_QUEUE_ID => QueueId(parse_u16(payload)?), + IFLA_BOND_PORT_STATE => BondPortState(parse_u8(payload)?.into()), + _ => Other(DefaultNla::parse(buf)?), }) } } diff --git a/src/link/link_info/bridge.rs b/src/link/link_info/bridge.rs index 13d2a894..f5f4e38a 100644 --- a/src/link/link_info/bridge.rs +++ b/src/link/link_info/bridge.rs @@ -2,7 +2,6 @@ use std::net::{IpAddr, Ipv4Addr, Ipv6Addr}; -use anyhow::Context; use byteorder::{BigEndian, ByteOrder, NativeEndian}; use netlink_packet_utils::{ nla::{DefaultNla, Nla, NlaBuffer, NlasIterator, NLA_F_NESTED}, @@ -304,214 +303,118 @@ impl Nla for InfoBridge { } } -impl<'a, T: AsRef<[u8]> + ?Sized> Parseable> for InfoBridge { - fn parse(buf: &NlaBuffer<&'a T>) -> Result { +impl + ?Sized> Parseable> for InfoBridge { + type Error = DecodeError; + + fn parse(buf: &NlaBuffer<&T>) -> Result { let payload = buf.value(); Ok(match buf.kind() { IFLA_BR_FDB_FLUSH => Self::FdbFlush, - IFLA_BR_HELLO_TIMER => Self::HelloTimer( - parse_u64(payload) - .context("invalid IFLA_BR_HELLO_TIMER value")?, - ), - IFLA_BR_TCN_TIMER => Self::TcnTimer( - parse_u64(payload) - .context("invalid IFLA_BR_TCN_TIMER value")?, - ), - IFLA_BR_TOPOLOGY_CHANGE_TIMER => Self::TopologyChangeTimer( - parse_u64(payload) - .context("invalid IFLA_BR_TOPOLOGY_CHANGE_TIMER value")?, - ), - IFLA_BR_GC_TIMER => Self::GcTimer( - parse_u64(payload).context("invalid IFLA_BR_GC_TIMER value")?, - ), + IFLA_BR_HELLO_TIMER => Self::HelloTimer(parse_u64(payload)?), + IFLA_BR_TCN_TIMER => Self::TcnTimer(parse_u64(payload)?), + IFLA_BR_TOPOLOGY_CHANGE_TIMER => { + Self::TopologyChangeTimer(parse_u64(payload)?) + } + IFLA_BR_GC_TIMER => Self::GcTimer(parse_u64(payload)?), IFLA_BR_MCAST_LAST_MEMBER_INTVL => { - Self::MulticastLastMemberInterval( - parse_u64(payload).context( - "invalid IFLA_BR_MCAST_LAST_MEMBER_INTVL value", - )?, - ) + Self::MulticastLastMemberInterval(parse_u64(payload)?) } IFLA_BR_MCAST_MEMBERSHIP_INTVL => { - Self::MulticastMembershipInterval( - parse_u64(payload).context( - "invalid IFLA_BR_MCAST_MEMBERSHIP_INTVL value", - )?, - ) - } - IFLA_BR_MCAST_QUERIER_INTVL => Self::MulticastQuerierInterval( - parse_u64(payload) - .context("invalid IFLA_BR_MCAST_QUERIER_INTVL value")?, - ), - IFLA_BR_MCAST_QUERY_INTVL => Self::MulticastQueryInterval( - parse_u64(payload) - .context("invalid IFLA_BR_MCAST_QUERY_INTVL value")?, - ), + Self::MulticastMembershipInterval(parse_u64(payload)?) + } + IFLA_BR_MCAST_QUERIER_INTVL => { + Self::MulticastQuerierInterval(parse_u64(payload)?) + } + IFLA_BR_MCAST_QUERY_INTVL => { + Self::MulticastQueryInterval(parse_u64(payload)?) + } IFLA_BR_MCAST_QUERY_RESPONSE_INTVL => { - Self::MulticastQueryResponseInterval( - parse_u64(payload).context( - "invalid IFLA_BR_MCAST_QUERY_RESPONSE_INTVL value", - )?, - ) + Self::MulticastQueryResponseInterval(parse_u64(payload)?) } IFLA_BR_MCAST_STARTUP_QUERY_INTVL => { - Self::MulticastStartupQueryInterval( - parse_u64(payload).context( - "invalid IFLA_BR_MCAST_STARTUP_QUERY_INTVL value", - )?, - ) - } - IFLA_BR_FORWARD_DELAY => Self::ForwardDelay( - parse_u32(payload) - .context("invalid IFLA_BR_FORWARD_DELAY value")?, - ), - IFLA_BR_HELLO_TIME => Self::HelloTime( - parse_u32(payload) - .context("invalid IFLA_BR_HELLO_TIME value")?, - ), - IFLA_BR_MAX_AGE => Self::MaxAge( - parse_u32(payload).context("invalid IFLA_BR_MAX_AGE value")?, - ), - IFLA_BR_AGEING_TIME => Self::AgeingTime( - parse_u32(payload) - .context("invalid IFLA_BR_AGEING_TIME value")?, - ), - IFLA_BR_STP_STATE => Self::StpState( - parse_u32(payload) - .context("invalid IFLA_BR_STP_STATE value")?, - ), - IFLA_BR_MCAST_HASH_ELASTICITY => Self::MulticastHashElasticity( - parse_u32(payload) - .context("invalid IFLA_BR_MCAST_HASH_ELASTICITY value")?, - ), - IFLA_BR_MCAST_HASH_MAX => Self::MulticastHashMax( - parse_u32(payload) - .context("invalid IFLA_BR_MCAST_HASH_MAX value")?, - ), - IFLA_BR_MCAST_LAST_MEMBER_CNT => Self::MulticastLastMemberCount( - parse_u32(payload) - .context("invalid IFLA_BR_MCAST_LAST_MEMBER_CNT value")?, - ), + Self::MulticastStartupQueryInterval(parse_u64(payload)?) + } + IFLA_BR_FORWARD_DELAY => Self::ForwardDelay(parse_u32(payload)?), + IFLA_BR_HELLO_TIME => Self::HelloTime(parse_u32(payload)?), + IFLA_BR_MAX_AGE => Self::MaxAge(parse_u32(payload)?), + IFLA_BR_AGEING_TIME => Self::AgeingTime(parse_u32(payload)?), + IFLA_BR_STP_STATE => Self::StpState(parse_u32(payload)?), + IFLA_BR_MCAST_HASH_ELASTICITY => { + Self::MulticastHashElasticity(parse_u32(payload)?) + } + IFLA_BR_MCAST_HASH_MAX => { + Self::MulticastHashMax(parse_u32(payload)?) + } + IFLA_BR_MCAST_LAST_MEMBER_CNT => { + Self::MulticastLastMemberCount(parse_u32(payload)?) + } IFLA_BR_MCAST_STARTUP_QUERY_CNT => { - Self::MulticastStartupQueryCount( - parse_u32(payload).context( - "invalid IFLA_BR_MCAST_STARTUP_QUERY_CNT value", - )?, - ) - } - IFLA_BR_ROOT_PATH_COST => Self::RootPathCost( - parse_u32(payload) - .context("invalid IFLA_BR_ROOT_PATH_COST value")?, - ), - IFLA_BR_PRIORITY => Self::Priority( - parse_u16(payload).context("invalid IFLA_BR_PRIORITY value")?, - ), - IFLA_BR_VLAN_PROTOCOL => Self::VlanProtocol( - parse_u16_be(payload) - .context("invalid IFLA_BR_VLAN_PROTOCOL value")?, - ), - IFLA_BR_GROUP_FWD_MASK => Self::GroupFwdMask( - parse_u16(payload) - .context("invalid IFLA_BR_GROUP_FWD_MASK value")?, - ), - IFLA_BR_ROOT_ID => Self::RootId( - BridgeId::parse(&BridgeIdBuffer::new(payload)) - .context("invalid IFLA_BR_ROOT_ID value")?, - ), - IFLA_BR_BRIDGE_ID => Self::BridgeId( - BridgeId::parse(&BridgeIdBuffer::new(payload)) - .context("invalid IFLA_BR_BRIDGE_ID value")?, - ), - IFLA_BR_GROUP_ADDR => Self::GroupAddr( - parse_mac(payload) - .context("invalid IFLA_BR_GROUP_ADDR value")?, - ), - IFLA_BR_ROOT_PORT => Self::RootPort( - parse_u16(payload) - .context("invalid IFLA_BR_ROOT_PORT value")?, - ), - IFLA_BR_VLAN_DEFAULT_PVID => Self::VlanDefaultPvid( - parse_u16(payload) - .context("invalid IFLA_BR_VLAN_DEFAULT_PVID value")?, - ), - IFLA_BR_VLAN_FILTERING => Self::VlanFiltering( - parse_u8(payload) - .context("invalid IFLA_BR_VLAN_FILTERING value")? - > 0, - ), - IFLA_BR_TOPOLOGY_CHANGE => Self::TopologyChange( - parse_u8(payload) - .context("invalid IFLA_BR_TOPOLOGY_CHANGE value")?, - ), + Self::MulticastStartupQueryCount(parse_u32(payload)?) + } + IFLA_BR_ROOT_PATH_COST => Self::RootPathCost(parse_u32(payload)?), + IFLA_BR_PRIORITY => Self::Priority(parse_u16(payload)?), + IFLA_BR_VLAN_PROTOCOL => Self::VlanProtocol(parse_u16_be(payload)?), + IFLA_BR_GROUP_FWD_MASK => Self::GroupFwdMask(parse_u16(payload)?), + IFLA_BR_ROOT_ID => { + Self::RootId(BridgeId::parse(&BridgeIdBuffer::new(payload))?) + } + IFLA_BR_BRIDGE_ID => { + Self::BridgeId(BridgeId::parse(&BridgeIdBuffer::new(payload))?) + } + IFLA_BR_GROUP_ADDR => Self::GroupAddr(parse_mac(payload)?), + IFLA_BR_ROOT_PORT => Self::RootPort(parse_u16(payload)?), + IFLA_BR_VLAN_DEFAULT_PVID => { + Self::VlanDefaultPvid(parse_u16(payload)?) + } + IFLA_BR_VLAN_FILTERING => { + Self::VlanFiltering(parse_u8(payload)? > 0) + } + IFLA_BR_TOPOLOGY_CHANGE => Self::TopologyChange(parse_u8(payload)?), IFLA_BR_TOPOLOGY_CHANGE_DETECTED => { - Self::TopologyChangeDetected(parse_u8(payload).context( - "invalid IFLA_BR_TOPOLOGY_CHANGE_DETECTED value", - )?) - } - IFLA_BR_MCAST_ROUTER => Self::MulticastRouter( - parse_u8(payload) - .context("invalid IFLA_BR_MCAST_ROUTER value")?, - ), - IFLA_BR_MCAST_SNOOPING => Self::MulticastSnooping( - parse_u8(payload) - .context("invalid IFLA_BR_MCAST_SNOOPING value")?, - ), - IFLA_BR_MCAST_QUERY_USE_IFADDR => Self::MulticastQueryUseIfaddr( - parse_u8(payload) - .context("invalid IFLA_BR_MCAST_QUERY_USE_IFADDR value")?, - ), - IFLA_BR_MCAST_QUERIER => Self::MulticastQuerier( - parse_u8(payload) - .context("invalid IFLA_BR_MCAST_QUERIER value")?, - ), - IFLA_BR_NF_CALL_IPTABLES => Self::NfCallIpTables( - parse_u8(payload) - .context("invalid IFLA_BR_NF_CALL_IPTABLES value")?, - ), - IFLA_BR_NF_CALL_IP6TABLES => Self::NfCallIp6Tables( - parse_u8(payload) - .context("invalid IFLA_BR_NF_CALL_IP6TABLES value")?, - ), - IFLA_BR_NF_CALL_ARPTABLES => Self::NfCallArpTables( - parse_u8(payload) - .context("invalid IFLA_BR_NF_CALL_ARPTABLES value")?, - ), - IFLA_BR_VLAN_STATS_ENABLED => Self::VlanStatsEnabled( - parse_u8(payload) - .context("invalid IFLA_BR_VLAN_STATS_ENABLED value")?, - ), - IFLA_BR_MCAST_STATS_ENABLED => Self::MulticastStatsEnabled( - parse_u8(payload) - .context("invalid IFLA_BR_MCAST_STATS_ENABLED value")?, - ), - IFLA_BR_MCAST_IGMP_VERSION => Self::MulticastIgmpVersion( - parse_u8(payload) - .context("invalid IFLA_BR_MCAST_IGMP_VERSION value")?, - ), - IFLA_BR_MCAST_MLD_VERSION => Self::MulticastMldVersion( - parse_u8(payload) - .context("invalid IFLA_BR_MCAST_MLD_VERSION value")?, - ), - IFLA_BR_VLAN_STATS_PER_PORT => Self::VlanStatsPerHost( - parse_u8(payload) - .context("invalid IFLA_BR_VLAN_STATS_PER_PORT value")?, - ), - IFLA_BR_MULTI_BOOLOPT => Self::MultiBoolOpt( - parse_u64(payload) - .context("invalid IFLA_BR_MULTI_BOOLOPT value")?, - ), + Self::TopologyChangeDetected(parse_u8(payload)?) + } + IFLA_BR_MCAST_ROUTER => Self::MulticastRouter(parse_u8(payload)?), + IFLA_BR_MCAST_SNOOPING => { + Self::MulticastSnooping(parse_u8(payload)?) + } + IFLA_BR_MCAST_QUERY_USE_IFADDR => { + Self::MulticastQueryUseIfaddr(parse_u8(payload)?) + } + IFLA_BR_MCAST_QUERIER => Self::MulticastQuerier(parse_u8(payload)?), + IFLA_BR_NF_CALL_IPTABLES => { + Self::NfCallIpTables(parse_u8(payload)?) + } + IFLA_BR_NF_CALL_IP6TABLES => { + Self::NfCallIp6Tables(parse_u8(payload)?) + } + IFLA_BR_NF_CALL_ARPTABLES => { + Self::NfCallArpTables(parse_u8(payload)?) + } + IFLA_BR_VLAN_STATS_ENABLED => { + Self::VlanStatsEnabled(parse_u8(payload)?) + } + IFLA_BR_MCAST_STATS_ENABLED => { + Self::MulticastStatsEnabled(parse_u8(payload)?) + } + IFLA_BR_MCAST_IGMP_VERSION => { + Self::MulticastIgmpVersion(parse_u8(payload)?) + } + IFLA_BR_MCAST_MLD_VERSION => { + Self::MulticastMldVersion(parse_u8(payload)?) + } + IFLA_BR_VLAN_STATS_PER_PORT => { + Self::VlanStatsPerHost(parse_u8(payload)?) + } + IFLA_BR_MULTI_BOOLOPT => Self::MultiBoolOpt(parse_u64(payload)?), IFLA_BR_MCAST_QUERIER_STATE => { let mut v = Vec::new(); - let err = "failed to parse IFLA_BR_MCAST_QUERIER_STATE"; for nla in NlasIterator::new(payload) { - let nla = &nla.context(err)?; - let parsed = BridgeQuerierState::parse(nla).context(err)?; + let parsed = BridgeQuerierState::parse(&nla?)?; v.push(parsed); } Self::MulticastQuerierState(v) } - _ => Self::Other(DefaultNla::parse(buf).context( - "invalid link info bridge NLA value (unknown type)", - )?), + _ => Self::Other(DefaultNla::parse(buf)?), }) } } @@ -530,14 +433,15 @@ buffer!(BridgeIdBuffer(BRIDGE_ID_LEN) { }); impl + ?Sized> Parseable> for BridgeId { - fn parse(buf: &BridgeIdBuffer<&T>) -> Result { + type Error = DecodeError; + + fn parse(buf: &BridgeIdBuffer<&T>) -> Result { // Priority is encoded in big endian. From kernel's // net/bridge/br_netlink.c br_fill_info(): // u16 priority = (br->bridge_id.prio[0] << 8) | br->bridge_id.prio[1]; Ok(Self { priority: u16::from_be(buf.priority()), - address: parse_mac(buf.address()) - .context("invalid MAC address in BridgeId buffer")?, + address: parse_mac(buf.address())?, }) } } @@ -613,10 +517,10 @@ impl Nla for BridgeQuerierState { } } -impl<'a, T: AsRef<[u8]> + ?Sized> Parseable> - for BridgeQuerierState -{ - fn parse(buf: &NlaBuffer<&'a T>) -> Result { +impl + ?Sized> Parseable> for BridgeQuerierState { + type Error = DecodeError; + + fn parse(buf: &NlaBuffer<&T>) -> Result { use self::BridgeQuerierState::*; let payload = buf.value(); Ok(match buf.kind() { @@ -648,27 +552,16 @@ impl<'a, T: AsRef<[u8]> + ?Sized> Parseable> ))); } }, - BRIDGE_QUERIER_IP_PORT => Ipv4Port( - parse_u32(payload) - .context("invalid BRIDGE_QUERIER_IP_PORT value")?, - ), - BRIDGE_QUERIER_IPV6_PORT => Ipv6Port( - parse_u32(payload) - .context("invalid BRIDGE_QUERIER_IPV6_PORT value")?, - ), - BRIDGE_QUERIER_IP_OTHER_TIMER => Ipv4OtherTimer( - parse_u64(payload) - .context("invalid BRIDGE_QUERIER_IP_OTHER_TIMER value")?, - ), - BRIDGE_QUERIER_IPV6_OTHER_TIMER => Ipv6OtherTimer( - parse_u64(payload) - .context("invalid BRIDGE_QUERIER_IPV6_OTHER_TIMER value")?, - ), - - kind => Other( - DefaultNla::parse(buf) - .context(format!("unknown NLA type {kind}"))?, - ), + BRIDGE_QUERIER_IP_PORT => Ipv4Port(parse_u32(payload)?), + BRIDGE_QUERIER_IPV6_PORT => Ipv6Port(parse_u32(payload)?), + BRIDGE_QUERIER_IP_OTHER_TIMER => { + Ipv4OtherTimer(parse_u64(payload)?) + } + BRIDGE_QUERIER_IPV6_OTHER_TIMER => { + Ipv6OtherTimer(parse_u64(payload)?) + } + + _ => Other(DefaultNla::parse(buf)?), }) } } diff --git a/src/link/link_info/bridge_port.rs b/src/link/link_info/bridge_port.rs index 35c818cf..76a53c5a 100644 --- a/src/link/link_info/bridge_port.rs +++ b/src/link/link_info/bridge_port.rs @@ -1,6 +1,5 @@ // SPDX-License-Identifier: MIT use crate::link::{BridgeId, BridgeIdBuffer}; -use anyhow::Context; use byteorder::{ByteOrder, NativeEndian}; use netlink_packet_utils::{ nla::{DefaultNla, Nla, NlaBuffer}, @@ -271,252 +270,128 @@ impl Nla for InfoBridgePort { } } -impl<'a, T: AsRef<[u8]> + ?Sized> Parseable> - for InfoBridgePort -{ - fn parse(buf: &NlaBuffer<&'a T>) -> Result { +impl + ?Sized> Parseable> for InfoBridgePort { + type Error = DecodeError; + + fn parse(buf: &NlaBuffer<&T>) -> Result { let payload = buf.value(); Ok(match buf.kind() { - IFLA_BRPORT_STATE => InfoBridgePort::State( - parse_u8(payload) - .with_context(|| { - format!("invalid IFLA_BRPORT_STATE {payload:?}") - })? - .into(), - ), + IFLA_BRPORT_STATE => { + InfoBridgePort::State(parse_u8(payload)?.into()) + } IFLA_BRPORT_PRIORITY => { - InfoBridgePort::Priority(parse_u16(payload).with_context( - || format!("invalid IFLA_BRPORT_PRIORITY {payload:?}"), - )?) - } - IFLA_BRPORT_COST => { - InfoBridgePort::Cost(parse_u32(payload).with_context(|| { - format!("invalid IFLA_BRPORT_COST {payload:?}") - })?) - } - IFLA_BRPORT_MODE => InfoBridgePort::HairpinMode( - parse_u8(payload).with_context(|| { - format!("invalid IFLA_BRPORT_MODE {payload:?}") - })? > 0, - ), - IFLA_BRPORT_GUARD => InfoBridgePort::Guard( - parse_u8(payload).with_context(|| { - format!("invalid IFLA_BRPORT_GUARD {payload:?}") - })? > 0, - ), - IFLA_BRPORT_PROTECT => InfoBridgePort::Protect( - parse_u8(payload).with_context(|| { - format!("invalid IFLA_BRPORT_PROTECT {payload:?}") - })? > 0, - ), - IFLA_BRPORT_FAST_LEAVE => InfoBridgePort::FastLeave( - parse_u8(payload).with_context(|| { - format!( - "invalid IFLA_BRPORT_FAST_LEAVE {payload:?}" - ) - })? > 0, - ), - IFLA_BRPORT_LEARNING => InfoBridgePort::Learning( - parse_u8(payload).with_context(|| { - format!("invalid IFLA_BRPORT_LEARNING {payload:?}") - })? > 0, - ), - IFLA_BRPORT_UNICAST_FLOOD => InfoBridgePort::UnicastFlood( - parse_u8(payload).with_context(|| { - format!("invalid IFLA_BRPORT_UNICAST_FLOOD {payload:?}") - })? > 0, - ), - IFLA_BRPORT_PROXYARP => InfoBridgePort::ProxyARP( - parse_u8(payload).with_context(|| { - format!("invalid IFLA_BRPORT_PROXYARP {payload:?}") - })? > 0, - ), - IFLA_BRPORT_PROXYARP_WIFI => InfoBridgePort::ProxyARPWifi( - parse_u8(payload).with_context(|| { - format!("invalid IFLA_BRPORT_PROXYARP_WIFI {payload:?}") - })? > 0, - ), - IFLA_BRPORT_ROOT_ID => Self::RootId( - BridgeId::parse(&BridgeIdBuffer::new(payload)).with_context(|| { - format!("invalid IFLA_BRPORT_ROOT_ID {payload:?}") - })?, - ), - IFLA_BRPORT_BRIDGE_ID => Self::BridgeId( - BridgeId::parse(&BridgeIdBuffer::new(payload)).with_context(|| { - format!("invalid IFLA_BRPORT_BRIDGE_ID {payload:?}") - })?, - ), - IFLA_BRPORT_DESIGNATED_PORT => InfoBridgePort::DesignatedPort( - parse_u16(payload).with_context(|| { - format!("invalid IFLA_BRPORT_DESIGNATED_PORT {payload:?}") - })?, - ), - IFLA_BRPORT_DESIGNATED_COST => InfoBridgePort::DesignatedCost( - parse_u16(payload).with_context(|| { - format!("invalid IFLA_BRPORT_DESIGNATED_COST {payload:?}") - })?, - ), - IFLA_BRPORT_ID => { - InfoBridgePort::PortId(parse_u16(payload).with_context(|| { - format!("invalid IFLA_BRPORT_ID {payload:?}") - })?) - } - IFLA_BRPORT_NO => { - InfoBridgePort::PortNumber(parse_u16(payload).with_context(|| { - format!("invalid IFLA_BRPORT_NO {payload:?}") - })?) + InfoBridgePort::Priority(parse_u16(payload)?) + } + IFLA_BRPORT_COST => InfoBridgePort::Cost(parse_u32(payload)?), + IFLA_BRPORT_MODE => { + InfoBridgePort::HairpinMode(parse_u8(payload)? > 0) + } + IFLA_BRPORT_GUARD => InfoBridgePort::Guard(parse_u8(payload)? > 0), + IFLA_BRPORT_PROTECT => { + InfoBridgePort::Protect(parse_u8(payload)? > 0) + } + IFLA_BRPORT_FAST_LEAVE => { + InfoBridgePort::FastLeave(parse_u8(payload)? > 0) + } + IFLA_BRPORT_LEARNING => { + InfoBridgePort::Learning(parse_u8(payload)? > 0) + } + IFLA_BRPORT_UNICAST_FLOOD => { + InfoBridgePort::UnicastFlood(parse_u8(payload)? > 0) + } + IFLA_BRPORT_PROXYARP => { + InfoBridgePort::ProxyARP(parse_u8(payload)? > 0) + } + IFLA_BRPORT_PROXYARP_WIFI => { + InfoBridgePort::ProxyARPWifi(parse_u8(payload)? > 0) } + IFLA_BRPORT_ROOT_ID => { + Self::RootId(BridgeId::parse(&BridgeIdBuffer::new(payload))?) + } + IFLA_BRPORT_BRIDGE_ID => { + Self::BridgeId(BridgeId::parse(&BridgeIdBuffer::new(payload))?) + } + IFLA_BRPORT_DESIGNATED_PORT => { + InfoBridgePort::DesignatedPort(parse_u16(payload)?) + } + IFLA_BRPORT_DESIGNATED_COST => { + InfoBridgePort::DesignatedCost(parse_u16(payload)?) + } + IFLA_BRPORT_ID => InfoBridgePort::PortId(parse_u16(payload)?), + IFLA_BRPORT_NO => InfoBridgePort::PortNumber(parse_u16(payload)?), IFLA_BRPORT_TOPOLOGY_CHANGE_ACK => { - InfoBridgePort::TopologyChangeAck( - parse_u8(payload).with_context(|| { - format!( - "invalid IFLA_BRPORT_TOPOLOGY_CHANGE_ACK {payload:?}" - ) - })? > 0, - ) - } - IFLA_BRPORT_CONFIG_PENDING => InfoBridgePort::ConfigPending( - parse_u8(payload).with_context(|| { - format!("invalid IFLA_BRPORT_CONFIG_PENDING {payload:?}") - })? > 0, - ), - IFLA_BRPORT_MESSAGE_AGE_TIMER => InfoBridgePort::MessageAgeTimer( - parse_u64(payload).with_context(|| { - format!("invalid IFLA_BRPORT_MESSAGE_AGE_TIMER {payload:?}") - })?, - ), + InfoBridgePort::TopologyChangeAck(parse_u8(payload)? > 0) + } + IFLA_BRPORT_CONFIG_PENDING => { + InfoBridgePort::ConfigPending(parse_u8(payload)? > 0) + } + IFLA_BRPORT_MESSAGE_AGE_TIMER => { + InfoBridgePort::MessageAgeTimer(parse_u64(payload)?) + } IFLA_BRPORT_FORWARD_DELAY_TIMER => { - InfoBridgePort::ForwardDelayTimer( - parse_u64(payload).with_context(|| { - format!( - "invalid IFLA_BRPORT_FORWARD_DELAY_TIMER {payload:?}" - ) - })?, - ) + InfoBridgePort::ForwardDelayTimer(parse_u64(payload)?) } IFLA_BRPORT_HOLD_TIMER => { - InfoBridgePort::HoldTimer(parse_u64(payload).with_context( - || format!("invalid IFLA_BRPORT_HOLD_TIMER {payload:?}"), - )?) + InfoBridgePort::HoldTimer(parse_u64(payload)?) } IFLA_BRPORT_FLUSH => InfoBridgePort::Flush, - IFLA_BRPORT_MULTICAST_ROUTER => InfoBridgePort::MulticastRouter( - parse_u8(payload) - .with_context(|| { - format!( - "invalid IFLA_BRPORT_MULTICAST_ROUTER {payload:?}" - ) - })? - .into(), - ), - IFLA_BRPORT_MCAST_FLOOD => InfoBridgePort::MulticastFlood( - parse_u8(payload).with_context(|| { - format!("invalid IFLA_BRPORT_MCAST_FLOOD {payload:?}") - })? > 0, - ), - IFLA_BRPORT_MCAST_TO_UCAST => InfoBridgePort::MulticastToUnicast( - parse_u8(payload).with_context(|| { - format!("invalid IFLA_BRPORT_MCAST_TO_UCAST {payload:?}") - })? > 0, - ), - IFLA_BRPORT_VLAN_TUNNEL => InfoBridgePort::VlanTunnel( - parse_u8(payload).with_context(|| { - format!("invalid IFLA_BRPORT_VLAN_TUNNEL {payload:?}") - })? > 0, - ), - IFLA_BRPORT_BCAST_FLOOD => InfoBridgePort::BroadcastFlood( - parse_u8(payload).with_context(|| { - format!("invalid IFLA_BRPORT_BCAST_FLOOD {payload:?}") - })? > 0, - ), - IFLA_BRPORT_GROUP_FWD_MASK => InfoBridgePort::GroupFwdMask( - parse_u16(payload).with_context(|| { - format!("invalid IFLA_BRPORT_GROUP_FWD_MASK {payload:?}") - })?, - ), - IFLA_BRPORT_NEIGH_SUPPRESS => InfoBridgePort::NeighSupress( - parse_u8(payload).with_context(|| { - format!("invalid IFLA_BRPORT_NEIGH_SUPPRESS {payload:?}") - })? > 0, - ), - IFLA_BRPORT_ISOLATED => InfoBridgePort::Isolated( - parse_u8(payload).with_context(|| { - format!("invalid IFLA_BRPORT_ISOLATED {payload:?}") - })? > 0, - ), + IFLA_BRPORT_MULTICAST_ROUTER => { + InfoBridgePort::MulticastRouter(parse_u8(payload)?.into()) + } + IFLA_BRPORT_MCAST_FLOOD => { + InfoBridgePort::MulticastFlood(parse_u8(payload)? > 0) + } + IFLA_BRPORT_MCAST_TO_UCAST => { + InfoBridgePort::MulticastToUnicast(parse_u8(payload)? > 0) + } + IFLA_BRPORT_VLAN_TUNNEL => { + InfoBridgePort::VlanTunnel(parse_u8(payload)? > 0) + } + IFLA_BRPORT_BCAST_FLOOD => { + InfoBridgePort::BroadcastFlood(parse_u8(payload)? > 0) + } + IFLA_BRPORT_GROUP_FWD_MASK => { + InfoBridgePort::GroupFwdMask(parse_u16(payload)?) + } + IFLA_BRPORT_NEIGH_SUPPRESS => { + InfoBridgePort::NeighSupress(parse_u8(payload)? > 0) + } + IFLA_BRPORT_ISOLATED => { + InfoBridgePort::Isolated(parse_u8(payload)? > 0) + } IFLA_BRPORT_BACKUP_PORT => { - InfoBridgePort::BackupPort(parse_u32(payload).with_context( - || format!("invalid IFLA_BRPORT_BACKUP_PORT {payload:?}"), - )?) - } - IFLA_BRPORT_MRP_RING_OPEN => InfoBridgePort::MrpRingOpen( - parse_u8(payload).with_context(|| { - format!("invalid IFLA_BRPORT_MRP_RING_OPEN {payload:?}") - })? > 0, - ), - IFLA_BRPORT_MRP_IN_OPEN => InfoBridgePort::MrpInOpen( - parse_u8(payload).with_context(|| { - format!("invalid IFLA_BRPORT_MRP_IN_OPEN {payload:?}") - })? > 0, - ), + InfoBridgePort::BackupPort(parse_u32(payload)?) + } + IFLA_BRPORT_MRP_RING_OPEN => { + InfoBridgePort::MrpRingOpen(parse_u8(payload)? > 0) + } + IFLA_BRPORT_MRP_IN_OPEN => { + InfoBridgePort::MrpInOpen(parse_u8(payload)? > 0) + } IFLA_BRPORT_MCAST_EHT_HOSTS_LIMIT => { - InfoBridgePort::MulticastEhtHostsLimit( - parse_u32(payload).with_context(|| { - format!( - "invalid IFLA_BRPORT_MCAST_EHT_HOSTS_LIMIT {payload:?}" - ) - })?, - ) + InfoBridgePort::MulticastEhtHostsLimit(parse_u32(payload)?) } IFLA_BRPORT_MCAST_EHT_HOSTS_CNT => { - InfoBridgePort::MulticastEhtHostsCnt( - parse_u32(payload).with_context(|| { - format!( - "invalid IFLA_BRPORT_MCAST_EHT_HOSTS_CNT {payload:?}" - ) - })? - ) - } - IFLA_BRPORT_LOCKED => InfoBridgePort::Locked( - parse_u8(payload).with_context(|| { - format!("invalid IFLA_BRPORT_LOCKED {payload:?}") - })? > 0, - ), - IFLA_BRPORT_MAB => InfoBridgePort::Mab( - parse_u8(payload).with_context(|| { - format!("invalid IFLA_BRPORT_MAB {payload:?}") - })? > 0, - ), - IFLA_BRPORT_MCAST_N_GROUPS => InfoBridgePort::MulticastNGroups( - parse_u32(payload).with_context(|| { - format!("invalid IFLA_BRPORT_MCAST_N_GROUPS {payload:?}") - })?, - ), - IFLA_BRPORT_MCAST_MAX_GROUPS => InfoBridgePort::MulticastMaxGroups( - parse_u32(payload).with_context(|| { - format!("invalid IFLA_BRPORT_MCAST_MAX_GROUPS {payload:?}") - })?, - ), - IFLA_BRPORT_NEIGH_VLAN_SUPPRESS => InfoBridgePort::NeighVlanSupress( - parse_u8(payload).with_context(|| { - format!( - "invalid IFLA_BRPORT_NEIGH_VLAN_SUPPRESS {payload:?}" - ) - })? > 0, - ), - IFLA_BRPORT_BACKUP_NHID => InfoBridgePort::BackupNextHopId( - parse_u32(payload).with_context(|| { - format!("invalid IFLA_BRPORT_BACKUP_NHID {payload:?}") - })?, - ), - kind => InfoBridgePort::Other( - DefaultNla::parse(buf).with_context(|| { - format!( - "failed to parse bridge port NLA of type '{kind}' into DefaultNla" - ) - })?, - ), + InfoBridgePort::MulticastEhtHostsCnt(parse_u32(payload)?) + } + IFLA_BRPORT_LOCKED => { + InfoBridgePort::Locked(parse_u8(payload)? > 0) + } + IFLA_BRPORT_MAB => InfoBridgePort::Mab(parse_u8(payload)? > 0), + IFLA_BRPORT_MCAST_N_GROUPS => { + InfoBridgePort::MulticastNGroups(parse_u32(payload)?) + } + IFLA_BRPORT_MCAST_MAX_GROUPS => { + InfoBridgePort::MulticastMaxGroups(parse_u32(payload)?) + } + IFLA_BRPORT_NEIGH_VLAN_SUPPRESS => { + InfoBridgePort::NeighVlanSupress(parse_u8(payload)? > 0) + } + IFLA_BRPORT_BACKUP_NHID => { + InfoBridgePort::BackupNextHopId(parse_u32(payload)?) + } + _ => InfoBridgePort::Other(DefaultNla::parse(buf)?), }) } } diff --git a/src/link/link_info/geneve.rs b/src/link/link_info/geneve.rs index 0404a3c8..a1812406 100644 --- a/src/link/link_info/geneve.rs +++ b/src/link/link_info/geneve.rs @@ -2,7 +2,6 @@ use std::net::{Ipv4Addr, Ipv6Addr}; -use anyhow::Context; use byteorder::{BigEndian, ByteOrder, NativeEndian}; use netlink_packet_utils::{ nla::{DefaultNla, Nla, NlaBuffer}, @@ -136,15 +135,14 @@ impl Nla for InfoGeneve { } } -impl<'a, T: AsRef<[u8]> + ?Sized> Parseable> for InfoGeneve { - fn parse(buf: &NlaBuffer<&'a T>) -> Result { +impl + ?Sized> Parseable> for InfoGeneve { + type Error = DecodeError; + + fn parse(buf: &NlaBuffer<&T>) -> Result { use self::InfoGeneve::*; let payload = buf.value(); Ok(match buf.kind() { - IFLA_GENEVE_ID => { - Id(parse_u32(payload) - .context("invalid IFLA_GENEVE_ID value")?) - } + IFLA_GENEVE_ID => Id(parse_u32(payload)?), IFLA_GENEVE_REMOTE => { if payload.len() == 4 { let mut data = [0u8; 4]; @@ -171,51 +169,22 @@ impl<'a, T: AsRef<[u8]> + ?Sized> Parseable> for InfoGeneve { ))); } } - IFLA_GENEVE_TTL => { - Ttl(parse_u8(payload) - .context("invalid IFLA_GENEVE_TTL value")?) + IFLA_GENEVE_TTL => Ttl(parse_u8(payload)?), + IFLA_GENEVE_TOS => Tos(parse_u8(payload)?), + IFLA_GENEVE_PORT => Port(parse_u16_be(payload)?), + IFLA_GENEVE_COLLECT_METADATA => CollectMetadata, + IFLA_GENEVE_UDP_CSUM => UdpCsum(parse_u8(payload)? > 0), + IFLA_GENEVE_UDP_ZERO_CSUM6_TX => { + UdpZeroCsum6Tx(parse_u8(payload)? > 0) } - IFLA_GENEVE_TOS => { - Tos(parse_u8(payload) - .context("invalid IFLA_GENEVE_TOS value")?) + IFLA_GENEVE_UDP_ZERO_CSUM6_RX => { + UdpZeroCsum6Rx(parse_u8(payload)? > 0) } - IFLA_GENEVE_PORT => Port( - parse_u16_be(payload) - .context("invalid IFLA_GENEVE_PORT value")?, - ), - IFLA_GENEVE_COLLECT_METADATA => CollectMetadata, - IFLA_GENEVE_UDP_CSUM => UdpCsum( - parse_u8(payload) - .context("invalid IFLA_GENEVE_UDP_CSUM value")? - > 0, - ), - IFLA_GENEVE_UDP_ZERO_CSUM6_TX => UdpZeroCsum6Tx( - parse_u8(payload) - .context("invalid IFLA_GENEVE_UDP_ZERO_CSUM6_TX value")? - > 0, - ), - IFLA_GENEVE_UDP_ZERO_CSUM6_RX => UdpZeroCsum6Rx( - parse_u8(payload) - .context("invalid IFLA_GENEVE_UDP_ZERO_CSUM6_RX value")? - > 0, - ), - IFLA_GENEVE_LABEL => Label( - parse_u32_be(payload) - .context("invalid IFLA_GENEVE_LABEL value")?, - ), - IFLA_GENEVE_TTL_INHERIT => TtlInherit( - parse_u8(payload) - .context("invalid IFLA_GENEVE_TTL_INHERIT value")? - > 0, - ), - IFLA_GENEVE_DF => Df(parse_u8(payload) - .context("invalid IFLA_GENEVE_DF value")? - .into()), + IFLA_GENEVE_LABEL => Label(parse_u32_be(payload)?), + IFLA_GENEVE_TTL_INHERIT => TtlInherit(parse_u8(payload)? > 0), + IFLA_GENEVE_DF => Df(parse_u8(payload)?.into()), IFLA_GENEVE_INNER_PROTO_INHERIT => InnerProtoInherit, - kind => Other( - DefaultNla::parse(buf) - .context(format!("unknown NLA type {kind}"))?, - ), + _ => Other(DefaultNla::parse(buf)?), }) } } diff --git a/src/link/link_info/gre.rs b/src/link/link_info/gre.rs index d1ff4a1a..06e8ea3d 100644 --- a/src/link/link_info/gre.rs +++ b/src/link/link_info/gre.rs @@ -1,6 +1,5 @@ // SPDX-License-Identifier: MIT -use anyhow::Context; use netlink_packet_utils::{ nla::{DefaultNla, Nla, NlaBuffer}, DecodeError, Parseable, @@ -33,13 +32,12 @@ impl Nla for InfoGreTun { } impl<'a, T: AsRef<[u8]> + ?Sized> Parseable> for InfoGreTun { - fn parse(buf: &NlaBuffer<&'a T>) -> Result { + type Error = DecodeError; + + fn parse(buf: &NlaBuffer<&'a T>) -> Result { #[allow(clippy::match_single_binding)] Ok(match buf.kind() { - kind => Self::Other( - DefaultNla::parse(buf) - .context(format!("unknown NLA type {kind} for gre"))?, - ), + _ => Self::Other(DefaultNla::parse(buf)?), }) } } diff --git a/src/link/link_info/gre6.rs b/src/link/link_info/gre6.rs index ceef4161..dfa2d621 100644 --- a/src/link/link_info/gre6.rs +++ b/src/link/link_info/gre6.rs @@ -1,6 +1,5 @@ // SPDX-License-Identifier: MIT -use anyhow::Context; use netlink_packet_utils::{ nla::{DefaultNla, Nla, NlaBuffer}, DecodeError, Parseable, @@ -32,14 +31,13 @@ impl Nla for InfoGreTun6 { } } -impl<'a, T: AsRef<[u8]> + ?Sized> Parseable> for InfoGreTun6 { - fn parse(buf: &NlaBuffer<&'a T>) -> Result { +impl + ?Sized> Parseable> for InfoGreTun6 { + type Error = DecodeError; + + fn parse(buf: &NlaBuffer<&T>) -> Result { #[allow(clippy::match_single_binding)] Ok(match buf.kind() { - kind => Self::Other( - DefaultNla::parse(buf) - .context(format!("unknown NLA type {kind} for ip6gre"))?, - ), + _ => Self::Other(DefaultNla::parse(buf)?), }) } } diff --git a/src/link/link_info/gre_tap.rs b/src/link/link_info/gre_tap.rs index 16293dd2..84144c72 100644 --- a/src/link/link_info/gre_tap.rs +++ b/src/link/link_info/gre_tap.rs @@ -1,6 +1,5 @@ // SPDX-License-Identifier: MIT -use anyhow::Context; use netlink_packet_utils::{ nla::{DefaultNla, Nla, NlaBuffer}, DecodeError, Parseable, @@ -32,14 +31,13 @@ impl Nla for InfoGreTap { } } -impl<'a, T: AsRef<[u8]> + ?Sized> Parseable> for InfoGreTap { - fn parse(buf: &NlaBuffer<&'a T>) -> Result { +impl + ?Sized> Parseable> for InfoGreTap { + type Error = DecodeError; + + fn parse(buf: &NlaBuffer<&T>) -> Result { #[allow(clippy::match_single_binding)] Ok(match buf.kind() { - kind => Self::Other( - DefaultNla::parse(buf) - .context(format!("unknown NLA type {kind} for gretap"))?, - ), + _ => Self::Other(DefaultNla::parse(buf)?), }) } } diff --git a/src/link/link_info/gre_tap6.rs b/src/link/link_info/gre_tap6.rs index 491e9f2b..04519b69 100644 --- a/src/link/link_info/gre_tap6.rs +++ b/src/link/link_info/gre_tap6.rs @@ -1,6 +1,5 @@ // SPDX-License-Identifier: MIT -use anyhow::Context; use netlink_packet_utils::{ nla::{DefaultNla, Nla, NlaBuffer}, DecodeError, Parseable, @@ -32,14 +31,13 @@ impl Nla for InfoGreTap6 { } } -impl<'a, T: AsRef<[u8]> + ?Sized> Parseable> for InfoGreTap6 { - fn parse(buf: &NlaBuffer<&'a T>) -> Result { +impl + ?Sized> Parseable> for InfoGreTap6 { + type Error = DecodeError; + + fn parse(buf: &NlaBuffer<&T>) -> Result { #[allow(clippy::match_single_binding)] Ok(match buf.kind() { - kind => Self::Other( - DefaultNla::parse(buf) - .context(format!("unknown NLA type {kind} for gretap6"))?, - ), + _ => Self::Other(DefaultNla::parse(buf)?), }) } } diff --git a/src/link/link_info/gtp.rs b/src/link/link_info/gtp.rs index 4a87d314..77f0fed5 100644 --- a/src/link/link_info/gtp.rs +++ b/src/link/link_info/gtp.rs @@ -1,6 +1,5 @@ // SPDX-License-Identifier: MIT -use anyhow::Context; use netlink_packet_utils::{ nla::{DefaultNla, Nla, NlaBuffer}, DecodeError, Parseable, @@ -32,14 +31,13 @@ impl Nla for InfoGtp { } } -impl<'a, T: AsRef<[u8]> + ?Sized> Parseable> for InfoGtp { - fn parse(buf: &NlaBuffer<&'a T>) -> Result { +impl + ?Sized> Parseable> for InfoGtp { + type Error = DecodeError; + + fn parse(buf: &NlaBuffer<&T>) -> Result { #[allow(clippy::match_single_binding)] Ok(match buf.kind() { - kind => Self::Other( - DefaultNla::parse(buf) - .context(format!("unknown NLA type {kind} for gtp"))?, - ), + _ => Self::Other(DefaultNla::parse(buf)?), }) } } diff --git a/src/link/link_info/hsr.rs b/src/link/link_info/hsr.rs index 52884ac5..95ff69b4 100644 --- a/src/link/link_info/hsr.rs +++ b/src/link/link_info/hsr.rs @@ -1,6 +1,5 @@ // SPDX-License-Identifier: MIT -use anyhow::Context; use byteorder::{ByteOrder, NativeEndian}; use netlink_packet_utils::{ nla::{DefaultNla, Nla, NlaBuffer}, @@ -73,40 +72,21 @@ impl Nla for InfoHsr { } } -impl<'a, T: AsRef<[u8]> + ?Sized> Parseable> for InfoHsr { - fn parse(buf: &NlaBuffer<&'a T>) -> Result { +impl + ?Sized> Parseable> for InfoHsr { + type Error = DecodeError; + + fn parse(buf: &NlaBuffer<&T>) -> Result { use self::InfoHsr::*; let payload = buf.value(); Ok(match buf.kind() { - IFLA_HSR_PORT1 => Port1( - parse_u32(payload).context("invalid IFLA_HSR_PORT1 value")?, - ), - IFLA_HSR_PORT2 => Port2( - parse_u32(payload).context("invalid IFLA_HSR_PORT2 value")?, - ), - IFLA_HSR_MULTICAST_SPEC => MulticastSpec( - parse_u8(payload) - .context("invalid IFLA_HSR_MULTICAST_SPEC value")?, - ), - IFLA_HSR_SUPERVISION_ADDR => SupervisionAddr( - parse_mac(payload) - .context("invalid IFLA_HSR_SUPERVISION_ADDR value")?, - ), - IFLA_HSR_SEQ_NR => SeqNr( - parse_u16(payload).context("invalid IFLA_HSR_SEQ_NR value")?, - ), - IFLA_HSR_VERSION => Version( - parse_u8(payload).context("invalid IFLA_HSR_VERSION value")?, - ), - IFLA_HSR_PROTOCOL => Protocol( - parse_u8(payload) - .context("invalid IFLA_HSR_PROTOCOL value")? - .into(), - ), - kind => Other( - DefaultNla::parse(buf) - .context(format!("unknown NLA type {kind}"))?, - ), + IFLA_HSR_PORT1 => Port1(parse_u32(payload)?), + IFLA_HSR_PORT2 => Port2(parse_u32(payload)?), + IFLA_HSR_MULTICAST_SPEC => MulticastSpec(parse_u8(payload)?), + IFLA_HSR_SUPERVISION_ADDR => SupervisionAddr(parse_mac(payload)?), + IFLA_HSR_SEQ_NR => SeqNr(parse_u16(payload)?), + IFLA_HSR_VERSION => Version(parse_u8(payload)?), + IFLA_HSR_PROTOCOL => Protocol(parse_u8(payload)?.into()), + _ => Other(DefaultNla::parse(buf)?), }) } } diff --git a/src/link/link_info/info_data.rs b/src/link/link_info/info_data.rs index 8c664d59..3ab79bc7 100644 --- a/src/link/link_info/info_data.rs +++ b/src/link/link_info/info_data.rs @@ -1,7 +1,5 @@ // SPDX-License-Identifier: MIT -use anyhow::Context; - use netlink_packet_utils::{ nla::{Nla, NlaBuffer, NlasIterator}, DecodeError, Emitable, Parseable, @@ -118,10 +116,7 @@ impl InfoData { InfoKind::Bridge => { let mut v = Vec::new(); for nla in NlasIterator::new(payload) { - let nla = &nla.context(format!( - "invalid IFLA_INFO_DATA for {kind} {payload:?}" - ))?; - let parsed = InfoBridge::parse(nla)?; + let parsed = InfoBridge::parse(&nla?)?; v.push(parsed); } InfoData::Bridge(v) @@ -129,10 +124,7 @@ impl InfoData { InfoKind::Vlan => { let mut v = Vec::new(); for nla in NlasIterator::new(payload) { - let nla = &nla.context(format!( - "invalid IFLA_INFO_DATA for {kind} {payload:?}" - ))?; - let parsed = InfoVlan::parse(nla)?; + let parsed = InfoVlan::parse(&nla?)?; v.push(parsed); } InfoData::Vlan(v) @@ -140,28 +132,20 @@ impl InfoData { InfoKind::Tun => { let mut nlas = Vec::new(); for nla in NlasIterator::new(payload) { - let nla = &nla.context(format!( - "invalid IFLA_INFO_DATA for {kind} {payload:?}" - ))?; - let parsed = InfoTun::parse(nla)?; + let parsed = InfoTun::parse(&nla?)?; nlas.push(parsed); } InfoData::Tun(nlas) } InfoKind::Veth => { - let nla_buf = NlaBuffer::new_checked(&payload).context( - format!("invalid IFLA_INFO_DATA for {kind} {payload:?}"), - )?; + let nla_buf = NlaBuffer::new_checked(&payload)?; let parsed = InfoVeth::parse(&nla_buf)?; InfoData::Veth(parsed) } InfoKind::Vxlan => { let mut v = Vec::new(); for nla in NlasIterator::new(payload) { - let nla = &nla.context(format!( - "invalid IFLA_INFO_DATA for {kind} {payload:?}" - ))?; - let parsed = InfoVxlan::parse(nla)?; + let parsed = InfoVxlan::parse(&nla?)?; v.push(parsed); } InfoData::Vxlan(v) @@ -169,10 +153,7 @@ impl InfoData { InfoKind::Bond => { let mut v = Vec::new(); for nla in NlasIterator::new(payload) { - let nla = &nla.context(format!( - "invalid IFLA_INFO_DATA for {kind} {payload:?}" - ))?; - let parsed = InfoBond::parse(nla)?; + let parsed = InfoBond::parse(&nla?)?; v.push(parsed); } InfoData::Bond(v) @@ -180,10 +161,7 @@ impl InfoData { InfoKind::IpVlan => { let mut v = Vec::new(); for nla in NlasIterator::new(payload) { - let nla = &nla.context(format!( - "invalid IFLA_INFO_DATA for {kind} {payload:?}" - ))?; - let parsed = InfoIpVlan::parse(nla)?; + let parsed = InfoIpVlan::parse(&nla?)?; v.push(parsed); } InfoData::IpVlan(v) @@ -191,10 +169,7 @@ impl InfoData { InfoKind::IpVtap => { let mut v = Vec::new(); for nla in NlasIterator::new(payload) { - let nla = &nla.context(format!( - "invalid IFLA_INFO_DATA for {kind} {payload:?}" - ))?; - let parsed = InfoIpVtap::parse(nla)?; + let parsed = InfoIpVtap::parse(&nla?)?; v.push(parsed); } InfoData::IpVtap(v) @@ -202,10 +177,7 @@ impl InfoData { InfoKind::MacVlan => { let mut v = Vec::new(); for nla in NlasIterator::new(payload) { - let nla = &nla.context(format!( - "invalid IFLA_INFO_DATA for {kind} {payload:?}" - ))?; - let parsed = InfoMacVlan::parse(nla)?; + let parsed = InfoMacVlan::parse(&nla?)?; v.push(parsed); } InfoData::MacVlan(v) @@ -213,10 +185,7 @@ impl InfoData { InfoKind::MacVtap => { let mut v = Vec::new(); for nla in NlasIterator::new(payload) { - let nla = &nla.context(format!( - "invalid IFLA_INFO_DATA for {kind} {payload:?}" - ))?; - let parsed = InfoMacVtap::parse(nla)?; + let parsed = InfoMacVtap::parse(&nla?)?; v.push(parsed); } InfoData::MacVtap(v) @@ -224,10 +193,7 @@ impl InfoData { InfoKind::GreTap => { let mut v = Vec::new(); for nla in NlasIterator::new(payload) { - let nla = &nla.context(format!( - "invalid IFLA_INFO_DATA for {kind} {payload:?}" - ))?; - let parsed = InfoGreTap::parse(nla)?; + let parsed = InfoGreTap::parse(&nla?)?; v.push(parsed); } InfoData::GreTap(v) @@ -235,10 +201,7 @@ impl InfoData { InfoKind::GreTap6 => { let mut v = Vec::new(); for nla in NlasIterator::new(payload) { - let nla = &nla.context(format!( - "invalid IFLA_INFO_DATA for {kind} {payload:?}" - ))?; - let parsed = InfoGreTap6::parse(nla)?; + let parsed = InfoGreTap6::parse(&nla?)?; v.push(parsed); } InfoData::GreTap6(v) @@ -246,10 +209,7 @@ impl InfoData { InfoKind::SitTun => { let mut v = Vec::new(); for nla in NlasIterator::new(payload) { - let nla = &nla.context(format!( - "invalid IFLA_INFO_DATA for {kind} {payload:?}" - ))?; - let parsed = InfoSitTun::parse(nla)?; + let parsed = InfoSitTun::parse(&nla?)?; v.push(parsed); } InfoData::SitTun(v) @@ -257,10 +217,7 @@ impl InfoData { InfoKind::GreTun => { let mut v = Vec::new(); for nla in NlasIterator::new(payload) { - let nla = &nla.context(format!( - "invalid IFLA_INFO_DATA for {kind} {payload:?}" - ))?; - let parsed = InfoGreTun::parse(nla)?; + let parsed = InfoGreTun::parse(&nla?)?; v.push(parsed); } InfoData::GreTun(v) @@ -268,10 +225,7 @@ impl InfoData { InfoKind::GreTun6 => { let mut v = Vec::new(); for nla in NlasIterator::new(payload) { - let nla = &nla.context(format!( - "invalid IFLA_INFO_DATA for {kind} {payload:?}" - ))?; - let parsed = InfoGreTun6::parse(nla)?; + let parsed = InfoGreTun6::parse(&nla?)?; v.push(parsed); } InfoData::GreTun6(v) @@ -279,10 +233,7 @@ impl InfoData { InfoKind::Vti => { let mut v = Vec::new(); for nla in NlasIterator::new(payload) { - let nla = &nla.context(format!( - "invalid IFLA_INFO_DATA for {kind} {payload:?}" - ))?; - let parsed = InfoVti::parse(nla)?; + let parsed = InfoVti::parse(&nla?)?; v.push(parsed); } InfoData::Vti(v) @@ -290,10 +241,7 @@ impl InfoData { InfoKind::Vrf => { let mut v = Vec::new(); for nla in NlasIterator::new(payload) { - let nla = &nla.context(format!( - "invalid IFLA_INFO_DATA for {kind} {payload:?}" - ))?; - let parsed = InfoVrf::parse(nla)?; + let parsed = InfoVrf::parse(&nla?)?; v.push(parsed); } InfoData::Vrf(v) @@ -301,10 +249,7 @@ impl InfoData { InfoKind::Gtp => { let mut v = Vec::new(); for nla in NlasIterator::new(payload) { - let nla = &nla.context(format!( - "invalid IFLA_INFO_DATA for {kind} {payload:?}" - ))?; - let parsed = InfoGtp::parse(nla)?; + let parsed = InfoGtp::parse(&nla?)?; v.push(parsed); } InfoData::Gtp(v) @@ -312,10 +257,7 @@ impl InfoData { InfoKind::Ipoib => { let mut v = Vec::new(); for nla in NlasIterator::new(payload) { - let nla = &nla.context(format!( - "invalid IFLA_INFO_DATA for {kind} {payload:?}" - ))?; - let parsed = InfoIpoib::parse(nla)?; + let parsed = InfoIpoib::parse(&nla?)?; v.push(parsed); } InfoData::Ipoib(v) @@ -323,10 +265,7 @@ impl InfoData { InfoKind::Xfrm => { let mut v = Vec::new(); for nla in NlasIterator::new(payload) { - let nla = &nla.context(format!( - "invalid IFLA_INFO_DATA for {kind} {payload:?}" - ))?; - let parsed = InfoXfrm::parse(nla)?; + let parsed = InfoXfrm::parse(&nla?)?; v.push(parsed); } InfoData::Xfrm(v) @@ -334,10 +273,7 @@ impl InfoData { InfoKind::MacSec => { let mut v = Vec::new(); for nla in NlasIterator::new(payload) { - let nla = &nla.context(format!( - "invalid IFLA_INFO_DATA for {kind} {payload:?}" - ))?; - let parsed = InfoMacSec::parse(nla)?; + let parsed = InfoMacSec::parse(&nla?)?; v.push(parsed); } InfoData::MacSec(v) @@ -345,10 +281,7 @@ impl InfoData { InfoKind::Hsr => { let mut v = Vec::new(); for nla in NlasIterator::new(payload) { - let nla = &nla.context(format!( - "invalid IFLA_INFO_DATA for {kind} {payload:?}" - ))?; - let parsed = InfoHsr::parse(nla)?; + let parsed = InfoHsr::parse(&nla?)?; v.push(parsed); } InfoData::Hsr(v) @@ -356,10 +289,7 @@ impl InfoData { InfoKind::Geneve => { let mut v = Vec::new(); for nla in NlasIterator::new(payload) { - let nla = &nla.context(format!( - "invalid IFLA_INFO_DATA for {kind} {payload:?}" - ))?; - let parsed = InfoGeneve::parse(nla)?; + let parsed = InfoGeneve::parse(&nla?)?; v.push(parsed); } InfoData::Geneve(v) diff --git a/src/link/link_info/info_port.rs b/src/link/link_info/info_port.rs index 952a860b..906faf25 100644 --- a/src/link/link_info/info_port.rs +++ b/src/link/link_info/info_port.rs @@ -1,8 +1,7 @@ // SPDX-License-Identifier: MIT -use anyhow::Context; use netlink_packet_utils::{ - nla::{Nla, NlaBuffer, NlasIterator}, + nla::{Nla, NlaBuffer, NlaError, NlasIterator}, parsers::parse_string, DecodeError, Emitable, Parseable, }; @@ -70,8 +69,10 @@ impl Nla for InfoPortKind { } } -impl<'a, T: AsRef<[u8]> + ?Sized> Parseable> for InfoPortKind { - fn parse(buf: &NlaBuffer<&'a T>) -> Result { +impl + ?Sized> Parseable> for InfoPortKind { + type Error = DecodeError; + + fn parse(buf: &NlaBuffer<&T>) -> Result { if buf.kind() != IFLA_INFO_PORT_KIND { return Err(format!( "failed to parse IFLA_INFO_PORT_KIND: NLA type is {}", @@ -79,8 +80,7 @@ impl<'a, T: AsRef<[u8]> + ?Sized> Parseable> for InfoPortKind { ) .into()); } - let s = parse_string(buf.value()) - .context("invalid IFLA_INFO_PORT_KIND value")?; + let s = parse_string(buf.value())?; Ok(match s.as_str() { BOND => Self::Bond, BRIDGE => Self::Bridge, @@ -132,22 +132,38 @@ impl InfoPortData { ) -> Result { let port_data = match kind { InfoPortKind::Bond => NlasIterator::new(payload) - .map(|nla| nla.and_then(|nla| InfoBondPort::parse(&nla))) + .map(|nla| { + nla.and_then(|nla| { + InfoBondPort::parse(&nla) + // Placeholder error, as we need to return a NlaError + .map_err(|_| NlaError::InvalidLength { nla_len: 0 }) + }) + }) .collect::, _>>() .map(InfoPortData::BondPort), InfoPortKind::Bridge => NlasIterator::new(payload) - .map(|nla| nla.and_then(|nla| InfoBridgePort::parse(&nla))) + .map(|nla| { + nla.and_then(|nla| { + InfoBridgePort::parse(&nla) + // Placeholder error, as we need to return a NlaError + .map_err(|_| NlaError::InvalidLength { nla_len: 0 }) + }) + }) .collect::, _>>() .map(InfoPortData::BridgePort), InfoPortKind::Vrf => NlasIterator::new(payload) - .map(|nla| nla.and_then(|nla| InfoVrfPort::parse(&nla))) + .map(|nla| { + nla.and_then(|nla| { + InfoVrfPort::parse(&nla) + // Placeholder error, as we need to return a NlaError + .map_err(|_| NlaError::InvalidLength { nla_len: 0 }) + }) + }) .collect::, _>>() .map(InfoPortData::VrfPort), InfoPortKind::Other(_) => Ok(InfoPortData::Other(payload.to_vec())), }; - Ok(port_data.context(format!( - "failed to parse IFLA_INFO_PORT_DATA (IFLA_INFO_PORT_KIND is '{kind}')" - ))?) + Ok(port_data?) } } diff --git a/src/link/link_info/infos.rs b/src/link/link_info/infos.rs index 04905a78..89aaa659 100644 --- a/src/link/link_info/infos.rs +++ b/src/link/link_info/infos.rs @@ -1,6 +1,5 @@ // SPDX-License-Identifier: MIT -use anyhow::Context; use netlink_packet_utils::{ nla::{DefaultNla, Nla, NlaBuffer, NlasIterator}, parsers::parse_string, @@ -103,8 +102,10 @@ pub(crate) struct VecLinkInfo(pub(crate) Vec); // // The downside is that this impl will not be exposed. -impl<'a, T: AsRef<[u8]> + ?Sized> Parseable> for VecLinkInfo { - fn parse(buf: &NlaBuffer<&'a T>) -> Result { +impl + ?Sized> Parseable> for VecLinkInfo { + type Error = DecodeError; + + fn parse(buf: &NlaBuffer<&T>) -> Result { let mut nlas = Vec::new(); let mut link_info_kind: Option = None; let mut link_info_port_kind: Option = None; @@ -159,12 +160,7 @@ impl<'a, T: AsRef<[u8]> + ?Sized> Parseable> for VecLinkInfo { .into()); } } - _kind => nlas.push(LinkInfo::Other( - DefaultNla::parse(&nla).context(format!( - "Unknown NLA type for IFLA_INFO_DATA {:?}", - nla - ))?, - )), + _kind => nlas.push(LinkInfo::Other(DefaultNla::parse(&nla)?)), } } Ok(Self(nlas)) @@ -293,8 +289,10 @@ impl Nla for InfoKind { } } -impl<'a, T: AsRef<[u8]> + ?Sized> Parseable> for InfoKind { - fn parse(buf: &NlaBuffer<&'a T>) -> Result { +impl + ?Sized> Parseable> for InfoKind { + type Error = DecodeError; + + fn parse(buf: &NlaBuffer<&T>) -> Result { if buf.kind() != IFLA_INFO_KIND { return Err(format!( "failed to parse IFLA_INFO_KIND: NLA type is {}", @@ -302,8 +300,7 @@ impl<'a, T: AsRef<[u8]> + ?Sized> Parseable> for InfoKind { ) .into()); } - let s = parse_string(buf.value()) - .context("invalid IFLA_INFO_KIND value")?; + let s = parse_string(buf.value())?; Ok(match s.as_str() { DUMMY => Self::Dummy, IFB => Self::Ifb, diff --git a/src/link/link_info/ipoib.rs b/src/link/link_info/ipoib.rs index e68c57b6..c7909cee 100644 --- a/src/link/link_info/ipoib.rs +++ b/src/link/link_info/ipoib.rs @@ -1,6 +1,5 @@ // SPDX-License-Identifier: MIT -use anyhow::Context; use byteorder::{ByteOrder, NativeEndian}; use netlink_packet_utils::{ nla::{DefaultNla, Nla, NlaBuffer}, @@ -52,24 +51,17 @@ impl Nla for InfoIpoib { } } -impl<'a, T: AsRef<[u8]> + ?Sized> Parseable> for InfoIpoib { - fn parse(buf: &NlaBuffer<&'a T>) -> Result { +impl + ?Sized> Parseable> for InfoIpoib { + type Error = DecodeError; + + fn parse(buf: &NlaBuffer<&T>) -> Result { use self::InfoIpoib::*; let payload = buf.value(); Ok(match buf.kind() { - IFLA_IPOIB_PKEY => Pkey( - parse_u16(payload).context("invalid IFLA_IPOIB_PKEY value")?, - ), - IFLA_IPOIB_MODE => Mode( - parse_u16(payload).context("invalid IFLA_IPOIB_MODE value")?, - ), - IFLA_IPOIB_UMCAST => UmCast( - parse_u16(payload) - .context("invalid IFLA_IPOIB_UMCAST value")?, - ), - kind => Other(DefaultNla::parse(buf).context(format!( - "unknown NLA type {kind} for IFLA_INFO_DATA(ipoib)" - ))?), + IFLA_IPOIB_PKEY => Pkey(parse_u16(payload)?), + IFLA_IPOIB_MODE => Mode(parse_u16(payload)?), + IFLA_IPOIB_UMCAST => UmCast(parse_u16(payload)?), + _ => Other(DefaultNla::parse(buf)?), }) } } diff --git a/src/link/link_info/ipvlan.rs b/src/link/link_info/ipvlan.rs index 3cc1e0e0..2d1c6421 100644 --- a/src/link/link_info/ipvlan.rs +++ b/src/link/link_info/ipvlan.rs @@ -1,6 +1,5 @@ // SPDX-License-Identifier: MIT -use anyhow::Context; use byteorder::{ByteOrder, NativeEndian}; use netlink_packet_utils::{ nla::{DefaultNla, Nla, NlaBuffer}, @@ -48,23 +47,18 @@ impl Nla for InfoIpVlan { } } -impl<'a, T: AsRef<[u8]> + ?Sized> Parseable> for InfoIpVlan { - fn parse(buf: &NlaBuffer<&'a T>) -> Result { +impl + ?Sized> Parseable> for InfoIpVlan { + type Error = DecodeError; + + fn parse(buf: &NlaBuffer<&T>) -> Result { use self::InfoIpVlan::*; let payload = buf.value(); Ok(match buf.kind() { - IFLA_IPVLAN_MODE => Mode( - parse_u16(payload) - .context("invalid IFLA_IPVLAN_MODE value")? - .into(), - ), - IFLA_IPVLAN_FLAGS => Self::Flags(IpVlanFlags::from_bits_retain( - parse_u16(payload) - .context("failed to parse IFLA_IPVLAN_FLAGS")?, - )), - kind => Other(DefaultNla::parse(buf).context(format!( - "unknown NLA type {kind} for IFLA_INFO_DATA(ipvlan)" - ))?), + IFLA_IPVLAN_MODE => Mode(parse_u16(payload)?.into()), + IFLA_IPVLAN_FLAGS => { + Self::Flags(IpVlanFlags::from_bits_retain(parse_u16(payload)?)) + } + _ => Other(DefaultNla::parse(buf)?), }) } } @@ -105,23 +99,18 @@ impl Nla for InfoIpVtap { } } -impl<'a, T: AsRef<[u8]> + ?Sized> Parseable> for InfoIpVtap { - fn parse(buf: &NlaBuffer<&'a T>) -> Result { +impl + ?Sized> Parseable> for InfoIpVtap { + type Error = DecodeError; + + fn parse(buf: &NlaBuffer<&T>) -> Result { use self::InfoIpVtap::*; let payload = buf.value(); Ok(match buf.kind() { - IFLA_IPVLAN_MODE => Mode( - parse_u16(payload) - .context("invalid IFLA_IPVLAN_MODE value")? - .into(), - ), - IFLA_IPVLAN_FLAGS => Self::Flags(IpVtapFlags::from_bits_retain( - parse_u16(payload) - .context("failed to parse IFLA_IPVLAN_FLAGS")?, - )), - kind => Other(DefaultNla::parse(buf).context(format!( - "unknown NLA type {kind} for IFLA_INFO_DATA(ipvlan)" - ))?), + IFLA_IPVLAN_MODE => Mode(parse_u16(payload)?.into()), + IFLA_IPVLAN_FLAGS => { + Self::Flags(IpVtapFlags::from_bits_retain(parse_u16(payload)?)) + } + _ => Other(DefaultNla::parse(buf)?), }) } } diff --git a/src/link/link_info/mac_vlan.rs b/src/link/link_info/mac_vlan.rs index 88d454a1..b892b1a9 100644 --- a/src/link/link_info/mac_vlan.rs +++ b/src/link/link_info/mac_vlan.rs @@ -1,6 +1,5 @@ // SPDX-License-Identifier: MIT -use anyhow::Context; use byteorder::{ByteOrder, NativeEndian}; use netlink_packet_utils::{ nla::{DefaultNla, Nla, NlaBuffer, NlasIterator}, @@ -89,57 +88,32 @@ impl Nla for InfoMacVlan { } } -impl<'a, T: AsRef<[u8]> + ?Sized> Parseable> for InfoMacVlan { - fn parse(buf: &NlaBuffer<&'a T>) -> Result { +impl + ?Sized> Parseable> for InfoMacVlan { + type Error = DecodeError; + + fn parse(buf: &NlaBuffer<&T>) -> Result { use self::InfoMacVlan::*; let payload = buf.value(); Ok(match buf.kind() { - IFLA_MACVLAN_MODE => Mode( - parse_u32(payload) - .context("invalid IFLA_MACVLAN_MODE value")? - .into(), - ), - IFLA_MACVLAN_FLAGS => Flags( - parse_u16(payload) - .context("invalid IFLA_MACVLAN_FLAGS value")?, - ), - IFLA_MACVLAN_MACADDR_MODE => MacAddrMode( - parse_u32(payload) - .context("invalid IFLA_MACVLAN_MACADDR_MODE value")?, - ), - IFLA_MACVLAN_MACADDR => MacAddr( - parse_mac(payload) - .context("invalid IFLA_MACVLAN_MACADDR value")?, - ), + IFLA_MACVLAN_MODE => Mode(parse_u32(payload)?.into()), + IFLA_MACVLAN_FLAGS => Flags(parse_u16(payload)?), + IFLA_MACVLAN_MACADDR_MODE => MacAddrMode(parse_u32(payload)?), + IFLA_MACVLAN_MACADDR => MacAddr(parse_mac(payload)?), IFLA_MACVLAN_MACADDR_DATA => { let mut mac_data = Vec::new(); - let err = "failed to parse IFLA_MACVLAN_MACADDR_DATA"; for nla in NlasIterator::new(payload) { - let nla = &nla.context(err)?; - let parsed = InfoMacVlan::parse(nla).context(err)?; + let parsed = InfoMacVlan::parse(&nla?)?; mac_data.push(parsed); } MacAddrData(mac_data) } - IFLA_MACVLAN_MACADDR_COUNT => MacAddrCount( - parse_u32(payload) - .context("invalid IFLA_MACVLAN_MACADDR_COUNT value")?, - ), - IFLA_MACVLAN_BC_QUEUE_LEN => BcQueueLen( - parse_u32(payload) - .context("invalid IFLA_MACVLAN_BC_QUEUE_LEN value")?, - ), - IFLA_MACVLAN_BC_QUEUE_LEN_USED => BcQueueLenUsed( - parse_u32(payload) - .context("invalid IFLA_MACVLAN_BC_QUEUE_LEN_USED value")?, - ), - IFLA_MACVLAN_BC_CUTOFF => BcCutoff( - parse_i32(payload) - .context("invalid IFLA_MACVLAN_BC_CUTOFF value")?, - ), - kind => Other(DefaultNla::parse(buf).context(format!( - "unknown NLA type {kind} for IFLA_INFO_DATA(mac_vlan)" - ))?), + IFLA_MACVLAN_MACADDR_COUNT => MacAddrCount(parse_u32(payload)?), + IFLA_MACVLAN_BC_QUEUE_LEN => BcQueueLen(parse_u32(payload)?), + IFLA_MACVLAN_BC_QUEUE_LEN_USED => { + BcQueueLenUsed(parse_u32(payload)?) + } + IFLA_MACVLAN_BC_CUTOFF => BcCutoff(parse_i32(payload)?), + _ => Other(DefaultNla::parse(buf)?), }) } } @@ -209,57 +183,32 @@ impl Nla for InfoMacVtap { } } -impl<'a, T: AsRef<[u8]> + ?Sized> Parseable> for InfoMacVtap { - fn parse(buf: &NlaBuffer<&'a T>) -> Result { +impl + ?Sized> Parseable> for InfoMacVtap { + type Error = DecodeError; + + fn parse(buf: &NlaBuffer<&T>) -> Result { use self::InfoMacVtap::*; let payload = buf.value(); Ok(match buf.kind() { - IFLA_MACVLAN_MODE => Mode( - parse_u32(payload) - .context("invalid IFLA_MACVLAN_MODE value")? - .into(), - ), - IFLA_MACVLAN_FLAGS => Flags( - parse_u16(payload) - .context("invalid IFLA_MACVLAN_FLAGS value")?, - ), - IFLA_MACVLAN_MACADDR_MODE => MacAddrMode( - parse_u32(payload) - .context("invalid IFLA_MACVLAN_MACADDR_MODE value")?, - ), - IFLA_MACVLAN_MACADDR => MacAddr( - parse_mac(payload) - .context("invalid IFLA_MACVLAN_MACADDR value")?, - ), + IFLA_MACVLAN_MODE => Mode(parse_u32(payload)?.into()), + IFLA_MACVLAN_FLAGS => Flags(parse_u16(payload)?), + IFLA_MACVLAN_MACADDR_MODE => MacAddrMode(parse_u32(payload)?), + IFLA_MACVLAN_MACADDR => MacAddr(parse_mac(payload)?), IFLA_MACVLAN_MACADDR_DATA => { let mut mac_data = Vec::new(); - let err = "failed to parse IFLA_MACVLAN_MACADDR_DATA"; for nla in NlasIterator::new(payload) { - let nla = &nla.context(err)?; - let parsed = InfoMacVtap::parse(nla).context(err)?; + let parsed = InfoMacVtap::parse(&nla?)?; mac_data.push(parsed); } MacAddrData(mac_data) } - IFLA_MACVLAN_MACADDR_COUNT => MacAddrCount( - parse_u32(payload) - .context("invalid IFLA_MACVLAN_MACADDR_COUNT value")?, - ), - IFLA_MACVLAN_BC_QUEUE_LEN => BcQueueLen( - parse_u32(payload) - .context("invalid IFLA_MACVLAN_BC_QUEUE_LEN value")?, - ), - IFLA_MACVLAN_BC_QUEUE_LEN_USED => BcQueueLenUsed( - parse_u32(payload) - .context("invalid IFLA_MACVLAN_BC_QUEUE_LEN_USED value")?, - ), - IFLA_MACVLAN_BC_CUTOFF => BcCutoff( - parse_i32(payload) - .context("invalid IFLA_MACVLAN_BC_CUTOFF value")?, - ), - kind => Other(DefaultNla::parse(buf).context(format!( - "unknown NLA type {kind} for IFLA_INFO_DATA(mac_vtap)" - ))?), + IFLA_MACVLAN_MACADDR_COUNT => MacAddrCount(parse_u32(payload)?), + IFLA_MACVLAN_BC_QUEUE_LEN => BcQueueLen(parse_u32(payload)?), + IFLA_MACVLAN_BC_QUEUE_LEN_USED => { + BcQueueLenUsed(parse_u32(payload)?) + } + IFLA_MACVLAN_BC_CUTOFF => BcCutoff(parse_i32(payload)?), + _ => Other(DefaultNla::parse(buf)?), }) } } diff --git a/src/link/link_info/macsec.rs b/src/link/link_info/macsec.rs index c8d24111..b0740070 100644 --- a/src/link/link_info/macsec.rs +++ b/src/link/link_info/macsec.rs @@ -1,6 +1,5 @@ // SPDX-License-Identifier: MIT -use anyhow::Context; use byteorder::{ByteOrder, NativeEndian}; use netlink_packet_utils::{ nla::{DefaultNla, Nla, NlaBuffer}, @@ -212,72 +211,28 @@ impl Nla for InfoMacSec { } } -impl<'a, T: AsRef<[u8]> + ?Sized> Parseable> for InfoMacSec { - fn parse(buf: &NlaBuffer<&'a T>) -> Result { +impl + ?Sized> Parseable> for InfoMacSec { + type Error = DecodeError; + + fn parse(buf: &NlaBuffer<&T>) -> Result { use self::InfoMacSec::*; let payload = buf.value(); Ok(match buf.kind() { - IFLA_MACSEC_SCI => { - Sci(parse_u64(payload) - .context("invalid IFLA_MACSEC_SCI value")?) - } - IFLA_MACSEC_PORT => Port( - parse_u16(payload).context("invalid IFLA_MACSEC_PORT value")?, - ), - IFLA_MACSEC_ICV_LEN => IcvLen( - parse_u8(payload) - .context("invalid IFLA_MACSEC_ICV_LEN value")?, - ), - IFLA_MACSEC_CIPHER_SUITE => CipherSuite( - parse_u64(payload) - .context("invalid IFLA_MACSEC_CIPHER_SUITE value")? - .into(), - ), - IFLA_MACSEC_WINDOW => Window( - parse_u32(payload) - .context("invalid IFLA_MACSEC_WINDOW value")?, - ), - IFLA_MACSEC_ENCODING_SA => EncodingSa( - parse_u8(payload) - .context("invalid IFLA_MACSEC_ENCODING_SA value")?, - ), - IFLA_MACSEC_ENCRYPT => Encrypt( - parse_u8(payload) - .context("invalid IFLA_MACSEC_ENCRYPT value")?, - ), - IFLA_MACSEC_PROTECT => Protect( - parse_u8(payload) - .context("invalid IFLA_MACSEC_PROTECT value")?, - ), - IFLA_MACSEC_INC_SCI => IncSci( - parse_u8(payload) - .context("invalid IFLA_MACSEC_INC_SCI value")?, - ), - IFLA_MACSEC_ES => { - Es(parse_u8(payload).context("invalid IFLA_MACSEC_ES value")?) - } - IFLA_MACSEC_SCB => { - Scb(parse_u8(payload) - .context("invalid IFLA_MACSEC_SCB value")?) - } - IFLA_MACSEC_REPLAY_PROTECT => ReplayProtect( - parse_u8(payload) - .context("invalid IFLA_MACSEC_REPLAY_PROTECT value")?, - ), - IFLA_MACSEC_VALIDATION => Validation( - parse_u8(payload) - .context("invalid IFLA_MACSEC_VALIDATION value")? - .into(), - ), - IFLA_MACSEC_OFFLOAD => Offload( - parse_u8(payload) - .context("invalid IFLA_MACSEC_OFFLOAD value")? - .into(), - ), - kind => Other( - DefaultNla::parse(buf) - .context(format!("unknown NLA type {kind}"))?, - ), + IFLA_MACSEC_SCI => Sci(parse_u64(payload)?), + IFLA_MACSEC_PORT => Port(parse_u16(payload)?), + IFLA_MACSEC_ICV_LEN => IcvLen(parse_u8(payload)?), + IFLA_MACSEC_CIPHER_SUITE => CipherSuite(parse_u64(payload)?.into()), + IFLA_MACSEC_WINDOW => Window(parse_u32(payload)?), + IFLA_MACSEC_ENCODING_SA => EncodingSa(parse_u8(payload)?), + IFLA_MACSEC_ENCRYPT => Encrypt(parse_u8(payload)?), + IFLA_MACSEC_PROTECT => Protect(parse_u8(payload)?), + IFLA_MACSEC_INC_SCI => IncSci(parse_u8(payload)?), + IFLA_MACSEC_ES => Es(parse_u8(payload)?), + IFLA_MACSEC_SCB => Scb(parse_u8(payload)?), + IFLA_MACSEC_REPLAY_PROTECT => ReplayProtect(parse_u8(payload)?), + IFLA_MACSEC_VALIDATION => Validation(parse_u8(payload)?.into()), + IFLA_MACSEC_OFFLOAD => Offload(parse_u8(payload)?.into()), + _ => Other(DefaultNla::parse(buf)?), }) } } diff --git a/src/link/link_info/sit.rs b/src/link/link_info/sit.rs index f4977f63..412a821c 100644 --- a/src/link/link_info/sit.rs +++ b/src/link/link_info/sit.rs @@ -1,6 +1,5 @@ // SPDX-License-Identifier: MIT -use anyhow::Context; use netlink_packet_utils::{ nla::{DefaultNla, Nla, NlaBuffer}, DecodeError, Parseable, @@ -32,14 +31,13 @@ impl Nla for InfoSitTun { } } -impl<'a, T: AsRef<[u8]> + ?Sized> Parseable> for InfoSitTun { - fn parse(buf: &NlaBuffer<&'a T>) -> Result { +impl + ?Sized> Parseable> for InfoSitTun { + type Error = DecodeError; + + fn parse(buf: &NlaBuffer<&T>) -> Result { #[allow(clippy::match_single_binding)] Ok(match buf.kind() { - kind => Self::Other( - DefaultNla::parse(buf) - .context(format!("unknown NLA type {kind} for sit"))?, - ), + _ => Self::Other(DefaultNla::parse(buf)?), }) } } diff --git a/src/link/link_info/tun.rs b/src/link/link_info/tun.rs index e7326c21..da3375c2 100644 --- a/src/link/link_info/tun.rs +++ b/src/link/link_info/tun.rs @@ -1,6 +1,5 @@ // SPDX-License-Identifier: MIT -use anyhow::Context; use netlink_packet_utils::{ nla::{DefaultNla, Nla, NlaBuffer}, DecodeError, Parseable, @@ -32,13 +31,13 @@ impl Nla for InfoTun { } } -impl<'a, T: AsRef<[u8]> + ?Sized> Parseable> for InfoTun { - fn parse(buf: &NlaBuffer<&'a T>) -> Result { +impl + ?Sized> Parseable> for InfoTun { + type Error = DecodeError; + + fn parse(buf: &NlaBuffer<&T>) -> Result { #[allow(clippy::match_single_binding)] Ok(match buf.kind() { - kind => Self::Other(DefaultNla::parse(buf).context(format!( - "unknown NLA type {kind} for IFLA_INFO_DATA(vrf)" - ))?), + _ => Self::Other(DefaultNla::parse(buf)?), }) } } diff --git a/src/link/link_info/veth.rs b/src/link/link_info/veth.rs index e36f698d..a5f17442 100644 --- a/src/link/link_info/veth.rs +++ b/src/link/link_info/veth.rs @@ -1,6 +1,5 @@ // SPDX-License-Identifier: MIT -use anyhow::Context; use netlink_packet_utils::{ nla::{DefaultNla, Nla, NlaBuffer}, traits::{Emitable, Parseable}, @@ -47,21 +46,18 @@ impl Nla for InfoVeth { } } -impl<'a, T: AsRef<[u8]> + ?Sized> Parseable> for InfoVeth { - fn parse(buf: &NlaBuffer<&'a T>) -> Result { +impl + ?Sized> Parseable> for InfoVeth { + type Error = DecodeError; + + fn parse(buf: &NlaBuffer<&T>) -> Result { use self::InfoVeth::*; let payload = buf.value(); Ok(match buf.kind() { VETH_INFO_PEER => { - let err = "failed to parse veth link info"; - let buffer = - LinkMessageBuffer::new_checked(&payload).context(err)?; - Peer(LinkMessage::parse(&buffer).context(err)?) + let buffer = LinkMessageBuffer::new_checked(&payload)?; + Peer(LinkMessage::parse(&buffer)?) } - kind => Other( - DefaultNla::parse(buf) - .context(format!("unknown NLA type {kind}"))?, - ), + _ => Other(DefaultNla::parse(buf)?), }) } } diff --git a/src/link/link_info/vlan.rs b/src/link/link_info/vlan.rs index d4c1ab4a..1c02e8ee 100644 --- a/src/link/link_info/vlan.rs +++ b/src/link/link_info/vlan.rs @@ -1,6 +1,5 @@ // SPDX-License-Identifier: MIT -use anyhow::Context; use byteorder::{BigEndian, ByteOrder, NativeEndian}; use netlink_packet_utils::{ nla::{DefaultNla, Nla, NlaBuffer, NlasIterator}, @@ -106,10 +105,10 @@ impl Nla for VlanQosMapping { } } -impl<'a, T: AsRef<[u8]> + ?Sized> Parseable> - for VlanQosMapping -{ - fn parse(buf: &NlaBuffer<&'a T>) -> Result { +impl + ?Sized> Parseable> for VlanQosMapping { + type Error = DecodeError; + + fn parse(buf: &NlaBuffer<&T>) -> Result { use VlanQosMapping::*; let payload = buf.value(); Ok(match buf.kind() { @@ -117,16 +116,9 @@ impl<'a, T: AsRef<[u8]> + ?Sized> Parseable> if payload.len() != 8 { return Err("invalid IFLA_VLAN_QOS_MAPPING value".into()); } - Mapping( - parse_u32(&payload[..4]) - .context("expected u32 from value")?, - parse_u32(&payload[4..]) - .context("expected u32 to value")?, - ) + Mapping(parse_u32(&payload[..4])?, parse_u32(&payload[4..])?) } - kind => Other(DefaultNla::parse(buf).context(format!( - "unknown NLA type {kind} for VLAN QoS mapping" - ))?), + _ => Other(DefaultNla::parse(buf)?), }) } } @@ -141,40 +133,27 @@ fn parse_mappings(payload: &[u8]) -> Result, DecodeError> { Ok(mappings) } -impl<'a, T: AsRef<[u8]> + ?Sized> Parseable> for InfoVlan { - fn parse(buf: &NlaBuffer<&'a T>) -> Result { +impl + ?Sized> Parseable> for InfoVlan { + type Error = DecodeError; + + fn parse(buf: &NlaBuffer<&T>) -> Result { use self::InfoVlan::*; let payload = buf.value(); Ok(match buf.kind() { - IFLA_VLAN_ID => { - Id(parse_u16(payload).context("invalid IFLA_VLAN_ID value")?) - } + IFLA_VLAN_ID => Id(parse_u16(payload)?), IFLA_VLAN_FLAGS => { let err = "invalid IFLA_VLAN_FLAGS value"; if payload.len() != 8 { return Err(err.into()); } - let flags = parse_u32(&payload[0..4]).context(err)?; - let mask = parse_u32(&payload[4..]).context(err)?; + let flags = parse_u32(&payload[0..4])?; + let mask = parse_u32(&payload[4..])?; Flags((flags, mask)) } - IFLA_VLAN_EGRESS_QOS => EgressQos( - parse_mappings(payload) - .context("failed to parse IFLA_VLAN_EGRESS_QOS")?, - ), - IFLA_VLAN_INGRESS_QOS => IngressQos( - parse_mappings(payload) - .context("failed to parse IFLA_VLAN_INGRESS_QOS")?, - ), - IFLA_VLAN_PROTOCOL => Protocol( - parse_u16_be(payload) - .context("invalid IFLA_VLAN_PROTOCOL value")? - .into(), - ), - _ => Self::Other(DefaultNla::parse(buf).context(format!( - "invalid NLA for {}: {payload:?}", - buf.kind() - ))?), + IFLA_VLAN_EGRESS_QOS => EgressQos(parse_mappings(payload)?), + IFLA_VLAN_INGRESS_QOS => IngressQos(parse_mappings(payload)?), + IFLA_VLAN_PROTOCOL => Protocol(parse_u16_be(payload)?.into()), + _ => Self::Other(DefaultNla::parse(buf)?), }) } } diff --git a/src/link/link_info/vrf.rs b/src/link/link_info/vrf.rs index a8524e12..8f0e162f 100644 --- a/src/link/link_info/vrf.rs +++ b/src/link/link_info/vrf.rs @@ -1,6 +1,5 @@ // SPDX-License-Identifier: MIT -use anyhow::Context; use byteorder::{ByteOrder, NativeEndian}; use netlink_packet_utils::{ nla::{DefaultNla, Nla, NlaBuffer}, @@ -44,17 +43,15 @@ impl Nla for InfoVrf { } } -impl<'a, T: AsRef<[u8]> + ?Sized> Parseable> for InfoVrf { - fn parse(buf: &NlaBuffer<&'a T>) -> Result { +impl + ?Sized> Parseable> for InfoVrf { + type Error = DecodeError; + + fn parse(buf: &NlaBuffer<&T>) -> Result { use self::InfoVrf::*; let payload = buf.value(); Ok(match buf.kind() { - IFLA_VRF_TABLE => TableId( - parse_u32(payload).context("invalid IFLA_VRF_TABLE value")?, - ), - kind => Other(DefaultNla::parse(buf).context(format!( - "unknown NLA type {kind} for IFLA_INFO_DATA(vrf)" - ))?), + IFLA_VRF_TABLE => TableId(parse_u32(payload)?), + _ => Other(DefaultNla::parse(buf)?), }) } } diff --git a/src/link/link_info/vti.rs b/src/link/link_info/vti.rs index bfe52608..25ae4026 100644 --- a/src/link/link_info/vti.rs +++ b/src/link/link_info/vti.rs @@ -1,6 +1,5 @@ // SPDX-License-Identifier: MIT -use anyhow::Context; use netlink_packet_utils::{ nla::{DefaultNla, Nla, NlaBuffer}, DecodeError, Parseable, @@ -32,14 +31,13 @@ impl Nla for InfoVti { } } -impl<'a, T: AsRef<[u8]> + ?Sized> Parseable> for InfoVti { - fn parse(buf: &NlaBuffer<&'a T>) -> Result { +impl + ?Sized> Parseable> for InfoVti { + type Error = DecodeError; + + fn parse(buf: &NlaBuffer<&T>) -> Result { #[allow(clippy::match_single_binding)] Ok(match buf.kind() { - kind => Self::Other( - DefaultNla::parse(buf) - .context(format!("unknown NLA type {kind} for vti"))?, - ), + _ => Self::Other(DefaultNla::parse(buf)?), }) } } diff --git a/src/link/link_info/vxlan.rs b/src/link/link_info/vxlan.rs index 8718c3f7..21a530a2 100644 --- a/src/link/link_info/vxlan.rs +++ b/src/link/link_info/vxlan.rs @@ -2,7 +2,6 @@ use std::net::{Ipv4Addr, Ipv6Addr}; -use anyhow::Context; use byteorder::{BigEndian, ByteOrder, NativeEndian}; use netlink_packet_utils::{ nla::{DefaultNla, Nla, NlaBuffer}, @@ -195,13 +194,13 @@ impl Nla for InfoVxlan { } } -impl<'a, T: AsRef<[u8]> + ?Sized> Parseable> for InfoVxlan { - fn parse(buf: &NlaBuffer<&'a T>) -> Result { +impl + ?Sized> Parseable> for InfoVxlan { + type Error = DecodeError; + + fn parse(buf: &NlaBuffer<&T>) -> Result { let payload = buf.value(); Ok(match buf.kind() { - IFLA_VXLAN_ID => { - Self::Id(parse_u32(payload).context("invalid IFLA_VXLAN_ID value")?) - } + IFLA_VXLAN_ID => Self::Id(parse_u32(payload)?), IFLA_VXLAN_GROUP => { if payload.len() == 4 { let mut data = [0u8; 4]; @@ -240,7 +239,7 @@ impl<'a, T: AsRef<[u8]> + ?Sized> Parseable> for InfoVxlan { payload ))); } - }, + } IFLA_VXLAN_LOCAL6 => { if payload.len() == 16 { let mut data = [0u8; 16]; @@ -253,107 +252,48 @@ impl<'a, T: AsRef<[u8]> + ?Sized> Parseable> for InfoVxlan { payload ))); } - }, - IFLA_VXLAN_LINK => Self::Link( - parse_u32(payload).context("invalid IFLA_VXLAN_LINK value")?, - ), - IFLA_VXLAN_TOS => { - Self::Tos(parse_u8(payload) - .context("invalid IFLA_VXLAN_TOS value")?) } - IFLA_VXLAN_TTL => { - Self::Ttl(parse_u8(payload) - .context("invalid IFLA_VXLAN_TTL value")?) + IFLA_VXLAN_LINK => Self::Link(parse_u32(payload)?), + IFLA_VXLAN_TOS => Self::Tos(parse_u8(payload)?), + IFLA_VXLAN_TTL => Self::Ttl(parse_u8(payload)?), + IFLA_VXLAN_LABEL => Self::Label(parse_u32(payload)?), + IFLA_VXLAN_LEARNING => Self::Learning(parse_u8(payload)? > 0), + IFLA_VXLAN_AGEING => Self::Ageing(parse_u32(payload)?), + IFLA_VXLAN_LIMIT => Self::Limit(parse_u32(payload)?), + IFLA_VXLAN_PROXY => Self::Proxy(parse_u8(payload)? > 0), + IFLA_VXLAN_RSC => Self::Rsc(parse_u8(payload)? > 0), + IFLA_VXLAN_L2MISS => Self::L2Miss(parse_u8(payload)? > 0), + IFLA_VXLAN_L3MISS => Self::L3Miss(parse_u8(payload)? > 0), + IFLA_VXLAN_COLLECT_METADATA => { + Self::CollectMetadata(parse_u8(payload)? > 0) } - IFLA_VXLAN_LABEL => Self::Label( - parse_u32(payload).context("invalid IFLA_VXLAN_LABEL value")?, - ), - IFLA_VXLAN_LEARNING => Self::Learning( - parse_u8(payload) - .context("invalid IFLA_VXLAN_LEARNING value")? > 0, - ), - IFLA_VXLAN_AGEING => Self::Ageing( - parse_u32(payload) - .context("invalid IFLA_VXLAN_AGEING value")?, - ), - IFLA_VXLAN_LIMIT => Self::Limit( - parse_u32(payload).context("invalid IFLA_VXLAN_LIMIT value")?, - ), - IFLA_VXLAN_PROXY => Self::Proxy( - parse_u8(payload).context("invalid IFLA_VXLAN_PROXY value")? > 0, - ), - IFLA_VXLAN_RSC => { - Self::Rsc(parse_u8(payload) - .context("invalid IFLA_VXLAN_RSC value")?> 0) - } - IFLA_VXLAN_L2MISS => Self::L2Miss( - parse_u8(payload).context("invalid IFLA_VXLAN_L2MISS value")? > 0, - ), - IFLA_VXLAN_L3MISS => Self::L3Miss( - parse_u8(payload).context("invalid IFLA_VXLAN_L3MISS value")? > 0, - ), - IFLA_VXLAN_COLLECT_METADATA => Self::CollectMetadata( - parse_u8(payload) - .context("invalid IFLA_VXLAN_COLLECT_METADATA value")? >0, - ), IFLA_VXLAN_PORT_RANGE => { let err = "invalid IFLA_VXLAN_PORT value"; if payload.len() != 4 { return Err(err.into()); } - let low = parse_u16_be(&payload[0..2]).context(err)?; - let high = parse_u16_be(&payload[2..]).context(err)?; + let low = parse_u16_be(&payload[0..2])?; + let high = parse_u16_be(&payload[2..])?; Self::PortRange((low, high)) } - IFLA_VXLAN_PORT => Self::Port( - parse_u16_be(payload) - .context("invalid IFLA_VXLAN_PORT value")?, - ), - IFLA_VXLAN_UDP_CSUM => Self::UDPCsum( - parse_u8(payload) - .context("invalid IFLA_VXLAN_UDP_CSUM value")? > 0, - ), - IFLA_VXLAN_UDP_ZERO_CSUM6_TX => Self::UDPZeroCsumTX( - parse_u8(payload) - .context("invalid IFLA_VXLAN_UDP_ZERO_CSUM6_TX value")? > 0, - ), - IFLA_VXLAN_UDP_ZERO_CSUM6_RX => Self::UDPZeroCsumRX( - parse_u8(payload) - .context("invalid IFLA_VXLAN_UDP_ZERO_CSUM6_RX value")? > 0, - ), - IFLA_VXLAN_REMCSUM_TX => Self::RemCsumTX( - parse_u8(payload) - .context("invalid IFLA_VXLAN_REMCSUM_TX value")? > 0, - ), - IFLA_VXLAN_REMCSUM_RX => Self::RemCsumRX( - parse_u8(payload) - .context("invalid IFLA_VXLAN_REMCSUM_RX value")? > 0, - ), - IFLA_VXLAN_DF => { - Self::Df(parse_u8(payload).context("invalid IFLA_VXLAN_DF value")?) - } - IFLA_VXLAN_GBP => { - Self::Gbp(true) + IFLA_VXLAN_PORT => Self::Port(parse_u16_be(payload)?), + IFLA_VXLAN_UDP_CSUM => Self::UDPCsum(parse_u8(payload)? > 0), + IFLA_VXLAN_UDP_ZERO_CSUM6_TX => { + Self::UDPZeroCsumTX(parse_u8(payload)? > 0) } - IFLA_VXLAN_GPE => { - Self::Gpe(true) + IFLA_VXLAN_UDP_ZERO_CSUM6_RX => { + Self::UDPZeroCsumRX(parse_u8(payload)? > 0) } + IFLA_VXLAN_REMCSUM_TX => Self::RemCsumTX(parse_u8(payload)? > 0), + IFLA_VXLAN_REMCSUM_RX => Self::RemCsumRX(parse_u8(payload)? > 0), + IFLA_VXLAN_DF => Self::Df(parse_u8(payload)?), + IFLA_VXLAN_GBP => Self::Gbp(true), + IFLA_VXLAN_GPE => Self::Gpe(true), IFLA_VXLAN_REMCSUM_NOPARTIAL => Self::RemCsumNoPartial(true), - IFLA_VXLAN_TTL_INHERIT => Self::TtlInherit( - parse_u8(payload) - .context("invalid IFLA_VXLAN_TTL_INHERIT value")? > 0, - ), - IFLA_VXLAN_VNIFILTER => Self::Vnifilter( - parse_u8(payload) - .context("invalid IFLA_VXLAN_VNIFILTER value")? > 0, - ), - IFLA_VXLAN_LOCALBYPASS => Self::Localbypass( - parse_u8(payload) - .context("invalid IFLA_VXLAN_LOCALBYPASS value")? > 0, - ), - unknown_kind => Self::Other(DefaultNla::parse(buf).context(format!( - "Failed to parse IFLA_INFO_DATA(vxlan) NLA type: {unknown_kind} as DefaultNla" - ))?), + IFLA_VXLAN_TTL_INHERIT => Self::TtlInherit(parse_u8(payload)? > 0), + IFLA_VXLAN_VNIFILTER => Self::Vnifilter(parse_u8(payload)? > 0), + IFLA_VXLAN_LOCALBYPASS => Self::Localbypass(parse_u8(payload)? > 0), + _ => Self::Other(DefaultNla::parse(buf)?), }) } } diff --git a/src/link/link_info/xfrm.rs b/src/link/link_info/xfrm.rs index d76ffc42..ae1f16f3 100644 --- a/src/link/link_info/xfrm.rs +++ b/src/link/link_info/xfrm.rs @@ -1,6 +1,5 @@ // SPDX-License-Identifier: MIT -use anyhow::Context; use byteorder::{ByteOrder, NativeEndian}; use netlink_packet_utils::{ nla::{DefaultNla, Nla, NlaBuffer}, @@ -49,20 +48,16 @@ impl Nla for InfoXfrm { } } -impl<'a, T: AsRef<[u8]> + ?Sized> Parseable> for InfoXfrm { - fn parse(buf: &NlaBuffer<&'a T>) -> Result { +impl + ?Sized> Parseable> for InfoXfrm { + type Error = DecodeError; + + fn parse(buf: &NlaBuffer<&T>) -> Result { use self::InfoXfrm::*; let payload = buf.value(); Ok(match buf.kind() { - IFLA_XFRM_LINK => Link( - parse_u32(payload).context("invalid IFLA_XFRM_LINK value")?, - ), - IFLA_XFRM_IF_ID => IfId( - parse_u32(payload).context("invalid IFLA_XFRM_IF_ID value")?, - ), - kind => Other(DefaultNla::parse(buf).context(format!( - "unknown NLA type {kind} for IFLA_INFO_DATA(xfrm)" - ))?), + IFLA_XFRM_LINK => Link(parse_u32(payload)?), + IFLA_XFRM_IF_ID => IfId(parse_u32(payload)?), + _ => Other(DefaultNla::parse(buf)?), }) } } diff --git a/src/link/link_info/xstats.rs b/src/link/link_info/xstats.rs index 9e5f5f1a..5f7539be 100644 --- a/src/link/link_info/xstats.rs +++ b/src/link/link_info/xstats.rs @@ -28,13 +28,15 @@ impl Emitable for LinkXstats { } } -impl<'a, T: AsRef<[u8]> + ?Sized> - ParseableParametrized, &InfoKind> for LinkXstats +impl + ?Sized> ParseableParametrized, &InfoKind> + for LinkXstats { + type Error = DecodeError; + fn parse_with_param( - buf: &NlaBuffer<&'a T>, + buf: &NlaBuffer<&T>, _kind: &InfoKind, - ) -> Result { + ) -> Result { Ok(Self::Other(buf.value().to_vec())) } } diff --git a/src/link/map.rs b/src/link/map.rs index 3a0e761f..b5c6780d 100644 --- a/src/link/map.rs +++ b/src/link/map.rs @@ -28,7 +28,9 @@ pub struct Map { } impl> Parseable> for Map { - fn parse(buf: &MapBuffer) -> Result { + type Error = DecodeError; + + fn parse(buf: &MapBuffer) -> Result { Ok(Self { memory_start: buf.memory_start(), memory_end: buf.memory_end(), diff --git a/src/link/message.rs b/src/link/message.rs index b6922a01..1072dcfc 100644 --- a/src/link/message.rs +++ b/src/link/message.rs @@ -1,6 +1,5 @@ // SPDX-License-Identifier: MIT -use anyhow::Context; use netlink_packet_utils::{ traits::{Emitable, Parseable, ParseableParametrized}, DecodeError, @@ -29,28 +28,27 @@ impl Emitable for LinkMessage { } } -impl<'a, T: AsRef<[u8]> + 'a> Parseable> - for LinkMessage -{ - fn parse(buf: &LinkMessageBuffer<&'a T>) -> Result { - let header = LinkHeader::parse(buf) - .context("failed to parse link message header")?; +impl> Parseable> for LinkMessage { + type Error = DecodeError; + + fn parse(buf: &LinkMessageBuffer<&T>) -> Result { + let header = LinkHeader::parse(buf)?; let interface_family = header.interface_family; let attributes = - Vec::::parse_with_param(buf, interface_family) - .context("failed to parse link message NLAs")?; + Vec::::parse_with_param(buf, interface_family)?; Ok(LinkMessage { header, attributes }) } } -impl<'a, T: AsRef<[u8]> + 'a> - ParseableParametrized, AddressFamily> +impl> ParseableParametrized, AddressFamily> for Vec { + type Error = DecodeError; + fn parse_with_param( - buf: &LinkMessageBuffer<&'a T>, + buf: &LinkMessageBuffer<&T>, family: AddressFamily, - ) -> Result { + ) -> Result { let mut attributes = vec![]; for nla_buf in buf.attributes() { attributes diff --git a/src/link/phys_id.rs b/src/link/phys_id.rs index 19d8fac2..10af2d12 100644 --- a/src/link/phys_id.rs +++ b/src/link/phys_id.rs @@ -15,7 +15,9 @@ pub struct LinkPhysId { } impl Parseable<[u8]> for LinkPhysId { - fn parse(buf: &[u8]) -> Result { + type Error = DecodeError; + + fn parse(buf: &[u8]) -> Result { let len = buf.len() % MAX_PHYS_ITEM_ID_LEN; let mut id = [0; MAX_PHYS_ITEM_ID_LEN]; id[..len].copy_from_slice(&buf[..len]); diff --git a/src/link/prop_list.rs b/src/link/prop_list.rs index 45fd74e0..e3f60312 100644 --- a/src/link/prop_list.rs +++ b/src/link/prop_list.rs @@ -1,6 +1,5 @@ // SPDX-License-Identifier: MIT -use anyhow::Context; use netlink_packet_utils::{ nla::{DefaultNla, Nla, NlaBuffer}, parsers::parse_string, @@ -48,18 +47,14 @@ impl Nla for Prop { } } -impl<'a, T: AsRef<[u8]> + ?Sized> Parseable> for Prop { - fn parse(buf: &NlaBuffer<&'a T>) -> Result { +impl + ?Sized> Parseable> for Prop { + type Error = DecodeError; + + fn parse(buf: &NlaBuffer<&T>) -> Result { let payload = buf.value(); Ok(match buf.kind() { - IFLA_ALT_IFNAME => Prop::AltIfName( - parse_string(payload) - .context("invalid IFLA_ALT_IFNAME value")?, - ), - kind => Prop::Other( - DefaultNla::parse(buf) - .context(format!("Unknown NLA type {kind}"))?, - ), + IFLA_ALT_IFNAME => Prop::AltIfName(parse_string(payload)?), + _ => Prop::Other(DefaultNla::parse(buf)?), }) } } diff --git a/src/link/proto_info/bridge.rs b/src/link/proto_info/bridge.rs index 8645cc15..4d60c2ee 100644 --- a/src/link/proto_info/bridge.rs +++ b/src/link/proto_info/bridge.rs @@ -1,6 +1,5 @@ // SPDX-License-Identifier: MIT -use anyhow::Context; use netlink_packet_utils::{ nla::{DefaultNla, Nla, NlaBuffer, NlasIterator}, traits::Parseable, @@ -18,14 +17,12 @@ pub(crate) struct VecLinkProtoInfoBridge(pub(crate) Vec); impl<'a, T: AsRef<[u8]> + ?Sized> Parseable> for VecLinkProtoInfoBridge { - fn parse(buf: &NlaBuffer<&'a T>) -> Result { + type Error = DecodeError; + + fn parse(buf: &NlaBuffer<&T>) -> Result { let mut nlas = vec![]; for nla in NlasIterator::new(buf.into_inner()) { - let nla = nla.context(format!( - "invalid bridge IFLA_PROTINFO {:?}", - buf.value() - ))?; - nlas.push(LinkProtoInfoBridge::parse(&nla)?); + nlas.push(LinkProtoInfoBridge::parse(&nla?)?); } Ok(Self(nlas)) } @@ -51,13 +48,10 @@ impl Nla for LinkProtoInfoBridge { } } -impl<'a, T: AsRef<[u8]> + ?Sized> Parseable> - for LinkProtoInfoBridge -{ - fn parse(buf: &NlaBuffer<&'a T>) -> Result { - Ok(Self::Other(DefaultNla::parse(buf).context(format!( - "invalid bridge IFLA_PROTINFO {:?}", - buf.value() - ))?)) +impl + ?Sized> Parseable> for LinkProtoInfoBridge { + type Error = DecodeError; + + fn parse(buf: &NlaBuffer<&T>) -> Result { + Ok(Self::Other(DefaultNla::parse(buf)?)) } } diff --git a/src/link/proto_info/inet6.rs b/src/link/proto_info/inet6.rs index e7cad4d0..9354de8c 100644 --- a/src/link/proto_info/inet6.rs +++ b/src/link/proto_info/inet6.rs @@ -1,6 +1,5 @@ // SPDX-License-Identifier: MIT -use anyhow::Context; use netlink_packet_utils::{ nla::{DefaultNla, Nla, NlaBuffer, NlasIterator}, traits::Parseable, @@ -15,17 +14,15 @@ pub enum LinkProtoInfoInet6 { pub(crate) struct VecLinkProtoInfoInet6(pub(crate) Vec); -impl<'a, T: AsRef<[u8]> + ?Sized> Parseable> +impl + ?Sized> Parseable> for VecLinkProtoInfoInet6 { - fn parse(buf: &NlaBuffer<&'a T>) -> Result { + type Error = DecodeError; + + fn parse(buf: &NlaBuffer<&T>) -> Result { let mut nlas = vec![]; for nla in NlasIterator::new(buf.into_inner()) { - let nla = nla.context(format!( - "invalid inet6 IFLA_PROTINFO {:?}", - buf.value() - ))?; - nlas.push(LinkProtoInfoInet6::parse(&nla)?); + nlas.push(LinkProtoInfoInet6::parse(&nla?)?); } Ok(Self(nlas)) } @@ -51,13 +48,10 @@ impl Nla for LinkProtoInfoInet6 { } } -impl<'a, T: AsRef<[u8]> + ?Sized> Parseable> - for LinkProtoInfoInet6 -{ - fn parse(buf: &NlaBuffer<&'a T>) -> Result { - Ok(Self::Other(DefaultNla::parse(buf).context(format!( - "invalid inet6 IFLA_PROTINFO {:?}", - buf.value() - ))?)) +impl + ?Sized> Parseable> for LinkProtoInfoInet6 { + type Error = DecodeError; + + fn parse(buf: &NlaBuffer<&T>) -> Result { + Ok(Self::Other(DefaultNla::parse(buf)?)) } } diff --git a/src/link/sriov/broadcast.rs b/src/link/sriov/broadcast.rs index 5cbc8d7d..59f21171 100644 --- a/src/link/sriov/broadcast.rs +++ b/src/link/sriov/broadcast.rs @@ -29,7 +29,9 @@ buffer!(VfInfoBroadcastBuffer(VF_INFO_BROADCAST_LEN) { impl + ?Sized> Parseable> for VfInfoBroadcast { - fn parse(buf: &VfInfoBroadcastBuffer<&T>) -> Result { + type Error = DecodeError; + + fn parse(buf: &VfInfoBroadcastBuffer<&T>) -> Result { Ok(Self::new(buf.addr())) } } diff --git a/src/link/sriov/guid.rs b/src/link/sriov/guid.rs index af54cd5d..f26f09fc 100644 --- a/src/link/sriov/guid.rs +++ b/src/link/sriov/guid.rs @@ -23,7 +23,9 @@ buffer!(VfInfoGuidBuffer(VF_INFO_GUID_LEN) { }); impl + ?Sized> Parseable> for VfInfoGuid { - fn parse(buf: &VfInfoGuidBuffer<&T>) -> Result { + type Error = DecodeError; + + fn parse(buf: &VfInfoGuidBuffer<&T>) -> Result { Ok(Self::new(buf.vf_id(), buf.guid())) } } diff --git a/src/link/sriov/link_state.rs b/src/link/sriov/link_state.rs index f1b7418f..d935c485 100644 --- a/src/link/sriov/link_state.rs +++ b/src/link/sriov/link_state.rs @@ -25,7 +25,9 @@ buffer!(VfInfoLinkStateBuffer(VF_INFO_LINK_STATE_LEN) { impl + ?Sized> Parseable> for VfInfoLinkState { - fn parse(buf: &VfInfoLinkStateBuffer<&T>) -> Result { + type Error = DecodeError; + + fn parse(buf: &VfInfoLinkStateBuffer<&T>) -> Result { Ok(Self::new(buf.vf_id(), buf.state().into())) } } diff --git a/src/link/sriov/mac.rs b/src/link/sriov/mac.rs index a7ff77dc..2047294c 100644 --- a/src/link/sriov/mac.rs +++ b/src/link/sriov/mac.rs @@ -34,7 +34,9 @@ buffer!(VfInfoMacBuffer(VF_INFO_MAC_LEN) { }); impl + ?Sized> Parseable> for VfInfoMac { - fn parse(buf: &VfInfoMacBuffer<&T>) -> Result { + type Error = DecodeError; + + fn parse(buf: &VfInfoMacBuffer<&T>) -> Result { Ok(Self::new(buf.vf_id(), buf.mac())) } } diff --git a/src/link/sriov/rate.rs b/src/link/sriov/rate.rs index 8618531d..13272cc3 100644 --- a/src/link/sriov/rate.rs +++ b/src/link/sriov/rate.rs @@ -29,7 +29,9 @@ buffer!(VfInfoRateBuffer(VF_INFO_RATE_LEN) { }); impl + ?Sized> Parseable> for VfInfoRate { - fn parse(buf: &VfInfoRateBuffer<&T>) -> Result { + type Error = DecodeError; + + fn parse(buf: &VfInfoRateBuffer<&T>) -> Result { Ok(Self { vf_id: buf.vf_id(), min_tx_rate: buf.min_tx_rate(), diff --git a/src/link/sriov/rss_query.rs b/src/link/sriov/rss_query.rs index e728ae69..fec90cc5 100644 --- a/src/link/sriov/rss_query.rs +++ b/src/link/sriov/rss_query.rs @@ -25,7 +25,9 @@ buffer!(VfInfoRssQueryEnBuffer(VF_INFO_RSS_QUERY_EN_LEN) { impl + ?Sized> Parseable> for VfInfoRssQueryEn { - fn parse(buf: &VfInfoRssQueryEnBuffer<&T>) -> Result { + type Error = DecodeError; + + fn parse(buf: &VfInfoRssQueryEnBuffer<&T>) -> Result { Ok(Self::new( buf.vf_id(), buf.setting() > 0 && buf.setting() != u32::MAX, diff --git a/src/link/sriov/spoofchk.rs b/src/link/sriov/spoofchk.rs index a568c650..ef831cb6 100644 --- a/src/link/sriov/spoofchk.rs +++ b/src/link/sriov/spoofchk.rs @@ -25,7 +25,9 @@ buffer!(VfInfoSpoofCheckBuffer(VF_INFO_SPOOFCHK_LEN) { impl + ?Sized> Parseable> for VfInfoSpoofCheck { - fn parse(buf: &VfInfoSpoofCheckBuffer<&T>) -> Result { + type Error = DecodeError; + + fn parse(buf: &VfInfoSpoofCheckBuffer<&T>) -> Result { Ok(Self::new( buf.vf_id(), buf.setting() > 0 && buf.setting() != u32::MAX, diff --git a/src/link/sriov/stats.rs b/src/link/sriov/stats.rs index 30a14dac..112cf17e 100644 --- a/src/link/sriov/stats.rs +++ b/src/link/sriov/stats.rs @@ -1,6 +1,5 @@ // SPDX-License-Identifier: MIT -use anyhow::Context; use byteorder::{ByteOrder, NativeEndian}; use netlink_packet_utils::{ nla::{DefaultNla, Nla, NlaBuffer}, @@ -70,52 +69,20 @@ impl Nla for VfStats { } impl<'a, T: AsRef<[u8]> + ?Sized> Parseable> for VfStats { - fn parse(buf: &NlaBuffer<&'a T>) -> Result { + type Error = DecodeError; + + fn parse(buf: &NlaBuffer<&'a T>) -> Result { let payload = buf.value(); Ok(match buf.kind() { - IFLA_VF_STATS_RX_PACKETS => { - Self::RxPackets(parse_u64(payload).context(format!( - "invalid IFLA_VF_STATS_RX_PACKETS value {payload:?}" - ))?) - } - IFLA_VF_STATS_TX_PACKETS => { - Self::TxPackets(parse_u64(payload).context(format!( - "invalid IFLA_VF_STATS_TX_PACKETS value {payload:?}" - ))?) - } - IFLA_VF_STATS_RX_BYTES => { - Self::RxBytes(parse_u64(payload).context(format!( - "invalid IFLA_VF_STATS_RX_BYTES value {payload:?}" - ))?) - } - IFLA_VF_STATS_TX_BYTES => { - Self::TxBytes(parse_u64(payload).context(format!( - "invalid IFLA_VF_STATS_TX_BYTES value {payload:?}" - ))?) - } - IFLA_VF_STATS_BROADCAST => { - Self::Broadcast(parse_u64(payload).context(format!( - "invalid IFLA_VF_STATS_BROADCAST value {payload:?}" - ))?) - } - IFLA_VF_STATS_MULTICAST => { - Self::Multicast(parse_u64(payload).context(format!( - "invalid IFLA_VF_STATS_MULTICAST value {payload:?}" - ))?) - } - IFLA_VF_STATS_RX_DROPPED => { - Self::RxDropped(parse_u64(payload).context(format!( - "invalid IFLA_VF_STATS_RX_DROPPED value {payload:?}" - ))?) - } - IFLA_VF_STATS_TX_DROPPED => { - Self::TxDropped(parse_u64(payload).context(format!( - "invalid IFLA_VF_STATS_TX_DROPPED value {payload:?}" - ))?) - } - kind => Self::Other(DefaultNla::parse(buf).context(format!( - "failed to parse {kind} as DefaultNla: {payload:?}" - ))?), + IFLA_VF_STATS_RX_PACKETS => Self::RxPackets(parse_u64(payload)?), + IFLA_VF_STATS_TX_PACKETS => Self::TxPackets(parse_u64(payload)?), + IFLA_VF_STATS_RX_BYTES => Self::RxBytes(parse_u64(payload)?), + IFLA_VF_STATS_TX_BYTES => Self::TxBytes(parse_u64(payload)?), + IFLA_VF_STATS_BROADCAST => Self::Broadcast(parse_u64(payload)?), + IFLA_VF_STATS_MULTICAST => Self::Multicast(parse_u64(payload)?), + IFLA_VF_STATS_RX_DROPPED => Self::RxDropped(parse_u64(payload)?), + IFLA_VF_STATS_TX_DROPPED => Self::TxDropped(parse_u64(payload)?), + _ => Self::Other(DefaultNla::parse(buf)?), }) } } diff --git a/src/link/sriov/trust.rs b/src/link/sriov/trust.rs index 72a1f834..998000d9 100644 --- a/src/link/sriov/trust.rs +++ b/src/link/sriov/trust.rs @@ -23,7 +23,9 @@ buffer!(VfInfoTrustBuffer(VF_INFO_TRUST_LEN) { }); impl + ?Sized> Parseable> for VfInfoTrust { - fn parse(buf: &VfInfoTrustBuffer<&T>) -> Result { + type Error = DecodeError; + + fn parse(buf: &VfInfoTrustBuffer<&T>) -> Result { Ok(Self::new( buf.vf_id(), buf.setting() > 0 && buf.setting() != u32::MAX, diff --git a/src/link/sriov/tx_rate.rs b/src/link/sriov/tx_rate.rs index 09678e1a..b6e00d74 100644 --- a/src/link/sriov/tx_rate.rs +++ b/src/link/sriov/tx_rate.rs @@ -25,7 +25,9 @@ buffer!(VfInfoTxRateBuffer(VF_INFO_TX_RATE_LEN) { impl + ?Sized> Parseable> for VfInfoTxRate { - fn parse(buf: &VfInfoTxRateBuffer<&T>) -> Result { + type Error = DecodeError; + + fn parse(buf: &VfInfoTxRateBuffer<&T>) -> Result { Ok(Self { vf_id: buf.vf_id(), rate: buf.rate(), diff --git a/src/link/sriov/vf_list.rs b/src/link/sriov/vf_list.rs index 4d17f851..76607c7e 100644 --- a/src/link/sriov/vf_list.rs +++ b/src/link/sriov/vf_list.rs @@ -1,6 +1,5 @@ // SPDX-License-Identifier: MIT -use anyhow::Context; use netlink_packet_utils::{ nla::{DefaultNla, Nla, NlaBuffer, NlasIterator}, DecodeError, Emitable, Parseable, @@ -23,13 +22,12 @@ pub(crate) struct VecLinkVfInfo(pub(crate) Vec); impl<'a, T: AsRef<[u8]> + ?Sized> Parseable> for VecLinkVfInfo { - fn parse(buf: &NlaBuffer<&'a T>) -> Result { + type Error = DecodeError; + + fn parse(buf: &NlaBuffer<&'a T>) -> Result { let mut nlas = vec![]; for nla in NlasIterator::new(buf.into_inner()) { - let nla = &nla.context(format!( - "invalid IFLA_VFINFO_LIST value: {:?}", - buf.value() - ))?; + let nla = &nla?; if nla.kind() == IFLA_VF_INFO { nlas.push(LinkVfInfo::parse(&NlaBuffer::new_checked( nla.value(), @@ -64,14 +62,12 @@ impl Nla for LinkVfInfo { } impl<'a, T: AsRef<[u8]> + ?Sized> Parseable> for LinkVfInfo { - fn parse(buf: &NlaBuffer<&'a T>) -> Result { + type Error = DecodeError; + + fn parse(buf: &NlaBuffer<&'a T>) -> Result { let mut nlas = vec![]; for nla in NlasIterator::new(buf.into_inner()) { - let nla = &nla.context(format!( - "invalid IFLA_VF_INFO value {:?}", - buf.value() - ))?; - nlas.push(VfInfo::parse(nla)?); + nlas.push(VfInfo::parse(&nla?)?); } Ok(Self(nlas)) } @@ -169,89 +165,60 @@ impl Nla for VfInfo { } } -impl<'a, T: AsRef<[u8]> + ?Sized> Parseable> for VfInfo { - fn parse(buf: &NlaBuffer<&'a T>) -> Result { +impl + ?Sized> Parseable> for VfInfo { + type Error = DecodeError; + + fn parse(buf: &NlaBuffer<&T>) -> Result { let payload = buf.value(); Ok(match buf.kind() { - IFLA_VF_MAC => Self::Mac( - VfInfoMac::parse(&VfInfoMacBuffer::new(payload)) - .context(format!("invalid IFLA_VF_MAC {payload:?}"))?, - ), - IFLA_VF_VLAN => Self::Vlan( - VfInfoVlan::parse(&VfInfoVlanBuffer::new(payload)) - .context(format!("invalid IFLA_VF_VLAN {payload:?}"))?, - ), - IFLA_VF_BROADCAST => Self::Broadcast( - VfInfoBroadcast::parse(&VfInfoBroadcastBuffer::new(payload)) - .context(format!( - "invalid IFLA_VF_BROADCAST {payload:?}" - ))?, - ), - IFLA_VF_RATE => Self::Rate( - VfInfoRate::parse(&VfInfoRateBuffer::new(payload)) - .context(format!("invalid IFLA_VF_RATE {payload:?}"))?, - ), - IFLA_VF_TX_RATE => Self::TxRate( - VfInfoTxRate::parse(&VfInfoTxRateBuffer::new(payload)) - .context(format!("invalid IFLA_VF_TX_RATE {payload:?}"))?, - ), - IFLA_VF_SPOOFCHK => Self::SpoofCheck( - VfInfoSpoofCheck::parse(&VfInfoSpoofCheckBuffer::new(payload)) - .context(format!("invalid IFLA_VF_SPOOFCHK {payload:?}"))?, - ), - IFLA_VF_LINK_STATE => Self::LinkState( - VfInfoLinkState::parse(&VfInfoLinkStateBuffer::new(payload)) - .context(format!( - "invalid IFLA_VF_LINK_STATE {payload:?}" - ))?, - ), - IFLA_VF_RSS_QUERY_EN => Self::RssQueryEn( - VfInfoRssQueryEn::parse(&VfInfoRssQueryEnBuffer::new(payload)) - .context(format!( - "invalid IFLA_VF_RSS_QUERY_EN {payload:?}" - ))?, - ), - IFLA_VF_TRUST => Self::Trust( - VfInfoTrust::parse(&VfInfoTrustBuffer::new(payload)) - .context(format!("invalid IFLA_VF_TRUST {payload:?}"))?, - ), - IFLA_VF_IB_NODE_GUID => Self::IbNodeGuid( - VfInfoGuid::parse(&VfInfoGuidBuffer::new(payload)).context( - format!("invalid IFLA_VF_IB_NODE_GUID {payload:?}"), - )?, - ), - IFLA_VF_IB_PORT_GUID => Self::IbPortGuid( - VfInfoGuid::parse(&VfInfoGuidBuffer::new(payload)).context( - format!("invalid IFLA_VF_IB_PORT_GUID {payload:?}"), - )?, - ), + IFLA_VF_MAC => { + Self::Mac(VfInfoMac::parse(&VfInfoMacBuffer::new(payload))?) + } + IFLA_VF_VLAN => { + Self::Vlan(VfInfoVlan::parse(&VfInfoVlanBuffer::new(payload))?) + } + IFLA_VF_BROADCAST => Self::Broadcast(VfInfoBroadcast::parse( + &VfInfoBroadcastBuffer::new(payload), + )?), + IFLA_VF_RATE => { + Self::Rate(VfInfoRate::parse(&VfInfoRateBuffer::new(payload))?) + } + IFLA_VF_TX_RATE => Self::TxRate(VfInfoTxRate::parse( + &VfInfoTxRateBuffer::new(payload), + )?), + IFLA_VF_SPOOFCHK => Self::SpoofCheck(VfInfoSpoofCheck::parse( + &VfInfoSpoofCheckBuffer::new(payload), + )?), + IFLA_VF_LINK_STATE => Self::LinkState(VfInfoLinkState::parse( + &VfInfoLinkStateBuffer::new(payload), + )?), + IFLA_VF_RSS_QUERY_EN => Self::RssQueryEn(VfInfoRssQueryEn::parse( + &VfInfoRssQueryEnBuffer::new(payload), + )?), + IFLA_VF_TRUST => Self::Trust(VfInfoTrust::parse( + &VfInfoTrustBuffer::new(payload), + )?), + IFLA_VF_IB_NODE_GUID => Self::IbNodeGuid(VfInfoGuid::parse( + &VfInfoGuidBuffer::new(payload), + )?), + IFLA_VF_IB_PORT_GUID => Self::IbPortGuid(VfInfoGuid::parse( + &VfInfoGuidBuffer::new(payload), + )?), IFLA_VF_VLAN_LIST => { let mut nlas: Vec = Vec::new(); for nla in NlasIterator::new(payload) { - let nla = &nla.context(format!( - "invalid IFLA_VF_VLAN_LIST value: {:?}", - buf.value() - ))?; - - nlas.push(VfVlan::parse(nla)?); + nlas.push(VfVlan::parse(&nla?)?); } Self::VlanList(nlas) } IFLA_VF_STATS => { let mut nlas: Vec = Vec::new(); for nla in NlasIterator::new(payload) { - let nla = &nla.context(format!( - "invalid IFLA_VF_STATS value: {:?}", - buf.value() - ))?; - - nlas.push(VfStats::parse(nla)?); + nlas.push(VfStats::parse(&nla?)?); } Self::Stats(nlas) } - kind => Self::Other(DefaultNla::parse(buf).context(format!( - "failed to parse {kind} as DefaultNla: {payload:?}" - ))?), + _ => Self::Other(DefaultNla::parse(buf)?), }) } } diff --git a/src/link/sriov/vf_port.rs b/src/link/sriov/vf_port.rs index a63d1935..c4edf593 100644 --- a/src/link/sriov/vf_port.rs +++ b/src/link/sriov/vf_port.rs @@ -1,6 +1,5 @@ // SPDX-License-Identifier: MIT -use anyhow::Context; use netlink_packet_utils::{ nla::{DefaultNla, Nla, NlaBuffer, NlasIterator}, DecodeError, Emitable, Parseable, @@ -12,13 +11,12 @@ pub(crate) struct VecLinkVfPort(pub(crate) Vec); impl<'a, T: AsRef<[u8]> + ?Sized> Parseable> for VecLinkVfPort { - fn parse(buf: &NlaBuffer<&'a T>) -> Result { + type Error = DecodeError; + + fn parse(buf: &NlaBuffer<&'a T>) -> Result { let mut nlas = vec![]; for nla in NlasIterator::new(buf.into_inner()) { - let nla = &nla.context(format!( - "invalid IFLA_VF_PORTS value: {:?}", - buf.value() - ))?; + let nla = &nla?; if nla.kind() == IFLA_VF_PORT { nlas.push(LinkVfPort::parse(&NlaBuffer::new_checked( nla.value(), @@ -54,15 +52,13 @@ impl Nla for LinkVfPort { } } -impl<'a, T: AsRef<[u8]> + ?Sized> Parseable> for LinkVfPort { - fn parse(buf: &NlaBuffer<&'a T>) -> Result { +impl + ?Sized> Parseable> for LinkVfPort { + type Error = DecodeError; + + fn parse(buf: &NlaBuffer<&T>) -> Result { let mut nlas = vec![]; for nla in NlasIterator::new(buf.into_inner()) { - let nla = &nla.context(format!( - "invalid IFLA_VF_PORT value {:?}", - buf.value() - ))?; - nlas.push(VfPort::parse(nla)?); + nlas.push(VfPort::parse(&nla?)?); } Ok(Self(nlas)) } @@ -112,14 +108,13 @@ impl Nla for VfPort { } } -impl<'a, T: AsRef<[u8]> + ?Sized> Parseable> for VfPort { - fn parse(buf: &NlaBuffer<&'a T>) -> Result { - let payload = buf.value(); +impl + ?Sized> Parseable> for VfPort { + type Error = DecodeError; + + fn parse(buf: &NlaBuffer<&T>) -> Result { #[allow(clippy::match_single_binding)] Ok(match buf.kind() { - kind => Self::Other(DefaultNla::parse(buf).context(format!( - "failed to parse {kind} as DefaultNla: {payload:?}" - ))?), + _ => Self::Other(DefaultNla::parse(buf)?), }) } } diff --git a/src/link/sriov/vf_vlan.rs b/src/link/sriov/vf_vlan.rs index 5449c0ed..4eb32431 100644 --- a/src/link/sriov/vf_vlan.rs +++ b/src/link/sriov/vf_vlan.rs @@ -1,6 +1,5 @@ // SPDX-License-Identifier: MIT -use anyhow::Context; use netlink_packet_utils::{ nla::{DefaultNla, Nla, NlaBuffer}, DecodeError, Emitable, Parseable, @@ -40,18 +39,16 @@ impl Nla for VfVlan { } } -impl<'a, T: AsRef<[u8]> + ?Sized> Parseable> for VfVlan { - fn parse(buf: &NlaBuffer<&'a T>) -> Result { +impl + ?Sized> Parseable> for VfVlan { + type Error = DecodeError; + + fn parse(buf: &NlaBuffer<&T>) -> Result { let payload = buf.value(); Ok(match buf.kind() { - IFLA_VF_VLAN_INFO => Self::Info( - VfVlanInfo::parse(&VfVlanInfoBuffer::new(payload)).context( - format!("invalid IFLA_VF_VLAN_INFO {payload:?}"), - )?, - ), - kind => Self::Other(DefaultNla::parse(buf).context(format!( - "failed to parse {kind} as DefaultNla: {payload:?}" - ))?), + IFLA_VF_VLAN_INFO => { + Self::Info(VfVlanInfo::parse(&VfVlanInfoBuffer::new(payload))?) + } + _ => Self::Other(DefaultNla::parse(buf)?), }) } } @@ -91,7 +88,9 @@ buffer!(VfVlanInfoBuffer(VF_VLAN_INFO_LEN) { }); impl + ?Sized> Parseable> for VfVlanInfo { - fn parse(buf: &VfVlanInfoBuffer<&T>) -> Result { + type Error = DecodeError; + + fn parse(buf: &VfVlanInfoBuffer<&T>) -> Result { Ok(Self { vf_id: buf.vf_id(), vlan_id: buf.vlan_id(), diff --git a/src/link/sriov/vlan.rs b/src/link/sriov/vlan.rs index 316d7426..53d22b58 100644 --- a/src/link/sriov/vlan.rs +++ b/src/link/sriov/vlan.rs @@ -29,7 +29,9 @@ buffer!(VfInfoVlanBuffer(VF_INFO_VLAN_LEN) { }); impl + ?Sized> Parseable> for VfInfoVlan { - fn parse(buf: &VfInfoVlanBuffer<&T>) -> Result { + type Error = DecodeError; + + fn parse(buf: &VfInfoVlanBuffer<&T>) -> Result { Ok(Self { vf_id: buf.vf_id(), vlan_id: buf.vlan_id(), diff --git a/src/link/stats.rs b/src/link/stats.rs index 0570d639..6b7b65ac 100644 --- a/src/link/stats.rs +++ b/src/link/stats.rs @@ -86,7 +86,9 @@ buffer!(StatsBuffer(LINK_STATS_LEN) { }); impl> Parseable> for Stats { - fn parse(buf: &StatsBuffer) -> Result { + type Error = DecodeError; + + fn parse(buf: &StatsBuffer) -> Result { Ok(Self { rx_packets: buf.rx_packets(), tx_packets: buf.tx_packets(), diff --git a/src/link/stats64.rs b/src/link/stats64.rs index 355556ad..31b92e11 100644 --- a/src/link/stats64.rs +++ b/src/link/stats64.rs @@ -89,7 +89,9 @@ pub struct Stats64 { } impl> Parseable> for Stats64 { - fn parse(buf: &Stats64Buffer) -> Result { + type Error = DecodeError; + + fn parse(buf: &Stats64Buffer) -> Result { Ok(Self { rx_packets: buf.rx_packets(), tx_packets: buf.tx_packets(), diff --git a/src/link/wireless.rs b/src/link/wireless.rs index 65fa628c..9abb7e85 100644 --- a/src/link/wireless.rs +++ b/src/link/wireless.rs @@ -8,7 +8,9 @@ use netlink_packet_utils::{DecodeError, Emitable, Parseable}; pub struct LinkWirelessEvent(Vec); impl + ?Sized> Parseable for LinkWirelessEvent { - fn parse(buf: &T) -> Result { + type Error = DecodeError; + + fn parse(buf: &T) -> Result { Ok(LinkWirelessEvent(buf.as_ref().to_vec())) } } diff --git a/src/link/xdp.rs b/src/link/xdp.rs index 99182a2d..d06f0b0c 100644 --- a/src/link/xdp.rs +++ b/src/link/xdp.rs @@ -2,7 +2,6 @@ use std::{mem::size_of, os::fd::RawFd}; -use anyhow::Context; use byteorder::{ByteOrder, NativeEndian}; use netlink_packet_utils::{ nla::{DefaultNla, Nla, NlaBuffer, NlasIterator}, @@ -91,40 +90,24 @@ impl Nla for LinkXdp { } } -impl<'a, T: AsRef<[u8]> + ?Sized> Parseable> for LinkXdp { - fn parse(nla: &NlaBuffer<&'a T>) -> Result { +impl + ?Sized> Parseable> for LinkXdp { + type Error = DecodeError; + + fn parse(nla: &NlaBuffer<&T>) -> Result { let payload = nla.value(); Ok(match nla.kind() as u32 { - IFLA_XDP_FD => Self::Fd( - parse_i32(payload).context("invalid IFLA_XDP_FD value")?, - ), + IFLA_XDP_FD => Self::Fd(parse_i32(payload)?), IFLA_XDP_ATTACHED => { - let err = "invalid IFLA_XDP_ATTACHED value"; - let value = parse_u8(payload).context(err)?; - Self::Attached(XdpAttached::try_from(value).context(err)?) + let value = parse_u8(payload)?; + Self::Attached(XdpAttached::try_from(value)?) } - IFLA_XDP_FLAGS => Self::Flags( - parse_u32(payload).context("invalid IFLA_XDP_FLAGS value")?, - ), - IFLA_XDP_PROG_ID => Self::ProgId( - parse_u32(payload).context("invalid IFLA_XDP_PROG_ID value")?, - ), - IFLA_XDP_DRV_PROG_ID => Self::DrvProgId( - parse_u32(payload).context("invalid IFLA_XDP_PROG_ID value")?, - ), - IFLA_XDP_SKB_PROG_ID => Self::SkbProgId( - parse_u32(payload).context("invalid IFLA_XDP_PROG_ID value")?, - ), - IFLA_XDP_HW_PROG_ID => Self::HwProgId( - parse_u32(payload).context("invalid IFLA_XDP_PROG_ID value")?, - ), - IFLA_XDP_EXPECTED_FD => Self::ExpectedFd( - parse_u32(payload).context("invalid IFLA_XDP_PROG_ID value")?, - ), - _ => Self::Other( - DefaultNla::parse(nla) - .context(format!("unknown NLA type {}", nla.kind()))?, - ), + IFLA_XDP_FLAGS => Self::Flags(parse_u32(payload)?), + IFLA_XDP_PROG_ID => Self::ProgId(parse_u32(payload)?), + IFLA_XDP_DRV_PROG_ID => Self::DrvProgId(parse_u32(payload)?), + IFLA_XDP_SKB_PROG_ID => Self::SkbProgId(parse_u32(payload)?), + IFLA_XDP_HW_PROG_ID => Self::HwProgId(parse_u32(payload)?), + IFLA_XDP_EXPECTED_FD => Self::ExpectedFd(parse_u32(payload)?), + _ => Self::Other(DefaultNla::parse(nla)?), }) } } @@ -137,8 +120,10 @@ pub(crate) struct VecLinkXdp(pub(crate) Vec); // nla->data[] // <- You are here == Vec // nla->data[0].type <- nla.kind() // nla->data[0].len -impl<'a, T: AsRef<[u8]> + ?Sized> Parseable> for VecLinkXdp { - fn parse(buf: &NlaBuffer<&'a T>) -> Result { +impl + ?Sized> Parseable> for VecLinkXdp { + type Error = DecodeError; + + fn parse(buf: &NlaBuffer<&T>) -> Result { let mut res = Vec::new(); let nlas = NlasIterator::new(buf.into_inner()); for nla in nlas { diff --git a/src/message.rs b/src/message.rs index d1b20809..ea906b80 100644 --- a/src/message.rs +++ b/src/message.rs @@ -1,9 +1,9 @@ // SPDX-License-Identifier: MIT -use anyhow::Context; use netlink_packet_core::{ NetlinkDeserializable, NetlinkHeader, NetlinkPayload, NetlinkSerializable, }; +use netlink_packet_utils::nla::NlaError; use netlink_packet_utils::{ DecodeError, Emitable, Parseable, ParseableParametrized, }; @@ -81,20 +81,21 @@ const RTM_DELLINKPROP: u16 = 109; buffer!(RouteNetlinkMessageBuffer); -impl<'a, T: AsRef<[u8]> + ?Sized> - ParseableParametrized, u16> +impl + ?Sized> + ParseableParametrized, u16> for RouteNetlinkMessage { + type Error = DecodeError; + fn parse_with_param( - buf: &RouteNetlinkMessageBuffer<&'a T>, + buf: &RouteNetlinkMessageBuffer<&T>, message_type: u16, - ) -> Result { + ) -> Result { let message = match message_type { // Link messages RTM_NEWLINK | RTM_GETLINK | RTM_DELLINK | RTM_SETLINK => { let msg = match LinkMessageBuffer::new_checked(&buf.inner()) { - Ok(buf) => LinkMessage::parse(&buf) - .context("invalid link message")?, + Ok(buf) => LinkMessage::parse(&buf)?, // HACK: iproute2 sends invalid RTM_GETLINK message, where // the header is limited to the // interface family (1 byte) and 3 bytes of padding. @@ -122,8 +123,7 @@ impl<'a, T: AsRef<[u8]> + ?Sized> RTM_NEWADDR | RTM_GETADDR | RTM_DELADDR => { let msg = match AddressMessageBuffer::new_checked(&buf.inner()) { - Ok(buf) => AddressMessage::parse(&buf) - .context("invalid link message")?, + Ok(buf) => AddressMessage::parse(&buf)?, // HACK: iproute2 sends invalid RTM_GETADDR message, where // the header is limited to the // interface family (1 byte) and 3 bytes of padding. @@ -151,12 +151,9 @@ impl<'a, T: AsRef<[u8]> + ?Sized> // Neighbour messages RTM_NEWNEIGH | RTM_GETNEIGH | RTM_DELNEIGH => { - let err = "invalid neighbour message"; let msg = NeighbourMessage::parse( - &NeighbourMessageBuffer::new_checked(&buf.inner()) - .context(err)?, - ) - .context(err)?; + &NeighbourMessageBuffer::new_checked(&buf.inner())?, + )?; match message_type { RTM_GETNEIGH => RouteNetlinkMessage::GetNeighbour(msg), RTM_NEWNEIGH => RouteNetlinkMessage::NewNeighbour(msg), @@ -167,12 +164,9 @@ impl<'a, T: AsRef<[u8]> + ?Sized> // Neighbour table messages RTM_NEWNEIGHTBL | RTM_GETNEIGHTBL | RTM_SETNEIGHTBL => { - let err = "invalid neighbour table message"; let msg = NeighbourTableMessage::parse( - &NeighbourTableMessageBuffer::new_checked(&buf.inner()) - .context(err)?, - ) - .context(err)?; + &NeighbourTableMessageBuffer::new_checked(&buf.inner())?, + )?; match message_type { RTM_GETNEIGHTBL => { RouteNetlinkMessage::GetNeighbourTable(msg) @@ -190,8 +184,7 @@ impl<'a, T: AsRef<[u8]> + ?Sized> // Route messages RTM_NEWROUTE | RTM_GETROUTE | RTM_DELROUTE => { let msg = match RouteMessageBuffer::new_checked(&buf.inner()) { - Ok(buf) => RouteMessage::parse(&buf) - .context("invalid route message")?, + Ok(buf) => RouteMessage::parse(&buf)?, // HACK: iproute2 sends invalid RTM_GETROUTE message, where // the header is limited to the // interface family (1 byte) and 3 bytes of padding. @@ -228,23 +221,15 @@ impl<'a, T: AsRef<[u8]> + ?Sized> // Prefix messages RTM_NEWPREFIX => { - let err = "invalid prefix message"; - RouteNetlinkMessage::NewPrefix( - PrefixMessage::parse( - &PrefixMessageBuffer::new_checked(&buf.inner()) - .context(err)?, - ) - .context(err)?, - ) + RouteNetlinkMessage::NewPrefix(PrefixMessage::parse( + &PrefixMessageBuffer::new_checked(&buf.inner())?, + )?) } RTM_NEWRULE | RTM_GETRULE | RTM_DELRULE => { - let err = "invalid fib rule message"; - let msg = RuleMessage::parse( - &RuleMessageBuffer::new_checked(&buf.inner()) - .context(err)?, - ) - .context(err)?; + let msg = RuleMessage::parse(&RuleMessageBuffer::new_checked( + &buf.inner(), + )?)?; match message_type { RTM_NEWRULE => RouteNetlinkMessage::NewRule(msg), RTM_DELRULE => RouteNetlinkMessage::DelRule(msg), @@ -257,11 +242,9 @@ impl<'a, T: AsRef<[u8]> + ?Sized> | RTM_DELTCLASS | RTM_GETTCLASS | RTM_NEWTFILTER | RTM_DELTFILTER | RTM_GETTFILTER | RTM_NEWCHAIN | RTM_DELCHAIN | RTM_GETCHAIN => { - let err = "invalid tc message"; - let msg = TcMessage::parse( - &TcMessageBuffer::new_checked(&buf.inner()).context(err)?, - ) - .context(err)?; + let msg = TcMessage::parse(&TcMessageBuffer::new_checked( + &buf.inner(), + )?)?; match message_type { RTM_NEWQDISC => { RouteNetlinkMessage::NewQueueDiscipline(msg) @@ -292,12 +275,9 @@ impl<'a, T: AsRef<[u8]> + ?Sized> } RTM_NEWACTION | RTM_DELACTION | RTM_GETACTION => { - let err = "invalid tc action message"; let msg = TcActionMessage::parse( - &TcActionMessageBuffer::new_checked(&buf.inner()) - .context(err)?, - ) - .context(err)?; + &TcActionMessageBuffer::new_checked(&buf.inner())?, + )?; match message_type { RTM_NEWACTION => RouteNetlinkMessage::NewTrafficAction(msg), RTM_DELACTION => RouteNetlinkMessage::DelTrafficAction(msg), @@ -308,12 +288,9 @@ impl<'a, T: AsRef<[u8]> + ?Sized> // ND ID Messages RTM_NEWNSID | RTM_GETNSID | RTM_DELNSID => { - let err = "invalid nsid message"; - let msg = NsidMessage::parse( - &NsidMessageBuffer::new_checked(&buf.inner()) - .context(err)?, - ) - .context(err)?; + let msg = NsidMessage::parse(&NsidMessageBuffer::new_checked( + &buf.inner(), + )?)?; match message_type { RTM_NEWNSID => RouteNetlinkMessage::NewNsId(msg), RTM_DELNSID => RouteNetlinkMessage::DelNsId(msg), @@ -721,16 +698,14 @@ impl NetlinkSerializable for RouteNetlinkMessage { } impl NetlinkDeserializable for RouteNetlinkMessage { - type Error = DecodeError; + type Error = NlaError; fn deserialize( header: &NetlinkHeader, payload: &[u8], ) -> Result { let buf = RouteNetlinkMessageBuffer::new(payload); - match RouteNetlinkMessage::parse_with_param(&buf, header.message_type) { - Err(e) => Err(e), - Ok(message) => Ok(message), - } + RouteNetlinkMessage::parse_with_param(&buf, header.message_type) + .map_err(|_| NlaError::InvalidLength { nla_len: 0 }) } } diff --git a/src/neighbour/attribute.rs b/src/neighbour/attribute.rs index ec871eda..db0367c3 100644 --- a/src/neighbour/attribute.rs +++ b/src/neighbour/attribute.rs @@ -1,6 +1,5 @@ // SPDX-License-Identifier: MIT -use anyhow::Context; use byteorder::{BigEndian, ByteOrder, NativeEndian}; use netlink_packet_utils::{ nla::{DefaultNla, Nla, NlaBuffer}, @@ -102,61 +101,35 @@ impl Nla for NeighbourAttribute { } } -impl<'a, T: AsRef<[u8]> + ?Sized> - ParseableParametrized, AddressFamily> - for NeighbourAttribute +impl + ?Sized> + ParseableParametrized, AddressFamily> for NeighbourAttribute { + type Error = DecodeError; + fn parse_with_param( - buf: &NlaBuffer<&'a T>, + buf: &NlaBuffer<&T>, address_family: AddressFamily, - ) -> Result { + ) -> Result { let payload = buf.value(); Ok(match buf.kind() { - NDA_DST => Self::Destination( - NeighbourAddress::parse_with_param(address_family, payload) - .context(format!("invalid NDA_DST value {:?}", payload))?, - ), + NDA_DST => Self::Destination(NeighbourAddress::parse_with_param( + address_family, + payload, + )?), NDA_LLADDR => Self::LinkLocalAddress(payload.to_vec()), - NDA_CACHEINFO => Self::CacheInfo( - NeighbourCacheInfo::parse( - &NeighbourCacheInfoBuffer::new_checked(payload).context( - format!("invalid NDA_CACHEINFO value {:?}", payload), - )?, - ) - .context(format!( - "invalid NDA_CACHEINFO value {:?}", - payload - ))?, - ), - NDA_PROBES => { - Self::Probes(parse_u32(payload).context(format!( - "invalid NDA_PROBES value {:?}", - payload - ))?) - } + NDA_CACHEINFO => Self::CacheInfo(NeighbourCacheInfo::parse( + &NeighbourCacheInfoBuffer::new_checked(payload)?, + )?), + NDA_PROBES => Self::Probes(parse_u32(payload)?), NDA_VLAN => Self::Vlan(parse_u16(payload)?), - NDA_PORT => Self::Port( - parse_u16_be(payload) - .context(format!("invalid NDA_PORT value {payload:?}"))?, - ), + NDA_PORT => Self::Port(parse_u16_be(payload)?), NDA_VNI => Self::Vni(parse_u32(payload)?), NDA_IFINDEX => Self::IfIndex(parse_u32(payload)?), - NDA_CONTROLLER => Self::Controller(parse_u32(payload).context( - format!("invalid NDA_CONTROLLER value {payload:?}"), - )?), - NDA_LINK_NETNSID => Self::LinkNetNsId(parse_u32(payload).context( - format!("invalid NDA_LINK_NETNSID value {payload:?}"), - )?), + NDA_CONTROLLER => Self::Controller(parse_u32(payload)?), + NDA_LINK_NETNSID => Self::LinkNetNsId(parse_u32(payload)?), NDA_SRC_VNI => Self::SourceVni(parse_u32(payload)?), - NDA_PROTOCOL => { - Self::Protocol(RouteProtocol::parse(payload).context( - format!("invalid NDA_PROTOCOL value {:?}", payload), - )?) - } - _ => Self::Other( - DefaultNla::parse(buf) - .context("invalid link NLA value (unknown type)")?, - ), + NDA_PROTOCOL => Self::Protocol(RouteProtocol::parse(payload)?), + _ => Self::Other(DefaultNla::parse(buf)?), }) } } diff --git a/src/neighbour/cache_info.rs b/src/neighbour/cache_info.rs index 86c61865..0a8bc513 100644 --- a/src/neighbour/cache_info.rs +++ b/src/neighbour/cache_info.rs @@ -26,7 +26,9 @@ buffer!(NeighbourCacheInfoBuffer(NEIGHBOUR_CACHE_INFO_LEN) { impl> Parseable> for NeighbourCacheInfo { - fn parse(buf: &NeighbourCacheInfoBuffer) -> Result { + type Error = DecodeError; + + fn parse(buf: &NeighbourCacheInfoBuffer) -> Result { Ok(Self { confirmed: buf.confirmed(), used: buf.used(), diff --git a/src/neighbour/header.rs b/src/neighbour/header.rs index f12fab69..07081944 100644 --- a/src/neighbour/header.rs +++ b/src/neighbour/header.rs @@ -1,7 +1,7 @@ // SPDX-License-Identifier: MIT use netlink_packet_utils::{ - nla::{NlaBuffer, NlasIterator}, + nla::{NlaBuffer, NlaError, NlasIterator}, traits::{Emitable, Parseable}, DecodeError, }; @@ -23,7 +23,7 @@ buffer!(NeighbourMessageBuffer(NEIGHBOUR_HEADER_LEN) { impl<'a, T: AsRef<[u8]> + ?Sized> NeighbourMessageBuffer<&'a T> { pub fn attributes( &self, - ) -> impl Iterator, DecodeError>> { + ) -> impl Iterator, NlaError>> { NlasIterator::new(self.payload()) } } @@ -58,7 +58,9 @@ pub struct NeighbourHeader { } impl> Parseable> for NeighbourHeader { - fn parse(buf: &NeighbourMessageBuffer) -> Result { + type Error = DecodeError; + + fn parse(buf: &NeighbourMessageBuffer) -> Result { Ok(Self { family: buf.family().into(), ifindex: buf.ifindex(), diff --git a/src/neighbour/message.rs b/src/neighbour/message.rs index f5908584..58f5c555 100644 --- a/src/neighbour/message.rs +++ b/src/neighbour/message.rs @@ -1,6 +1,5 @@ // SPDX-License-Identifier: MIT -use anyhow::Context; use netlink_packet_utils::{ traits::{Emitable, Parseable, ParseableParametrized}, DecodeError, @@ -31,32 +30,34 @@ impl Emitable for NeighbourMessage { } } -impl<'a, T: AsRef<[u8]> + 'a> Parseable> +impl> Parseable> for NeighbourMessage { - fn parse(buf: &NeighbourMessageBuffer<&'a T>) -> Result { - let header = NeighbourHeader::parse(buf) - .context("failed to parse neighbour message header")?; + type Error = DecodeError; + + fn parse(buf: &NeighbourMessageBuffer<&T>) -> Result { + let header = NeighbourHeader::parse(buf)?; let address_family = header.family; Ok(NeighbourMessage { header, attributes: Vec::::parse_with_param( buf, address_family, - ) - .context("failed to parse neighbour message NLAs")?, + )?, }) } } -impl<'a, T: AsRef<[u8]> + 'a> - ParseableParametrized, AddressFamily> +impl> + ParseableParametrized, AddressFamily> for Vec { + type Error = DecodeError; + fn parse_with_param( - buf: &NeighbourMessageBuffer<&'a T>, + buf: &NeighbourMessageBuffer<&T>, address_family: AddressFamily, - ) -> Result { + ) -> Result { let mut attributes = vec![]; for nla_buf in buf.attributes() { attributes.push(NeighbourAttribute::parse_with_param( diff --git a/src/neighbour_table/attribute.rs b/src/neighbour_table/attribute.rs index 43524bb1..94a5eb88 100644 --- a/src/neighbour_table/attribute.rs +++ b/src/neighbour_table/attribute.rs @@ -1,6 +1,5 @@ // SPDX-License-Identifier: MIT -use anyhow::Context; use byteorder::{ByteOrder, NativeEndian}; use netlink_packet_utils::{ nla::{DefaultNla, Nla, NlaBuffer}, @@ -87,56 +86,32 @@ impl Nla for NeighbourTableAttribute { } } -impl<'a, T: AsRef<[u8]> + ?Sized> Parseable> +impl + ?Sized> Parseable> for NeighbourTableAttribute { - fn parse(buf: &NlaBuffer<&'a T>) -> Result { + type Error = DecodeError; + + fn parse(buf: &NlaBuffer<&T>) -> Result { let payload = buf.value(); Ok(match buf.kind() { - NDTA_NAME => Self::Name( - parse_string(payload).context("invalid NDTA_NAME value")?, - ), - NDTA_CONFIG => Self::Config( - NeighbourTableConfig::parse( - &NeighbourTableConfigBuffer::new_checked(payload) - .context(format!("invalid NDTA_CONFIG {payload:?}"))?, - ) - .context(format!("invalid NDTA_CONFIG {payload:?}"))?, - ), - NDTA_STATS => Self::Stats( - NeighbourTableStats::parse( - &NeighbourTableStatsBuffer::new_checked(payload) - .context(format!("invalid NDTA_STATS {payload:?}"))?, - ) - .context(format!("invalid NDTA_STATS {payload:?}"))?, - ), - NDTA_PARMS => { - let err = |payload| format!("invalid NDTA_PARMS {payload:?}"); - Self::Parms( - VecNeighbourTableParameter::parse( - &NlaBuffer::new_checked(payload) - .context(err(payload))?, - ) - .context(err(payload))? - .0, - ) - } - NDTA_GC_INTERVAL => Self::GcInterval( - parse_u64(payload).context("invalid NDTA_GC_INTERVAL value")?, - ), - NDTA_THRESH1 => Self::Threshold1( - parse_u32(payload).context("invalid NDTA_THRESH1 value")?, - ), - NDTA_THRESH2 => Self::Threshold2( - parse_u32(payload).context("invalid NDTA_THRESH2 value")?, - ), - NDTA_THRESH3 => Self::Threshold3( - parse_u32(payload).context("invalid NDTA_THRESH3 value")?, - ), - kind => Self::Other( - DefaultNla::parse(buf) - .context(format!("unknown NLA type {kind}"))?, + NDTA_NAME => Self::Name(parse_string(payload)?), + NDTA_CONFIG => Self::Config(NeighbourTableConfig::parse( + &NeighbourTableConfigBuffer::new_checked(payload)?, + )?), + NDTA_STATS => Self::Stats(NeighbourTableStats::parse( + &NeighbourTableStatsBuffer::new_checked(payload)?, + )?), + NDTA_PARMS => Self::Parms( + VecNeighbourTableParameter::parse(&NlaBuffer::new_checked( + payload, + )?)? + .0, ), + NDTA_GC_INTERVAL => Self::GcInterval(parse_u64(payload)?), + NDTA_THRESH1 => Self::Threshold1(parse_u32(payload)?), + NDTA_THRESH2 => Self::Threshold2(parse_u32(payload)?), + NDTA_THRESH3 => Self::Threshold3(parse_u32(payload)?), + _ => Self::Other(DefaultNla::parse(buf)?), }) } } diff --git a/src/neighbour_table/config.rs b/src/neighbour_table/config.rs index 6e625333..6e46c76d 100644 --- a/src/neighbour_table/config.rs +++ b/src/neighbour_table/config.rs @@ -36,7 +36,9 @@ buffer!(NeighbourTableConfigBuffer(CONFIG_LEN) { impl> Parseable> for NeighbourTableConfig { - fn parse(buf: &NeighbourTableConfigBuffer) -> Result { + type Error = DecodeError; + + fn parse(buf: &NeighbourTableConfigBuffer) -> Result { Ok(Self { key_len: buf.key_len(), entry_size: buf.entry_size(), diff --git a/src/neighbour_table/header.rs b/src/neighbour_table/header.rs index 1f41d838..11bc1a4e 100644 --- a/src/neighbour_table/header.rs +++ b/src/neighbour_table/header.rs @@ -1,7 +1,7 @@ // SPDX-License-Identifier: MIT use netlink_packet_utils::{ - nla::{NlaBuffer, NlasIterator}, + nla::{NlaBuffer, NlaError, NlasIterator}, traits::{Emitable, Parseable}, DecodeError, }; @@ -18,7 +18,7 @@ buffer!(NeighbourTableMessageBuffer(NEIGHBOUR_TABLE_HEADER_LEN) { impl<'a, T: AsRef<[u8]> + ?Sized> NeighbourTableMessageBuffer<&'a T> { pub fn attributes( &self, - ) -> impl Iterator, DecodeError>> { + ) -> impl Iterator, NlaError>> { NlasIterator::new(self.payload()) } } @@ -32,9 +32,11 @@ pub struct NeighbourTableHeader { impl> Parseable> for NeighbourTableHeader { + type Error = DecodeError; + fn parse( buf: &NeighbourTableMessageBuffer, - ) -> Result { + ) -> Result { Ok(Self { family: buf.family().into(), }) diff --git a/src/neighbour_table/message.rs b/src/neighbour_table/message.rs index 9dbdb11d..dfc656c7 100644 --- a/src/neighbour_table/message.rs +++ b/src/neighbour_table/message.rs @@ -1,6 +1,5 @@ // SPDX-License-Identifier: MIT -use anyhow::Context; use netlink_packet_utils::{ traits::{Emitable, Parseable}, DecodeError, @@ -30,27 +29,29 @@ impl Emitable for NeighbourTableMessage { } } -impl<'a, T: AsRef<[u8]> + 'a> Parseable> +impl> Parseable> for NeighbourTableMessage { + type Error = DecodeError; + fn parse( - buf: &NeighbourTableMessageBuffer<&'a T>, - ) -> Result { + buf: &NeighbourTableMessageBuffer<&T>, + ) -> Result { Ok(NeighbourTableMessage { - header: NeighbourTableHeader::parse(buf) - .context("failed to parse neighbour table message header")?, - attributes: Vec::::parse(buf) - .context("failed to parse neighbour table message NLAs")?, + header: NeighbourTableHeader::parse(buf)?, + attributes: Vec::::parse(buf)?, }) } } -impl<'a, T: AsRef<[u8]> + 'a> Parseable> +impl> Parseable> for Vec { + type Error = DecodeError; + fn parse( - buf: &NeighbourTableMessageBuffer<&'a T>, - ) -> Result { + buf: &NeighbourTableMessageBuffer<&T>, + ) -> Result { let mut attributes = vec![]; for nla_buf in buf.attributes() { attributes.push(NeighbourTableAttribute::parse(&nla_buf?)?); diff --git a/src/neighbour_table/param.rs b/src/neighbour_table/param.rs index 91cd791c..3312ab5d 100644 --- a/src/neighbour_table/param.rs +++ b/src/neighbour_table/param.rs @@ -1,6 +1,5 @@ // SPDX-License-Identifier: MIT -use anyhow::Context; use byteorder::{ByteOrder, NativeEndian}; use netlink_packet_utils::{ nla::{DefaultNla, Nla, NlaBuffer, NlasIterator}, @@ -132,95 +131,35 @@ impl Nla for NeighbourTableParameter { } } -impl<'a, T: AsRef<[u8]> + ?Sized> Parseable> +impl + ?Sized> Parseable> for NeighbourTableParameter { - fn parse(buf: &NlaBuffer<&'a T>) -> Result { + type Error = DecodeError; + + fn parse(buf: &NlaBuffer<&T>) -> Result { let payload = buf.value(); Ok(match buf.kind() { - NDTPA_IFINDEX => { - Self::Ifindex(parse_u32(payload).context(format!( - "invalid NDTPA_IFINDEX value {payload:?}" - ))?) - } - NDTPA_REFCNT => { - Self::ReferenceCount(parse_u32(payload).context(format!( - "invalid NDTPA_REFCNT value {payload:?}" - ))?) - } - NDTPA_REACHABLE_TIME => { - Self::ReachableTime(parse_u64(payload).context(format!( - "invalid NDTPA_REACHABLE_TIME value {payload:?}" - ))?) - } + NDTPA_IFINDEX => Self::Ifindex(parse_u32(payload)?), + NDTPA_REFCNT => Self::ReferenceCount(parse_u32(payload)?), + NDTPA_REACHABLE_TIME => Self::ReachableTime(parse_u64(payload)?), NDTPA_BASE_REACHABLE_TIME => { - Self::BaseReachableTime(parse_u64(payload).context(format!( - "invalid NDTPA_BASE_REACHABLE_TIME value {payload:?}" - ))?) - } - NDTPA_RETRANS_TIME => { - Self::RetransTime(parse_u64(payload).context(format!( - "invalid NDTPA_RETRANS_TIME value {payload:?}" - ))?) - } - NDTPA_GC_STALETIME => { - Self::GcStaletime(parse_u64(payload).context(format!( - "invalid NDTPA_GC_STALE_TIME value {payload:?}" - ))?) + Self::BaseReachableTime(parse_u64(payload)?) } - NDTPA_DELAY_PROBE_TIME => { - Self::DelayProbeTime(parse_u64(payload).context(format!( - "invalid NDTPA_DELAY_PROBE_TIME value {payload:?}" - ))?) + NDTPA_DELAY_PROBE_TIME => Self::DelayProbeTime(parse_u64(payload)?), + NDTPA_QUEUE_LEN => Self::QueueLen(parse_u32(payload)?), + NDTPA_APP_PROBES => Self::AppProbes(parse_u32(payload)?), + NDTPA_UCAST_PROBES => Self::UcastProbes(parse_u32(payload)?), + NDTPA_MCAST_PROBES => Self::McastProbes(parse_u32(payload)?), + NDTPA_ANYCAST_DELAY => Self::AnycastDelay(parse_u64(payload)?), + NDTPA_PROXY_DELAY => Self::ProxyDelay(parse_u64(payload)?), + NDTPA_PROXY_QLEN => Self::ProxyQlen(parse_u32(payload)?), + NDTPA_LOCKTIME => Self::Locktime(parse_u64(payload)?), + NDTPA_QUEUE_LENBYTES => Self::QueueLenbytes(parse_u32(payload)?), + NDTPA_MCAST_REPROBES => Self::McastReprobes(parse_u32(payload)?), + NDTPA_INTERVAL_PROBE_TIME_MS => { + Self::IntervalProbeTimeMs(parse_u64(payload)?) } - NDTPA_QUEUE_LEN => Self::QueueLen(parse_u32(payload).context( - format!("invalid NDTPA_QUEUE_LEN value {payload:?}"), - )?), - NDTPA_APP_PROBES => Self::AppProbes(parse_u32(payload).context( - format!("invalid NDTPA_APP_PROBES value {payload:?}"), - )?), - NDTPA_UCAST_PROBES => { - Self::UcastProbes(parse_u32(payload).context(format!( - "invalid NDTPA_UCAST_PROBES value {payload:?}" - ))?) - } - NDTPA_MCAST_PROBES => { - Self::McastProbes(parse_u32(payload).context(format!( - "invalid NDTPA_MCAST_PROBES value {payload:?}" - ))?) - } - NDTPA_ANYCAST_DELAY => { - Self::AnycastDelay(parse_u64(payload).context(format!( - "invalid NDTPA_ANYCAST_DELAY value {payload:?}" - ))?) - } - NDTPA_PROXY_DELAY => Self::ProxyDelay(parse_u64(payload).context( - format!("invalid NDTPA_PROXY_DELAY value {payload:?}"), - )?), - NDTPA_PROXY_QLEN => Self::ProxyQlen(parse_u32(payload).context( - format!("invalid NDTPA_PROXY_QLEN value {payload:?}"), - )?), - NDTPA_LOCKTIME => Self::Locktime(parse_u64(payload).context( - format!("invalid NDTPA_LOCKTIME value {payload:?}"), - )?), - NDTPA_QUEUE_LENBYTES => { - Self::QueueLenbytes(parse_u32(payload).context(format!( - "invalid NDTPA_QUEUE_LENBYTES value {payload:?}" - ))?) - } - NDTPA_MCAST_REPROBES => { - Self::McastReprobes(parse_u32(payload).context(format!( - "invalid NDTPA_MCAST_PROBES value {payload:?}" - ))?) - } - NDTPA_INTERVAL_PROBE_TIME_MS => Self::IntervalProbeTimeMs( - parse_u64(payload).context(format!( - "invalid NDTPA_INTERVAL_PROBE_TIME_MS value {payload:?}" - ))?, - ), - _ => Self::Other(DefaultNla::parse(buf).context(format!( - "invalid NDTA_PARMS attribute {payload:?}" - ))?), + _ => Self::Other(DefaultNla::parse(buf)?), }) } } @@ -230,15 +169,15 @@ pub(crate) struct VecNeighbourTableParameter( pub(crate) Vec, ); -impl<'a, T: AsRef<[u8]> + ?Sized> Parseable> +impl + ?Sized> Parseable> for VecNeighbourTableParameter { - fn parse(buf: &NlaBuffer<&'a T>) -> Result { + type Error = DecodeError; + + fn parse(buf: &NlaBuffer<&T>) -> Result { let mut nlas = vec![]; - let err = "invalid NDTA_PARMS attribute"; for nla in NlasIterator::new(buf.into_inner()) { - let nla = nla.context(err)?; - nlas.push(NeighbourTableParameter::parse(&nla).context(err)?); + nlas.push(NeighbourTableParameter::parse(&nla?)?); } Ok(Self(nlas)) } diff --git a/src/neighbour_table/stats.rs b/src/neighbour_table/stats.rs index a99bf6ff..20a610fb 100644 --- a/src/neighbour_table/stats.rs +++ b/src/neighbour_table/stats.rs @@ -39,7 +39,9 @@ buffer!(NeighbourTableStatsBuffer(STATS_LEN) { impl> Parseable> for NeighbourTableStats { - fn parse(buf: &NeighbourTableStatsBuffer) -> Result { + type Error = DecodeError; + + fn parse(buf: &NeighbourTableStatsBuffer) -> Result { Ok(Self { allocs: buf.allocs(), destroys: buf.destroys(), diff --git a/src/nsid/attribute.rs b/src/nsid/attribute.rs index 487e6f3e..9d7c11b4 100644 --- a/src/nsid/attribute.rs +++ b/src/nsid/attribute.rs @@ -1,6 +1,5 @@ // SPDX-License-Identifier: MIT -use anyhow::Context; use byteorder::{ByteOrder, NativeEndian}; use netlink_packet_utils::{ @@ -62,31 +61,18 @@ impl Nla for NsidAttribute { } } -impl<'a, T: AsRef<[u8]> + ?Sized> Parseable> - for NsidAttribute -{ - fn parse(buf: &NlaBuffer<&'a T>) -> Result { +impl + ?Sized> Parseable> for NsidAttribute { + type Error = DecodeError; + + fn parse(buf: &NlaBuffer<&T>) -> Result { let payload = buf.value(); Ok(match buf.kind() { - NETNSA_NSID => { - Self::Id(parse_i32(payload).context("invalid NETNSA_NSID")?) - } - NETNSA_PID => { - Self::Pid(parse_u32(payload).context("invalid NETNSA_PID")?) - } - NETNSA_FD => { - Self::Fd(parse_u32(payload).context("invalid NETNSA_FD")?) - } - NETNSA_TARGET_NSID => Self::TargetNsid( - parse_i32(payload).context("invalid NETNSA_TARGET_NSID")?, - ), - NETNSA_CURRENT_NSID => Self::CurrentNsid( - parse_i32(payload).context("invalid NETNSA_CURRENT_NSID")?, - ), - kind => Self::Other( - DefaultNla::parse(buf) - .context(format!("unknown NLA type {kind}"))?, - ), + NETNSA_NSID => Self::Id(parse_i32(payload)?), + NETNSA_PID => Self::Pid(parse_u32(payload)?), + NETNSA_FD => Self::Fd(parse_u32(payload)?), + NETNSA_TARGET_NSID => Self::TargetNsid(parse_i32(payload)?), + NETNSA_CURRENT_NSID => Self::CurrentNsid(parse_i32(payload)?), + _ => Self::Other(DefaultNla::parse(buf)?), }) } } diff --git a/src/nsid/header.rs b/src/nsid/header.rs index 7b43b736..4a09ed58 100644 --- a/src/nsid/header.rs +++ b/src/nsid/header.rs @@ -1,7 +1,7 @@ // SPDX-License-Identifier: MIT use netlink_packet_utils::{ - nla::{NlaBuffer, NlasIterator}, + nla::{NlaBuffer, NlaError, NlasIterator}, DecodeError, Emitable, Parseable, }; @@ -17,7 +17,7 @@ buffer!(NsidMessageBuffer(NSID_HEADER_LEN) { impl<'a, T: AsRef<[u8]> + ?Sized> NsidMessageBuffer<&'a T> { pub fn attributes( &self, - ) -> impl Iterator, DecodeError>> { + ) -> impl Iterator, NlaError>> { NlasIterator::new(self.payload()) } } @@ -39,7 +39,9 @@ impl Emitable for NsidHeader { } impl> Parseable> for NsidHeader { - fn parse(buf: &NsidMessageBuffer) -> Result { + type Error = DecodeError; + + fn parse(buf: &NsidMessageBuffer) -> Result { Ok(NsidHeader { family: buf.family().into(), }) diff --git a/src/nsid/message.rs b/src/nsid/message.rs index e6269f76..e4935903 100644 --- a/src/nsid/message.rs +++ b/src/nsid/message.rs @@ -1,6 +1,5 @@ // SPDX-License-Identifier: MIT -use anyhow::Context; use netlink_packet_utils::{ traits::{Emitable, Parseable}, DecodeError, @@ -15,23 +14,21 @@ pub struct NsidMessage { pub attributes: Vec, } -impl<'a, T: AsRef<[u8]> + 'a> Parseable> - for NsidMessage -{ - fn parse(buf: &NsidMessageBuffer<&'a T>) -> Result { +impl> Parseable> for NsidMessage { + type Error = DecodeError; + + fn parse(buf: &NsidMessageBuffer<&T>) -> Result { Ok(Self { - header: NsidHeader::parse(buf) - .context("failed to parse nsid message header")?, - attributes: Vec::::parse(buf) - .context("failed to parse nsid message NLAs")?, + header: NsidHeader::parse(buf)?, + attributes: Vec::::parse(buf)?, }) } } -impl<'a, T: AsRef<[u8]> + 'a> Parseable> - for Vec -{ - fn parse(buf: &NsidMessageBuffer<&'a T>) -> Result { +impl> Parseable> for Vec { + type Error = DecodeError; + + fn parse(buf: &NsidMessageBuffer<&T>) -> Result { let mut attributes = vec![]; for nla_buf in buf.attributes() { attributes.push(NsidAttribute::parse(&nla_buf?)?); diff --git a/src/prefix/attribute.rs b/src/prefix/attribute.rs index 1c129ca4..be530ef7 100644 --- a/src/prefix/attribute.rs +++ b/src/prefix/attribute.rs @@ -2,7 +2,6 @@ use std::net::Ipv6Addr; -use anyhow::Context; use netlink_packet_utils::{ nla::{self, DefaultNla, NlaBuffer}, traits::Parseable, @@ -47,10 +46,10 @@ impl nla::Nla for PrefixAttribute { } } -impl<'a, T: AsRef<[u8]> + ?Sized> Parseable> - for PrefixAttribute -{ - fn parse(buf: &NlaBuffer<&'a T>) -> Result { +impl + ?Sized> Parseable> for PrefixAttribute { + type Error = DecodeError; + + fn parse(buf: &NlaBuffer<&T>) -> Result { let payload = buf.value(); match buf.kind() { PREFIX_ADDRESS => { @@ -60,11 +59,9 @@ impl<'a, T: AsRef<[u8]> + ?Sized> Parseable> Err(DecodeError::from(format!("Invalid PREFIX_ADDRESS, unexpected payload length: {:?}", payload))) } } - PREFIX_CACHEINFO => Ok(Self::CacheInfo( - CacheInfo::parse(&CacheInfoBuffer::new(payload)).context( - format!("Invalid PREFIX_CACHEINFO: {:?}", payload), - )?, - )), + PREFIX_CACHEINFO => Ok(Self::CacheInfo(CacheInfo::parse( + &CacheInfoBuffer::new(payload), + )?)), _ => Ok(Self::Other(DefaultNla::parse(buf)?)), } } diff --git a/src/prefix/cache_info.rs b/src/prefix/cache_info.rs index b2dc2bb9..6de2f41b 100644 --- a/src/prefix/cache_info.rs +++ b/src/prefix/cache_info.rs @@ -17,7 +17,9 @@ buffer!(CacheInfoBuffer(CACHE_INFO_LEN) { }); impl> Parseable> for CacheInfo { - fn parse(buf: &CacheInfoBuffer) -> Result { + type Error = DecodeError; + + fn parse(buf: &CacheInfoBuffer) -> Result { Ok(CacheInfo { preferred_time: buf.preferred_time(), valid_time: buf.valid_time(), diff --git a/src/prefix/header.rs b/src/prefix/header.rs index aead250f..9faa4076 100644 --- a/src/prefix/header.rs +++ b/src/prefix/header.rs @@ -1,7 +1,7 @@ // SPDX-License-Identifier: MIT use netlink_packet_utils::{ - nla::{NlaBuffer, NlasIterator}, + nla::{NlaBuffer, NlaError, NlasIterator}, DecodeError, Emitable, }; @@ -22,7 +22,7 @@ buffer!(PrefixMessageBuffer(PREFIX_HEADER_LEN) { impl<'a, T: AsRef<[u8]> + ?Sized> PrefixMessageBuffer<&'a T> { pub fn nlas( &self, - ) -> impl Iterator, DecodeError>> { + ) -> impl Iterator, NlaError>> { NlasIterator::new(self.payload()) } } diff --git a/src/prefix/message.rs b/src/prefix/message.rs index fc4e9bcf..8e54a9b1 100644 --- a/src/prefix/message.rs +++ b/src/prefix/message.rs @@ -1,7 +1,5 @@ // SPDX-License-Identifier: MIT -use anyhow::Context; - use netlink_packet_utils::{ traits::{Emitable, Parseable}, DecodeError, @@ -32,7 +30,9 @@ impl Emitable for PrefixMessage { } impl> Parseable> for PrefixHeader { - fn parse(buf: &PrefixMessageBuffer) -> Result { + type Error = DecodeError; + + fn parse(buf: &PrefixMessageBuffer) -> Result { Ok(Self { prefix_family: buf.prefix_family(), ifindex: buf.ifindex(), @@ -43,23 +43,23 @@ impl> Parseable> for PrefixHeader { } } -impl<'a, T: AsRef<[u8]> + 'a> Parseable> - for PrefixMessage -{ - fn parse(buf: &PrefixMessageBuffer<&'a T>) -> Result { +impl> Parseable> for PrefixMessage { + type Error = DecodeError; + + fn parse(buf: &PrefixMessageBuffer<&T>) -> Result { Ok(Self { - header: PrefixHeader::parse(buf) - .context("failed to parse prefix message header")?, - attributes: Vec::::parse(buf) - .context("failed to parse prefix message attributes")?, + header: PrefixHeader::parse(buf)?, + attributes: Vec::::parse(buf)?, }) } } -impl<'a, T: AsRef<[u8]> + 'a> Parseable> +impl> Parseable> for Vec { - fn parse(buf: &PrefixMessageBuffer<&'a T>) -> Result { + type Error = DecodeError; + + fn parse(buf: &PrefixMessageBuffer<&T>) -> Result { let mut nlas = vec![]; for nla_buf in buf.nlas() { nlas.push(PrefixAttribute::parse(&nla_buf?)?); diff --git a/src/route/attribute.rs b/src/route/attribute.rs index 344fc745..735b45d3 100644 --- a/src/route/attribute.rs +++ b/src/route/attribute.rs @@ -1,6 +1,5 @@ // SPDX-License-Identifier: MIT -use anyhow::Context; use byteorder::{ByteOrder, NativeEndian}; use netlink_packet_utils::{ nla::{DefaultNla, Nla, NlaBuffer}, @@ -188,20 +187,22 @@ impl Nla for RouteAttribute { } } -impl<'a, T: AsRef<[u8]> + ?Sized> +impl + ?Sized> ParseableParametrized< - NlaBuffer<&'a T>, + NlaBuffer<&T>, (AddressFamily, RouteType, RouteLwEnCapType), > for RouteAttribute { + type Error = DecodeError; + fn parse_with_param( - buf: &NlaBuffer<&'a T>, + buf: &NlaBuffer<&T>, (address_family, route_type, encap_type): ( AddressFamily, RouteType, RouteLwEnCapType, ), - ) -> Result { + ) -> Result { let payload = buf.value(); Ok(match buf.kind() { RTA_DST => { @@ -216,20 +217,10 @@ impl<'a, T: AsRef<[u8]> + ?Sized> RTA_PREFSRC => { Self::PrefSource(RouteAddress::parse(address_family, payload)?) } - RTA_VIA => Self::Via( - RouteVia::parse( - &RouteViaBuffer::new_checked(payload).context(format!( - "Invalid RTA_VIA value {:?}", - payload - ))?, - ) - .context(format!("Invalid RTA_VIA value {:?}", payload))?, - ), - RTA_NEWDST => Self::NewDestination( - VecMplsLabel::parse(payload) - .context(format!("Invalid RTA_NEWDST value {:?}", payload))? - .0, - ), + RTA_VIA => Self::Via(RouteVia::parse( + &RouteViaBuffer::new_checked(payload)?, + )?), + RTA_NEWDST => Self::NewDestination(VecMplsLabel::parse(payload)?.0), RTA_PREF => Self::Preference(parse_u8(payload)?.into()), RTA_ENCAP => Self::Encap( @@ -237,81 +228,42 @@ impl<'a, T: AsRef<[u8]> + ?Sized> ), RTA_EXPIRES => { if route_type == RouteType::Multicast { - Self::MulticastExpires(parse_u64(payload).context( - format!( - "invalid RTA_EXPIRES (multicast) value {:?}", - payload - ), - )?) + Self::MulticastExpires(parse_u64(payload)?) } else { - Self::Expires(parse_u32(payload).context(format!( - "invalid RTA_EXPIRES value {:?}", - payload - ))?) + Self::Expires(parse_u32(payload)?) } } - RTA_UID => Self::Uid( - parse_u32(payload) - .context(format!("invalid RTA_UID value {:?}", payload))?, - ), + RTA_UID => Self::Uid(parse_u32(payload)?), RTA_TTL_PROPAGATE => Self::TtlPropagate( - RouteMplsTtlPropagation::from(parse_u8(payload).context( - format!("invalid RTA_TTL_PROPAGATE {:?}", payload), - )?), + RouteMplsTtlPropagation::from(parse_u8(payload)?), ), - RTA_ENCAP_TYPE => Self::EncapType(RouteLwEnCapType::from( - parse_u16(payload).context("invalid RTA_ENCAP_TYPE value")?, - )), - RTA_IIF => { - Self::Iif(parse_u32(payload).context("invalid RTA_IIF value")?) + RTA_ENCAP_TYPE => { + Self::EncapType(RouteLwEnCapType::from(parse_u16(payload)?)) } - RTA_OIF => { - Self::Oif(parse_u32(payload).context("invalid RTA_OIF value")?) - } - RTA_PRIORITY => Self::Priority( - parse_u32(payload).context("invalid RTA_PRIORITY value")?, - ), - RTA_FLOW => Self::Realm( - RouteRealm::parse(payload).context("invalid RTA_FLOW value")?, - ), - RTA_TABLE => Self::Table( - parse_u32(payload).context("invalid RTA_TABLE value")?, - ), - RTA_MARK => Self::Mark( - parse_u32(payload).context("invalid RTA_MARK value")?, - ), + RTA_IIF => Self::Iif(parse_u32(payload)?), + RTA_OIF => Self::Oif(parse_u32(payload)?), + RTA_PRIORITY => Self::Priority(parse_u32(payload)?), + RTA_FLOW => Self::Realm(RouteRealm::parse(payload)?), + RTA_TABLE => Self::Table(parse_u32(payload)?), + RTA_MARK => Self::Mark(parse_u32(payload)?), - RTA_CACHEINFO => Self::CacheInfo( - RouteCacheInfo::parse( - &RouteCacheInfoBuffer::new_checked(payload) - .context("invalid RTA_CACHEINFO value")?, - ) - .context("invalid RTA_CACHEINFO value")?, - ), - RTA_MFC_STATS => Self::MfcStats( - RouteMfcStats::parse( - &RouteMfcStatsBuffer::new_checked(payload) - .context("invalid RTA_MFC_STATS value")?, - ) - .context("invalid RTA_MFC_STATS value")?, - ), - RTA_METRICS => Self::Metrics( - VecRouteMetric::parse(payload) - .context("invalid RTA_METRICS value")? - .0, - ), + RTA_CACHEINFO => Self::CacheInfo(RouteCacheInfo::parse( + &RouteCacheInfoBuffer::new_checked(payload)?, + )?), + RTA_MFC_STATS => Self::MfcStats(RouteMfcStats::parse( + &RouteMfcStatsBuffer::new_checked(payload)?, + )?), + RTA_METRICS => Self::Metrics(VecRouteMetric::parse(payload)?.0), RTA_MULTIPATH => { let mut next_hops = vec![]; let mut buf = payload; loop { - let nh_buf = RouteNextHopBuffer::new_checked(&buf) - .context("invalid RTA_MULTIPATH value")?; + let nh_buf = RouteNextHopBuffer::new_checked(&buf)?; let len = nh_buf.length() as usize; let nh = RouteNextHop::parse_with_param( &nh_buf, (address_family, route_type, encap_type), - ) - .context("invalid RTA_MULTIPATH value")?; + )?; next_hops.push(nh); if buf.len() == len { break; @@ -320,9 +272,7 @@ impl<'a, T: AsRef<[u8]> + ?Sized> } Self::MultiPath(next_hops) } - _ => Self::Other( - DefaultNla::parse(buf).context("invalid NLA (unknown kind)")?, - ), + _ => Self::Other(DefaultNla::parse(buf)?), }) } } diff --git a/src/route/cache_info.rs b/src/route/cache_info.rs index 42484c24..d7e5c626 100644 --- a/src/route/cache_info.rs +++ b/src/route/cache_info.rs @@ -32,7 +32,9 @@ buffer!(RouteCacheInfoBuffer(CACHE_INFO_LEN) { }); impl> Parseable> for RouteCacheInfo { - fn parse(buf: &RouteCacheInfoBuffer) -> Result { + type Error = DecodeError; + + fn parse(buf: &RouteCacheInfoBuffer) -> Result { Ok(Self { clntref: buf.clntref(), last_use: buf.last_use(), diff --git a/src/route/header.rs b/src/route/header.rs index c33af0f6..6e3988a8 100644 --- a/src/route/header.rs +++ b/src/route/header.rs @@ -1,7 +1,7 @@ // SPDX-License-Identifier: MIT use netlink_packet_utils::{ - nla::{NlaBuffer, NlasIterator}, + nla::{NlaBuffer, NlaError, NlasIterator}, traits::{Emitable, Parseable}, DecodeError, }; @@ -26,7 +26,7 @@ buffer!(RouteMessageBuffer(ROUTE_HEADER_LEN) { impl<'a, T: AsRef<[u8]> + ?Sized> RouteMessageBuffer<&'a T> { pub fn attributes( &self, - ) -> impl Iterator, DecodeError>> { + ) -> impl Iterator, NlaError>> { NlasIterator::new(self.payload()) } } @@ -61,10 +61,12 @@ impl RouteHeader { pub const RT_TABLE_UNSPEC: u8 = 0; } -impl<'a, T: AsRef<[u8]> + ?Sized> Parseable> +impl + ?Sized> Parseable> for RouteHeader { - fn parse(buf: &RouteMessageBuffer<&'a T>) -> Result { + type Error = DecodeError; + + fn parse(buf: &RouteMessageBuffer<&T>) -> Result { Ok(RouteHeader { address_family: buf.address_family().into(), destination_prefix_length: buf.destination_prefix_length(), @@ -246,7 +248,9 @@ impl Default for RouteProtocol { } impl Parseable<[u8]> for RouteProtocol { - fn parse(buf: &[u8]) -> Result { + type Error = DecodeError; + + fn parse(buf: &[u8]) -> Result { if buf.len() == 1 { Ok(Self::from(buf[0])) } else { diff --git a/src/route/lwtunnel.rs b/src/route/lwtunnel.rs index 8e1619f1..d5953206 100644 --- a/src/route/lwtunnel.rs +++ b/src/route/lwtunnel.rs @@ -1,6 +1,5 @@ // SPDX-License-Identifier: MIT -use anyhow::Context; use netlink_packet_utils::{ nla::{DefaultNla, Nla, NlaBuffer, NlasIterator}, traits::{Emitable, Parseable, ParseableParametrized}, @@ -136,15 +135,17 @@ impl Nla for RouteLwTunnelEncap { } } -impl<'a, T> ParseableParametrized, RouteLwEnCapType> +impl ParseableParametrized, RouteLwEnCapType> for RouteLwTunnelEncap where T: AsRef<[u8]> + ?Sized, { + type Error = DecodeError; + fn parse_with_param( - buf: &NlaBuffer<&'a T>, + buf: &NlaBuffer<&T>, kind: RouteLwEnCapType, - ) -> Result { + ) -> Result { Ok(match kind { RouteLwEnCapType::Mpls => { Self::Mpls(RouteMplsIpTunnel::parse(buf)?) @@ -158,22 +159,20 @@ where #[non_exhaustive] pub(crate) struct VecRouteLwTunnelEncap(pub(crate) Vec); -impl<'a, T> ParseableParametrized, RouteLwEnCapType> +impl ParseableParametrized, RouteLwEnCapType> for VecRouteLwTunnelEncap where T: AsRef<[u8]> + ?Sized, { + type Error = DecodeError; + fn parse_with_param( - buf: &NlaBuffer<&'a T>, + buf: &NlaBuffer<&T>, kind: RouteLwEnCapType, - ) -> Result { + ) -> Result { let mut ret = Vec::new(); for nla in NlasIterator::new(buf.value()) { - let nla = - nla.context(format!("Invalid RTA_ENCAP for kind: {kind}"))?; - ret.push(RouteLwTunnelEncap::parse_with_param(&nla, kind).context( - format!("Failed to parse RTA_ENCAP for kind: {kind}",), - )?) + ret.push(RouteLwTunnelEncap::parse_with_param(&nla?, kind)?) } Ok(Self(ret)) } diff --git a/src/route/message.rs b/src/route/message.rs index 072776cc..aab6fbed 100644 --- a/src/route/message.rs +++ b/src/route/message.rs @@ -1,6 +1,5 @@ // SPDX-License-Identifier: MIT -use anyhow::Context; use netlink_packet_utils::{ traits::{Emitable, Parseable, ParseableParametrized}, DecodeError, @@ -31,12 +30,11 @@ impl Emitable for RouteMessage { } } -impl<'a, T: AsRef<[u8]> + 'a> Parseable> - for RouteMessage -{ - fn parse(buf: &RouteMessageBuffer<&'a T>) -> Result { - let header = RouteHeader::parse(buf) - .context("failed to parse route message header")?; +impl> Parseable> for RouteMessage { + type Error = DecodeError; + + fn parse(buf: &RouteMessageBuffer<&T>) -> Result { + let header = RouteHeader::parse(buf)?; let address_family = header.address_family; let route_type = header.kind; Ok(RouteMessage { @@ -44,20 +42,21 @@ impl<'a, T: AsRef<[u8]> + 'a> Parseable> attributes: Vec::::parse_with_param( buf, (address_family, route_type), - ) - .context("failed to parse route message NLAs")?, + )?, }) } } -impl<'a, T: AsRef<[u8]> + 'a> - ParseableParametrized, (AddressFamily, RouteType)> +impl> + ParseableParametrized, (AddressFamily, RouteType)> for Vec { + type Error = DecodeError; + fn parse_with_param( - buf: &RouteMessageBuffer<&'a T>, + buf: &RouteMessageBuffer<&T>, (address_family, route_type): (AddressFamily, RouteType), - ) -> Result { + ) -> Result { let mut attributes = vec![]; let mut encap_type = RouteLwEnCapType::None; // The RTA_ENCAP_TYPE is provided __after__ RTA_ENCAP, we should find diff --git a/src/route/metrics.rs b/src/route/metrics.rs index 6bb24ea5..4c60bafb 100644 --- a/src/route/metrics.rs +++ b/src/route/metrics.rs @@ -1,6 +1,5 @@ // SPDX-License-Identifier: MIT -use anyhow::Context; use byteorder::{ByteOrder, NativeEndian}; use std::mem::size_of; @@ -126,66 +125,32 @@ impl Nla for RouteMetric { } } -impl<'a, T: AsRef<[u8]> + ?Sized> Parseable> for RouteMetric { - fn parse(buf: &NlaBuffer<&'a T>) -> Result { +impl + ?Sized> Parseable> for RouteMetric { + type Error = DecodeError; + + fn parse(buf: &NlaBuffer<&T>) -> Result { let payload = buf.value(); Ok(match buf.kind() { - RTAX_LOCK => Self::Lock( - parse_u32(payload).context("invalid RTAX_LOCK value")?, - ), - RTAX_MTU => { - Self::Mtu(parse_u32(payload).context("invalid RTAX_MTU value")?) - } - RTAX_WINDOW => Self::Window( - parse_u32(payload).context("invalid RTAX_WINDOW value")?, - ), - RTAX_RTT => { - Self::Rtt(parse_u32(payload).context("invalid RTAX_RTT value")?) + RTAX_LOCK => Self::Lock(parse_u32(payload)?), + RTAX_MTU => Self::Mtu(parse_u32(payload)?), + RTAX_WINDOW => Self::Window(parse_u32(payload)?), + RTAX_RTT => Self::Rtt(parse_u32(payload)?), + RTAX_RTTVAR => Self::RttVar(parse_u32(payload)?), + RTAX_SSTHRESH => Self::SsThresh(parse_u32(payload)?), + RTAX_CWND => Self::Cwnd(parse_u32(payload)?), + RTAX_ADVMSS => Self::Advmss(parse_u32(payload)?), + RTAX_REORDERING => Self::Reordering(parse_u32(payload)?), + RTAX_HOPLIMIT => Self::Hoplimit(parse_u32(payload)?), + RTAX_INITCWND => Self::InitCwnd(parse_u32(payload)?), + RTAX_FEATURES => Self::Features(parse_u32(payload)?), + RTAX_RTO_MIN => Self::RtoMin(parse_u32(payload)?), + RTAX_INITRWND => Self::InitRwnd(parse_u32(payload)?), + RTAX_QUICKACK => Self::QuickAck(parse_u32(payload)?), + RTAX_CC_ALGO => Self::CcAlgo(parse_u32(payload)?), + RTAX_FASTOPEN_NO_COOKIE => { + Self::FastopenNoCookie(parse_u32(payload)?) } - RTAX_RTTVAR => Self::RttVar( - parse_u32(payload).context("invalid RTAX_RTTVAR value")?, - ), - RTAX_SSTHRESH => Self::SsThresh( - parse_u32(payload).context("invalid RTAX_SSTHRESH value")?, - ), - RTAX_CWND => Self::Cwnd( - parse_u32(payload).context("invalid RTAX_CWND value")?, - ), - RTAX_ADVMSS => Self::Advmss( - parse_u32(payload).context("invalid RTAX_ADVMSS value")?, - ), - RTAX_REORDERING => Self::Reordering( - parse_u32(payload).context("invalid RTAX_REORDERING value")?, - ), - RTAX_HOPLIMIT => Self::Hoplimit( - parse_u32(payload).context("invalid RTAX_HOPLIMIT value")?, - ), - RTAX_INITCWND => Self::InitCwnd( - parse_u32(payload).context("invalid RTAX_INITCWND value")?, - ), - RTAX_FEATURES => Self::Features( - parse_u32(payload).context("invalid RTAX_FEATURES value")?, - ), - RTAX_RTO_MIN => Self::RtoMin( - parse_u32(payload).context("invalid RTAX_RTO_MIN value")?, - ), - RTAX_INITRWND => Self::InitRwnd( - parse_u32(payload).context("invalid RTAX_INITRWND value")?, - ), - RTAX_QUICKACK => Self::QuickAck( - parse_u32(payload).context("invalid RTAX_QUICKACK value")?, - ), - RTAX_CC_ALGO => Self::CcAlgo( - parse_u32(payload).context("invalid RTAX_CC_ALGO value")?, - ), - RTAX_FASTOPEN_NO_COOKIE => Self::FastopenNoCookie( - parse_u32(payload) - .context("invalid RTAX_FASTOPEN_NO_COOKIE value")?, - ), - _ => Self::Other( - DefaultNla::parse(buf) - .context("invalid NLA value (unknown type) value")?, - ), + _ => Self::Other(DefaultNla::parse(buf)?), }) } } @@ -193,11 +158,12 @@ impl<'a, T: AsRef<[u8]> + ?Sized> Parseable> for RouteMetric { pub(crate) struct VecRouteMetric(pub(crate) Vec); impl + ?Sized> Parseable for VecRouteMetric { - fn parse(payload: &T) -> Result { + type Error = DecodeError; + + fn parse(payload: &T) -> Result { let mut nlas = vec![]; for nla in NlasIterator::new(payload) { - let nla = nla.context("Invalid RTA_METRICS")?; - nlas.push(RouteMetric::parse(&nla).context("Invalid RTA_METRICS")?); + nlas.push(RouteMetric::parse(&nla?)?); } Ok(Self(nlas)) } diff --git a/src/route/mfc_stats.rs b/src/route/mfc_stats.rs index a9f14455..1e13cf20 100644 --- a/src/route/mfc_stats.rs +++ b/src/route/mfc_stats.rs @@ -22,9 +22,11 @@ buffer!(RouteMfcStatsBuffer(MFC_STATS_LEN) { }); impl> Parseable> for RouteMfcStats { + type Error = DecodeError; + fn parse( buf: &RouteMfcStatsBuffer, - ) -> Result { + ) -> Result { Ok(RouteMfcStats { packets: buf.packets(), bytes: buf.bytes(), diff --git a/src/route/mpls.rs b/src/route/mpls.rs index 96f75153..59c1d941 100644 --- a/src/route/mpls.rs +++ b/src/route/mpls.rs @@ -1,6 +1,5 @@ // SPDX-License-Identifier: MIT -use anyhow::Context; use netlink_packet_utils::{ nla::{DefaultNla, Nla, NlaBuffer}, parsers::parse_u8, @@ -47,27 +46,17 @@ impl Nla for RouteMplsIpTunnel { } } -impl<'a, T: AsRef<[u8]> + ?Sized> Parseable> - for RouteMplsIpTunnel -{ - fn parse(buf: &NlaBuffer<&'a T>) -> Result { +impl + ?Sized> Parseable> for RouteMplsIpTunnel { + type Error = DecodeError; + + fn parse(buf: &NlaBuffer<&T>) -> Result { let payload = buf.value(); Ok(match buf.kind() { - MPLS_IPTUNNEL_DST => Self::Destination( - VecMplsLabel::parse(payload) - .context(format!( - "invalid MPLS_IPTUNNEL_DST value {:?}", - payload - ))? - .0, - ), - MPLS_IPTUNNEL_TTL => Self::Ttl( - parse_u8(payload).context("invalid MPLS_IPTUNNEL_TTL value")?, - ), - _ => Self::Other( - DefaultNla::parse(buf) - .context("invalid NLA value (unknown type) value")?, - ), + MPLS_IPTUNNEL_DST => { + Self::Destination(VecMplsLabel::parse(payload)?.0) + } + MPLS_IPTUNNEL_TTL => Self::Ttl(parse_u8(payload)?), + _ => Self::Other(DefaultNla::parse(buf)?), }) } } diff --git a/src/route/next_hops.rs b/src/route/next_hops.rs index 1586586c..90191dd2 100644 --- a/src/route/next_hops.rs +++ b/src/route/next_hops.rs @@ -1,8 +1,7 @@ // SPDX-License-Identifier: MIT -use anyhow::Context; use netlink_packet_utils::{ - nla::{NlaBuffer, NlasIterator}, + nla::{NlaBuffer, NlaError, NlasIterator}, traits::{Emitable, ParseableParametrized}, DecodeError, }; @@ -74,7 +73,7 @@ impl> RouteNextHopBuffer { impl<'a, T: AsRef<[u8]> + ?Sized> RouteNextHopBuffer<&'a T> { pub fn attributes( &self, - ) -> impl Iterator, DecodeError>> { + ) -> impl Iterator, NlaError>> { NlasIterator::new( &self.payload()[..(self.length() as usize - PAYLOAD_OFFSET)], ) @@ -100,6 +99,8 @@ impl> (AddressFamily, RouteType, RouteLwEnCapType), > for RouteNextHop { + type Error = DecodeError; + fn parse_with_param( buf: &RouteNextHopBuffer<&T>, (address_family, route_type, encap_type): ( @@ -109,11 +110,9 @@ impl> ), ) -> Result { let attributes = Vec::::parse_with_param( - &RouteNextHopBuffer::new_checked(buf.buffer) - .context("cannot parse route attributes in next-hop")?, + &RouteNextHopBuffer::new_checked(buf.buffer)?, (address_family, route_type, encap_type), - ) - .context("cannot parse route attributes in next-hop")?; + )?; Ok(RouteNextHop { flags: RouteNextHopFlags::from_bits_retain(buf.flags()), hops: buf.hops(), @@ -123,20 +122,22 @@ impl> } } -impl<'a, T: AsRef<[u8]> + 'a> +impl> ParseableParametrized< - RouteNextHopBuffer<&'a T>, + RouteNextHopBuffer<&T>, (AddressFamily, RouteType, RouteLwEnCapType), > for Vec { + type Error = DecodeError; + fn parse_with_param( - buf: &RouteNextHopBuffer<&'a T>, + buf: &RouteNextHopBuffer<&T>, (address_family, route_type, encap_type): ( AddressFamily, RouteType, RouteLwEnCapType, ), - ) -> Result { + ) -> Result { let mut nlas = vec![]; for nla_buf in buf.attributes() { nlas.push(RouteAttribute::parse_with_param( diff --git a/src/route/via.rs b/src/route/via.rs index e7da6924..6fa58d28 100644 --- a/src/route/via.rs +++ b/src/route/via.rs @@ -33,10 +33,10 @@ buffer!(RouteViaBuffer(RTVIA_LEN) { address: (slice, RTVIA_LEN..), }); -impl<'a, T: AsRef<[u8]> + ?Sized> Parseable> - for RouteVia -{ - fn parse(buf: &RouteViaBuffer<&'a T>) -> Result { +impl + ?Sized> Parseable> for RouteVia { + type Error = DecodeError; + + fn parse(buf: &RouteViaBuffer<&T>) -> Result { let address_family: AddressFamily = (buf.address_family() as u8).into(); Ok(match address_family { AddressFamily::Inet => Self::Inet(parse_ipv4_addr(buf.address())?), diff --git a/src/rule/attribute.rs b/src/rule/attribute.rs index 2c38972c..cd2d29e5 100644 --- a/src/rule/attribute.rs +++ b/src/rule/attribute.rs @@ -2,7 +2,6 @@ use std::net::IpAddr; -use anyhow::Context; use netlink_packet_utils::{ byteorder::{ByteOrder, NativeEndian}, nla::{DefaultNla, Nla, NlaBuffer}, @@ -149,82 +148,40 @@ impl Nla for RuleAttribute { } } -impl<'a, T: AsRef<[u8]> + ?Sized> Parseable> - for RuleAttribute -{ - fn parse(buf: &NlaBuffer<&'a T>) -> Result { +impl + ?Sized> Parseable> for RuleAttribute { + type Error = DecodeError; + fn parse(buf: &NlaBuffer<&T>) -> Result { let payload = buf.value(); Ok(match buf.kind() { - FRA_DST => Self::Destination( - parse_ip_addr(payload) - .context(format!("Invalid FRA_DST value {payload:?}"))?, - ), - FRA_SRC => Self::Source( - parse_ip_addr(payload) - .context(format!("Invalid FRA_SRC value {payload:?}"))?, - ), - FRA_IIFNAME => Self::Iifname( - parse_string(payload).context("invalid FRA_IIFNAME value")?, - ), - FRA_GOTO => Self::Goto( - parse_u32(payload).context("invalid FRA_GOTO value")?, - ), - FRA_PRIORITY => Self::Priority( - parse_u32(payload).context("invalid FRA_PRIORITY value")?, - ), - FRA_FWMARK => Self::FwMark( - parse_u32(payload).context("invalid FRA_FWMARK value")?, - ), - FRA_FLOW => Self::Realm( - RouteRealm::parse(payload).context("invalid FRA_FLOW value")?, - ), - FRA_TUN_ID => Self::TunId( - parse_u32(payload).context("invalid FRA_TUN_ID value")?, - ), - FRA_SUPPRESS_IFGROUP => Self::SuppressIfGroup( - parse_u32(payload) - .context("invalid FRA_SUPPRESS_IFGROUP value")?, - ), - FRA_SUPPRESS_PREFIXLEN => Self::SuppressPrefixLen( - parse_u32(payload) - .context("invalid FRA_SUPPRESS_PREFIXLEN value")?, - ), - FRA_TABLE => Self::Table( - parse_u32(payload).context("invalid FRA_TABLE value")?, - ), - FRA_FWMASK => Self::FwMask( - parse_u32(payload).context("invalid FRA_FWMASK value")?, - ), - FRA_OIFNAME => Self::Oifname( - parse_string(payload).context("invalid FRA_OIFNAME value")?, - ), - FRA_L3MDEV => Self::L3MDev( - parse_u8(payload).context("invalid FRA_L3MDEV value")? > 0, - ), - FRA_UID_RANGE => Self::UidRange( - RuleUidRange::parse(payload) - .context("invalid FRA_UID_RANGE value")?, - ), - FRA_PROTOCOL => Self::Protocol( - parse_u8(payload) - .context("invalid FRA_PROTOCOL value")? - .into(), - ), - FRA_IP_PROTO => Self::IpProtocol(IpProtocol::from( - parse_u8(payload).context("invalid FRA_IP_PROTO value")? as i32, - )), - FRA_SPORT_RANGE => Self::SourcePortRange( - RulePortRange::parse(payload) - .context("invalid FRA_SPORT_RANGE value")?, - ), - FRA_DPORT_RANGE => Self::DestinationPortRange( - RulePortRange::parse(payload) - .context("invalid FRA_DPORT_RANGE value")?, - ), - _ => Self::Other( - DefaultNla::parse(buf).context("invalid NLA (unknown kind)")?, - ), + FRA_DST => Self::Destination(parse_ip_addr(payload)?), + FRA_SRC => Self::Source(parse_ip_addr(payload)?), + FRA_IIFNAME => Self::Iifname(parse_string(payload)?), + FRA_GOTO => Self::Goto(parse_u32(payload)?), + FRA_PRIORITY => Self::Priority(parse_u32(payload)?), + FRA_FWMARK => Self::FwMark(parse_u32(payload)?), + FRA_FLOW => Self::Realm(RouteRealm::parse(payload)?), + FRA_TUN_ID => Self::TunId(parse_u32(payload)?), + FRA_SUPPRESS_IFGROUP => Self::SuppressIfGroup(parse_u32(payload)?), + FRA_SUPPRESS_PREFIXLEN => { + Self::SuppressPrefixLen(parse_u32(payload)?) + } + FRA_TABLE => Self::Table(parse_u32(payload)?), + FRA_FWMASK => Self::FwMask(parse_u32(payload)?), + FRA_OIFNAME => Self::Oifname(parse_string(payload)?), + FRA_L3MDEV => Self::L3MDev(parse_u8(payload)? > 0), + FRA_UID_RANGE => Self::UidRange(RuleUidRange::parse(payload)?), + FRA_PROTOCOL => Self::Protocol(parse_u8(payload)?.into()), + FRA_IP_PROTO => { + Self::IpProtocol(IpProtocol::from(parse_u8(payload)? as i32)) + } + FRA_SPORT_RANGE => { + Self::SourcePortRange(RulePortRange::parse(payload)?) + } + FRA_DPORT_RANGE => { + Self::DestinationPortRange(RulePortRange::parse(payload)?) + } + _ => Self::Other(DefaultNla::parse(buf)?), }) } } diff --git a/src/rule/header.rs b/src/rule/header.rs index 8451ec47..a465b033 100644 --- a/src/rule/header.rs +++ b/src/rule/header.rs @@ -1,7 +1,7 @@ // SPDX-License-Identifier: MIT use netlink_packet_utils::{ - nla::{NlaBuffer, NlasIterator}, + nla::{NlaBuffer, NlaError, NlasIterator}, traits::{Emitable, Parseable}, DecodeError, }; @@ -26,7 +26,7 @@ buffer!(RuleMessageBuffer(RULE_HEADER_LEN) { impl<'a, T: AsRef<[u8]> + ?Sized> RuleMessageBuffer<&'a T> { pub fn attributes( &self, - ) -> impl Iterator, DecodeError>> { + ) -> impl Iterator, NlaError>> { NlasIterator::new(self.payload()) } } @@ -60,10 +60,10 @@ impl Emitable for RuleHeader { } } -impl<'a, T: AsRef<[u8]> + ?Sized> Parseable> - for RuleHeader -{ - fn parse(buf: &RuleMessageBuffer<&'a T>) -> Result { +impl + ?Sized> Parseable> for RuleHeader { + type Error = DecodeError; + + fn parse(buf: &RuleMessageBuffer<&T>) -> Result { Ok(RuleHeader { family: buf.family().into(), dst_len: buf.dst_len(), diff --git a/src/rule/message.rs b/src/rule/message.rs index fa96cf01..bce43cf8 100644 --- a/src/rule/message.rs +++ b/src/rule/message.rs @@ -1,6 +1,5 @@ // SPDX-License-Identifier: MIT -use anyhow::Context; use netlink_packet_utils::{ traits::{Emitable, Parseable}, DecodeError, @@ -28,22 +27,20 @@ impl Emitable for RuleMessage { } } -impl<'a, T: AsRef<[u8]> + 'a> Parseable> - for RuleMessage -{ - fn parse(buf: &RuleMessageBuffer<&'a T>) -> Result { - let header = RuleHeader::parse(buf) - .context("failed to parse link message header")?; - let attributes = Vec::::parse(buf) - .context("failed to parse link message NLAs")?; +impl> Parseable> for RuleMessage { + type Error = DecodeError; + + fn parse(buf: &RuleMessageBuffer<&T>) -> Result { + let header = RuleHeader::parse(buf)?; + let attributes = Vec::::parse(buf)?; Ok(RuleMessage { header, attributes }) } } -impl<'a, T: AsRef<[u8]> + 'a> Parseable> - for Vec -{ - fn parse(buf: &RuleMessageBuffer<&'a T>) -> Result { +impl> Parseable> for Vec { + type Error = DecodeError; + + fn parse(buf: &RuleMessageBuffer<&T>) -> Result { let mut attributes = vec![]; for nla_buf in buf.attributes() { attributes.push(RuleAttribute::parse(&nla_buf?)?); diff --git a/src/tc/actions/action.rs b/src/tc/actions/action.rs index c19e6229..32ba516a 100644 --- a/src/tc/actions/action.rs +++ b/src/tc/actions/action.rs @@ -1,10 +1,9 @@ // SPDX-License-Identifier: MIT -use anyhow::Context; use byteorder::{ByteOrder, NativeEndian}; use netlink_packet_utils::nla::NLA_F_NESTED; use netlink_packet_utils::{ - nla::{DefaultNla, Nla, NlaBuffer, NlasIterator}, + nla::{DefaultNla, Nla, NlaBuffer, NlaError, NlasIterator}, parsers::{parse_string, parse_u32}, traits::{Emitable, Parseable, ParseableParametrized}, DecodeError, @@ -58,8 +57,10 @@ impl Nla for TcAction { } } -impl<'a, T: AsRef<[u8]> + ?Sized> Parseable> for TcAction { - fn parse(buf: &NlaBuffer<&'a T>) -> Result { +impl + ?Sized> Parseable> for TcAction { + type Error = DecodeError; + + fn parse(buf: &NlaBuffer<&T>) -> Result { // We need to find the `Kind` attribute before we can parse the others, // as kind is used in calls to parse_with_param for the other // attributes. @@ -73,17 +74,15 @@ impl<'a, T: AsRef<[u8]> + ?Sized> Parseable> for TcAction { .filter_map(|nla| { let nla = match nla { Ok(nla) => nla, - Err(e) => { - return Some( - Err(e).context("failed to parse action nla"), - ) - } + Err(e) => return Some(Err(e)), }; match nla.kind() { - TCA_ACT_KIND => Some( - parse_string(nla.value()) - .context("failed to parse TCA_ACT_KIND"), - ), + TCA_ACT_KIND => { + Some(parse_string(nla.value()).map_err(|_| { + // Placeholder error, as we need to return a NlaError + NlaError::InvalidLength { nla_len: 0 } + })) + } _ => None, } }) @@ -216,53 +215,40 @@ impl Nla for TcActionAttribute { } } -impl<'a, T, P> ParseableParametrized, P> for TcActionAttribute +impl ParseableParametrized, P> for TcActionAttribute where T: AsRef<[u8]> + ?Sized, P: AsRef, { + type Error = DecodeError; + fn parse_with_param( - buf: &NlaBuffer<&'a T>, + buf: &NlaBuffer<&T>, kind: P, - ) -> Result { + ) -> Result { Ok(match buf.kind() { TCA_ACT_KIND => { let buf_value = buf.value(); - TcActionAttribute::Kind( - parse_string(buf_value) - .context("failed to parse TCA_ACT_KIND")?, - ) + TcActionAttribute::Kind(parse_string(buf_value)?) } TCA_ACT_OPTIONS => TcActionAttribute::Options( NlasIterator::new(buf.value()) .map(|nla| { - let nla = nla.context("invalid TCA_ACT_OPTIONS")?; - TcActionOption::parse_with_param(&nla, kind.as_ref()) - .context("failed to parse TCA_ACT_OPTIONS") + TcActionOption::parse_with_param(&nla?, kind.as_ref()) }) .collect::, _>>()?, ), - TCA_ACT_INDEX => TcActionAttribute::Index( - parse_u32(buf.value()) - .context("failed to parse TCA_ACT_INDEX")?, - ), + TCA_ACT_INDEX => TcActionAttribute::Index(parse_u32(buf.value())?), TCA_ACT_STATS => TcActionAttribute::Stats( NlasIterator::new(buf.value()) - .map(|nla| { - let nla = nla.context("invalid TCA_ACT_STATS")?; - TcStats2::parse_with_param(&nla, kind.as_ref()) - .context("failed to parse TCA_ACT_STATS") - }) + .map(|nla| TcStats2::parse_with_param(&nla?, kind.as_ref())) .collect::, _>>()?, ), TCA_ACT_COOKIE => TcActionAttribute::Cookie(buf.value().to_vec()), - TCA_ACT_IN_HW_COUNT => TcActionAttribute::InHwCount( - parse_u32(buf.value()) - .context("failed to parse TCA_ACT_IN_HW_COUNT")?, - ), - _ => TcActionAttribute::Other( - DefaultNla::parse(buf).context("failed to parse action nla")?, - ), + TCA_ACT_IN_HW_COUNT => { + TcActionAttribute::InHwCount(parse_u32(buf.value())?) + } + _ => TcActionAttribute::Other(DefaultNla::parse(buf)?), }) } } @@ -325,32 +311,26 @@ impl Nla for TcActionOption { } } -impl<'a, T, S> ParseableParametrized, S> for TcActionOption +impl ParseableParametrized, S> for TcActionOption where T: AsRef<[u8]> + ?Sized, S: AsRef, { + type Error = DecodeError; + fn parse_with_param( - buf: &NlaBuffer<&'a T>, + buf: &NlaBuffer<&T>, kind: S, - ) -> Result { + ) -> Result { Ok(match kind.as_ref() { - TcActionMirror::KIND => Self::Mirror( - TcActionMirrorOption::parse(buf) - .context("failed to parse mirror action")?, - ), - TcActionNat::KIND => Self::Nat( - TcActionNatOption::parse(buf) - .context("failed to parse nat action")?, - ), - TcActionTunnelKey::KIND => Self::TunnelKey( - TcActionTunnelKeyOption::parse(buf) - .context("failed to parse tunnel_key action")?, - ), - _ => Self::Other( - DefaultNla::parse(buf) - .context("failed to parse action options")?, - ), + TcActionMirror::KIND => { + Self::Mirror(TcActionMirrorOption::parse(buf)?) + } + TcActionNat::KIND => Self::Nat(TcActionNatOption::parse(buf)?), + TcActionTunnelKey::KIND => { + Self::TunnelKey(TcActionTunnelKeyOption::parse(buf)?) + } + _ => Self::Other(DefaultNla::parse(buf)?), }) } } @@ -451,7 +431,9 @@ impl Emitable for TcActionGeneric { } impl> Parseable> for TcActionGeneric { - fn parse(buf: &TcActionGenericBuffer) -> Result { + type Error = DecodeError; + + fn parse(buf: &TcActionGenericBuffer) -> Result { Ok(Self { index: buf.index(), capab: buf.capab(), @@ -580,7 +562,9 @@ buffer!(TcfBuffer(TC_TCF_BUF_LEN) { }); impl + ?Sized> Parseable> for Tcf { - fn parse(buf: &TcfBuffer<&T>) -> Result { + type Error = DecodeError; + + fn parse(buf: &TcfBuffer<&T>) -> Result { Ok(Self { install: buf.install(), lastuse: buf.lastuse(), diff --git a/src/tc/actions/header.rs b/src/tc/actions/header.rs index 2bc85938..694fd416 100644 --- a/src/tc/actions/header.rs +++ b/src/tc/actions/header.rs @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT -use netlink_packet_utils::nla::{NlaBuffer, NlasIterator}; +use netlink_packet_utils::nla::{NlaBuffer, NlaError, NlasIterator}; use netlink_packet_utils::{DecodeError, Emitable, Parseable}; use crate::AddressFamily; @@ -18,7 +18,7 @@ impl<'a, T: AsRef<[u8]> + ?Sized> TcActionMessageBuffer<&'a T> { /// Returns an iterator over the attributes of a `TcActionMessageBuffer`. pub fn attributes( &self, - ) -> impl Iterator, DecodeError>> { + ) -> impl Iterator, NlaError>> { NlasIterator::new(self.payload()) } } @@ -44,7 +44,9 @@ impl Emitable for TcActionMessageHeader { impl> Parseable> for TcActionMessageHeader { - fn parse(buf: &TcActionMessageBuffer) -> Result { + type Error = DecodeError; + + fn parse(buf: &TcActionMessageBuffer) -> Result { Ok(TcActionMessageHeader { family: buf.family().into(), }) diff --git a/src/tc/actions/message.rs b/src/tc/actions/message.rs index 9038ed1f..c9a9efe9 100644 --- a/src/tc/actions/message.rs +++ b/src/tc/actions/message.rs @@ -1,6 +1,5 @@ // SPDX-License-Identifier: MIT -use anyhow::Context; use netlink_packet_utils::nla::{DefaultNla, NlaBuffer}; use netlink_packet_utils::nla::{Nla, NlasIterator}; use netlink_packet_utils::{DecodeError, Emitable, Parseable}; @@ -104,22 +103,28 @@ impl TcActionMessageFlagsWithSelector { } } -impl<'a, T: AsRef<[u8]> + 'a + ?Sized> Parseable> +impl + ?Sized> Parseable> for TcActionMessageFlagsWithSelector { - fn parse(buf: &NlaBuffer<&'a T>) -> Result { + type Error = DecodeError; + + fn parse(buf: &NlaBuffer<&T>) -> Result { let value = buf.value(); if value.len() != 8 { - return Err(DecodeError::from("invalid length")); + return Err(Self::Error::from("invalid length")); } let flags = TcActionMessageFlags::from_bits(u32::from_ne_bytes( - value[0..4].try_into().context("invalid length")?, + value[0..4] + .try_into() + .map_err(|_| Self::Error::from("invalid length"))?, )) - .ok_or_else(|| DecodeError::from("invalid flags"))?; + .ok_or_else(|| Self::Error::from("invalid flags"))?; let selector = TcActionMessageFlags::from_bits(u32::from_ne_bytes( - value[4..].try_into().context("invalid length")?, + value[4..] + .try_into() + .map_err(|_| Self::Error::from("invalid length"))?, )) - .ok_or_else(|| DecodeError::from("invalid flags selector"))?; + .ok_or_else(|| Self::Error::from("invalid flags selector"))?; Ok(Self::new_with_selector(flags, selector)) } } @@ -151,10 +156,12 @@ pub enum TcActionMessageAttribute { Other(DefaultNla), } -impl<'a, T: AsRef<[u8]> + 'a + ?Sized> Parseable> +impl + ?Sized> Parseable> for TcActionMessageAttribute { - fn parse(buf: &NlaBuffer<&'a T>) -> Result { + type Error = DecodeError; + + fn parse(buf: &NlaBuffer<&T>) -> Result { Ok(match buf.kind() { TCA_ACT_TAB => { let actions = NlasIterator::new(buf.value()) @@ -167,19 +174,22 @@ impl<'a, T: AsRef<[u8]> + 'a + ?Sized> Parseable> } TCA_ROOT_COUNT => { let count = u32::from_ne_bytes( - buf.value().try_into().context("invalid length")?, + buf.value() + .try_into() + .map_err(|_| Self::Error::from("invalid length"))?, ); Self::RootCount(count) } TCA_ROOT_TIME_DELTA => { let delta = u32::from_be_bytes( - buf.value().try_into().context("invalid length")?, + buf.value() + .try_into() + .map_err(|_| Self::Error::from("invalid length"))?, ); Self::RootTimeDelta(delta) } TCA_ROOT_EXT_WARN_MSG => { - let msg = String::from_utf8(buf.value().to_vec()) - .context("invalid utf8")?; + let msg = String::from_utf8(buf.value().to_vec())?; Self::RootExtWarnMsg(msg) } _ => Self::Other(DefaultNla::parse(buf)?), @@ -228,18 +238,19 @@ impl Nla for TcActionMessageAttribute { } } -impl<'a, T: AsRef<[u8]> + 'a + ?Sized> Parseable> +impl + ?Sized> Parseable> for TcActionMessage { - fn parse(buf: &TcActionMessageBuffer<&'a T>) -> Result { + type Error = DecodeError; + + fn parse(buf: &TcActionMessageBuffer<&T>) -> Result { let attrs: Result, DecodeError> = buf .attributes() .map(|attr| TcActionMessageAttribute::parse(&attr?)) .collect::, _>>(); Ok(Self { - header: TcActionMessageHeader::parse(buf) - .context("failed to parse tc message header")?, + header: TcActionMessageHeader::parse(buf)?, attributes: attrs?, }) } diff --git a/src/tc/actions/mirror.rs b/src/tc/actions/mirror.rs index a43ce687..2fa015be 100644 --- a/src/tc/actions/mirror.rs +++ b/src/tc/actions/mirror.rs @@ -65,10 +65,12 @@ impl Nla for TcActionMirrorOption { } } -impl<'a, T: AsRef<[u8]> + ?Sized> Parseable> +impl + ?Sized> Parseable> for TcActionMirrorOption { - fn parse(buf: &NlaBuffer<&'a T>) -> Result { + type Error = DecodeError; + + fn parse(buf: &NlaBuffer<&T>) -> Result { let payload = buf.value(); Ok(match buf.kind() { TCA_MIRRED_TM => { @@ -117,7 +119,9 @@ impl Emitable for TcMirror { } impl + ?Sized> Parseable> for TcMirror { - fn parse(buf: &TcMirrorBuffer<&T>) -> Result { + type Error = DecodeError; + + fn parse(buf: &TcMirrorBuffer<&T>) -> Result { Ok(Self { generic: TcActionGeneric::parse(&TcActionGenericBuffer::new( buf.generic(), diff --git a/src/tc/actions/nat.rs b/src/tc/actions/nat.rs index 4c0d14e2..cf73dba5 100644 --- a/src/tc/actions/nat.rs +++ b/src/tc/actions/nat.rs @@ -68,7 +68,9 @@ impl Nla for TcActionNatOption { impl<'a, T: AsRef<[u8]> + ?Sized> Parseable> for TcActionNatOption { - fn parse(buf: &NlaBuffer<&'a T>) -> Result { + type Error = DecodeError; + + fn parse(buf: &NlaBuffer<&'a T>) -> Result { let payload = buf.value(); Ok(match buf.kind() { TCA_NAT_TM => { @@ -140,7 +142,9 @@ impl Emitable for TcNat { } impl + ?Sized> Parseable> for TcNat { - fn parse(buf: &TcNatBuffer<&T>) -> Result { + type Error = DecodeError; + + fn parse(buf: &TcNatBuffer<&T>) -> Result { Ok(Self { generic: TcActionGeneric::parse(&TcActionGenericBuffer::new( buf.generic(), diff --git a/src/tc/actions/tunnel_key.rs b/src/tc/actions/tunnel_key.rs index 706ace64..d81d0b79 100755 --- a/src/tc/actions/tunnel_key.rs +++ b/src/tc/actions/tunnel_key.rs @@ -1,7 +1,6 @@ // SPDX-License-Identifier: MIT use crate::ip::{parse_ipv4_addr, parse_ipv6_addr}; -use anyhow::Context; /// set tunnel key /// /// The set_tunnel action allows to set tunnel encap applied @@ -112,7 +111,9 @@ impl Nla for TcActionTunnelKeyOption { impl<'a, T: AsRef<[u8]> + ?Sized> Parseable> for TcActionTunnelKeyOption { - fn parse(buf: &NlaBuffer<&'a T>) -> Result { + type Error = DecodeError; + + fn parse(buf: &NlaBuffer<&'a T>) -> Result { let payload = buf.value(); Ok(match buf.kind() { TCA_TUNNEL_KEY_TM => { @@ -121,43 +122,25 @@ impl<'a, T: AsRef<[u8]> + ?Sized> Parseable> TCA_TUNNEL_KEY_PARMS => Self::Parms(TcTunnelKey::parse( &TcTunnelKeyBuffer::new_checked(payload)?, )?), - TCA_TUNNEL_KEY_ENC_IPV4_SRC => Self::EncIpv4Src( - parse_ipv4_addr(payload) - .context("failed to parse TCA_TUNNEL_KEY_ENC_IPV4_SRC")?, - ), - TCA_TUNNEL_KEY_ENC_IPV4_DST => Self::EncIpv4Dst( - parse_ipv4_addr(payload) - .context("failed to parse TCA_TUNNEL_KEY_ENC_IPV4_DST")?, - ), - TCA_TUNNEL_KEY_ENC_IPV6_SRC => Self::EncIpv6Src( - parse_ipv6_addr(payload) - .context("failed to parse TCA_TUNNEL_KEY_ENC_IPV6_SRC")?, - ), - TCA_TUNNEL_KEY_ENC_IPV6_DST => Self::EncIpv6Dst( - parse_ipv6_addr(payload) - .context("failed to parse TCA_TUNNEL_KEY_ENC_IPV6_DST")?, - ), - TCA_TUNNEL_KEY_ENC_KEY_ID => Self::EncKeyId( - parse_u32_be(payload) - .context("failed to parse TCA_TUNNEL_KEY_ENC_KEY_ID")?, - ), - TCA_TUNNEL_KEY_ENC_DST_PORT => Self::EncDstPort( - parse_u16_be(payload) - .context("failed to parse TCA_TUNNEL_KEY_ENC_DST_PORT")?, - ), - TCA_TUNNEL_KEY_ENC_TOS => Self::EncTos( - parse_u8(payload) - .context("failed to parse TCA_TUNNEL_KEY_ENC_TOS")?, - ), - TCA_TUNNEL_KEY_ENC_TTL => Self::EncTtl( - parse_u8(payload) - .context("failed to parse TCA_TUNNEL_KEY_ENC_TTL")?, - ), - TCA_TUNNEL_KEY_NO_CSUM => Self::NoCsum( - parse_u8(payload) - .context("invalid TCA_TUNNEL_KEY_NO_CSUM value")? - != 0, - ), + TCA_TUNNEL_KEY_ENC_IPV4_SRC => { + Self::EncIpv4Src(parse_ipv4_addr(payload)?) + } + TCA_TUNNEL_KEY_ENC_IPV4_DST => { + Self::EncIpv4Dst(parse_ipv4_addr(payload)?) + } + TCA_TUNNEL_KEY_ENC_IPV6_SRC => { + Self::EncIpv6Src(parse_ipv6_addr(payload)?) + } + TCA_TUNNEL_KEY_ENC_IPV6_DST => { + Self::EncIpv6Dst(parse_ipv6_addr(payload)?) + } + TCA_TUNNEL_KEY_ENC_KEY_ID => Self::EncKeyId(parse_u32_be(payload)?), + TCA_TUNNEL_KEY_ENC_DST_PORT => { + Self::EncDstPort(parse_u16_be(payload)?) + } + TCA_TUNNEL_KEY_ENC_TOS => Self::EncTos(parse_u8(payload)?), + TCA_TUNNEL_KEY_ENC_TTL => Self::EncTtl(parse_u8(payload)?), + TCA_TUNNEL_KEY_NO_CSUM => Self::NoCsum(parse_u8(payload)? != 0), _ => Self::Other(DefaultNla::parse(buf)?), }) } @@ -190,7 +173,9 @@ impl Emitable for TcTunnelKey { } impl + ?Sized> Parseable> for TcTunnelKey { - fn parse(buf: &TcTunnelKeyBuffer<&T>) -> Result { + type Error = DecodeError; + + fn parse(buf: &TcTunnelKeyBuffer<&T>) -> Result { Ok(Self { generic: TcActionGeneric::parse(&TcActionGenericBuffer::new( buf.generic(), diff --git a/src/tc/attribute.rs b/src/tc/attribute.rs index 01a0b577..dd03d754 100644 --- a/src/tc/attribute.rs +++ b/src/tc/attribute.rs @@ -1,6 +1,5 @@ // SPDX-License-Identifier: MIT -use anyhow::Context; use byteorder::{ByteOrder, NativeEndian}; use netlink_packet_utils::{ nla::{DefaultNla, Nla, NlaBuffer, NlasIterator}, @@ -105,57 +104,41 @@ impl Nla for TcAttribute { } } -impl<'a, T: AsRef<[u8]> + ?Sized> ParseableParametrized, &str> +impl + ?Sized> ParseableParametrized, &str> for TcAttribute { + type Error = DecodeError; + fn parse_with_param( - buf: &NlaBuffer<&'a T>, + buf: &NlaBuffer<&T>, kind: &str, - ) -> Result { + ) -> Result { let payload = buf.value(); Ok(match buf.kind() { - TCA_KIND => TcAttribute::Kind( - parse_string(payload).context("invalid TCA_KIND")?, - ), + TCA_KIND => TcAttribute::Kind(parse_string(payload)?), TCA_OPTIONS => TcAttribute::Options( - VecTcOption::parse_with_param(buf, kind) - .context(format!("Invalid TCA_OPTIONS for kind: {kind}"))? - .0, - ), - TCA_STATS => TcAttribute::Stats( - TcStats::parse( - &TcStatsBuffer::new_checked(payload) - .context("invalid TCA_STATS")?, - ) - .context("failed to parse TCA_STATS")?, - ), - TCA_XSTATS => TcAttribute::Xstats( - TcXstats::parse_with_param(buf, kind) - .context("invalid TCA_XSTATS")?, + VecTcOption::parse_with_param(buf, kind)?.0, ), + TCA_STATS => TcAttribute::Stats(TcStats::parse( + &TcStatsBuffer::new_checked(payload)?, + )?), + TCA_XSTATS => { + TcAttribute::Xstats(TcXstats::parse_with_param(buf, kind)?) + } TCA_RATE => TcAttribute::Rate(payload.to_vec()), TCA_FCNT => TcAttribute::Fcnt(payload.to_vec()), TCA_STATS2 => { let mut nlas = vec![]; for nla in NlasIterator::new(payload) { - let nla = nla.context("invalid TCA_STATS2")?; - nlas.push(TcStats2::parse_with_param(&nla, kind).context( - format!("failed to parse TCA_STATS2 for kind {kind}"), - )?); + nlas.push(TcStats2::parse_with_param(&nla?, kind)?) } TcAttribute::Stats2(nlas) } TCA_STAB => TcAttribute::Stab(payload.to_vec()), - TCA_CHAIN => TcAttribute::Chain( - parse_u32(payload).context("failed to parse TCA_CHAIN")?, - ), - TCA_HW_OFFLOAD => TcAttribute::HwOffload( - parse_u8(payload).context("failed to parse TCA_HW_OFFLOAD")?, - ), + TCA_CHAIN => TcAttribute::Chain(parse_u32(payload)?), + TCA_HW_OFFLOAD => TcAttribute::HwOffload(parse_u8(payload)?), TCA_DUMP_INVISIBLE => TcAttribute::DumpInvisible(true), - _ => TcAttribute::Other( - DefaultNla::parse(buf).context("failed to parse tc nla")?, - ), + _ => TcAttribute::Other(DefaultNla::parse(buf)?), }) } } diff --git a/src/tc/filters/cls_u32.rs b/src/tc/filters/cls_u32.rs index e4a4a585..288531ec 100644 --- a/src/tc/filters/cls_u32.rs +++ b/src/tc/filters/cls_u32.rs @@ -7,7 +7,6 @@ /// described below, are compared with the currently processed IP packet /// until the first match occurs, and then the associated action is /// performed. -use anyhow::Context; use byteorder::{ByteOrder, NativeEndian}; use netlink_packet_utils::{ nla::{DefaultNla, Nla, NlaBuffer, NlasIterator}, @@ -112,41 +111,26 @@ impl Nla for TcFilterU32Option { } } -impl<'a, T: AsRef<[u8]> + ?Sized> Parseable> - for TcFilterU32Option -{ - fn parse(buf: &NlaBuffer<&'a T>) -> Result { +impl + ?Sized> Parseable> for TcFilterU32Option { + type Error = DecodeError; + + fn parse(buf: &NlaBuffer<&T>) -> Result { let payload = buf.value(); Ok(match buf.kind() { - TCA_U32_CLASSID => Self::ClassId(TcHandle::from( - parse_u32(payload).context("failed to parse TCA_U32_UNSPEC")?, - )), - TCA_U32_HASH => Self::Hash( - parse_u32(payload).context("failed to parse TCA_U32_HASH")?, - ), - TCA_U32_LINK => Self::Link( - parse_u32(payload).context("failed to parse TCA_U32_LINK")?, - ), - TCA_U32_DIVISOR => Self::Divisor( - parse_u32(payload) - .context("failed to parse TCA_U32_DIVISOR")?, - ), - TCA_U32_SEL => Self::Selector( - TcU32Selector::parse( - &TcU32SelectorBuffer::new_checked(payload) - .context("invalid TCA_U32_SEL")?, - ) - .context("failed to parse TCA_U32_SEL")?, - ), + TCA_U32_CLASSID => { + Self::ClassId(TcHandle::from(parse_u32(payload)?)) + } + TCA_U32_HASH => Self::Hash(parse_u32(payload)?), + TCA_U32_LINK => Self::Link(parse_u32(payload)?), + TCA_U32_DIVISOR => Self::Divisor(parse_u32(payload)?), + TCA_U32_SEL => Self::Selector(TcU32Selector::parse( + &TcU32SelectorBuffer::new_checked(payload)?, + )?), TCA_U32_POLICE => Self::Police(payload.to_vec()), TCA_U32_ACT => { let mut acts = vec![]; for act in NlasIterator::new(payload) { - let act = act.context("invalid TCA_U32_ACT")?; - acts.push( - TcAction::parse(&act) - .context("failed to parse TCA_U32_ACT")?, - ); + acts.push(TcAction::parse(&act?)?); } Self::Action(acts) } @@ -154,11 +138,9 @@ impl<'a, T: AsRef<[u8]> + ?Sized> Parseable> TCA_U32_PCNT => Self::Pnct(payload.to_vec()), TCA_U32_MARK => Self::Mark(payload.to_vec()), TCA_U32_FLAGS => Self::Flags(TcU32OptionFlags::from_bits_retain( - parse_u32(payload).context("failed to parse TCA_U32_FLAGS")?, + parse_u32(payload)?, )), - _ => Self::Other( - DefaultNla::parse(buf).context("failed to parse u32 nla")?, - ), + _ => Self::Other(DefaultNla::parse(buf)?), }) } } @@ -248,7 +230,9 @@ impl Emitable for TcU32Selector { impl + ?Sized> Parseable> for TcU32Selector { - fn parse(buf: &TcU32SelectorBuffer<&T>) -> Result { + type Error = DecodeError; + + fn parse(buf: &TcU32SelectorBuffer<&T>) -> Result { let nkeys = buf.nkeys(); let mut keys = Vec::::with_capacity(nkeys.into()); let key_payload = buf.keys(); @@ -257,11 +241,8 @@ impl + ?Sized> Parseable> let keybuf = TcU32KeyBuffer::new_checked( &key_payload [(i * TC_U32_KEY_BUF_LEN)..(i + 1) * TC_U32_KEY_BUF_LEN], - ) - .context("invalid u32 key")?; - keys.push( - TcU32Key::parse(&keybuf).context("failed to parse u32 key")?, - ); + )?; + keys.push(TcU32Key::parse(&keybuf)?); } Ok(Self { @@ -308,7 +289,8 @@ impl Emitable for TcU32Key { } impl> Parseable> for TcU32Key { - fn parse(buf: &TcU32KeyBuffer) -> Result { + type Error = DecodeError; + fn parse(buf: &TcU32KeyBuffer) -> Result { Ok(Self { mask: buf.mask(), val: buf.val(), diff --git a/src/tc/filters/flower/core.rs b/src/tc/filters/flower/core.rs index a03bc0aa..bb3bfae4 100644 --- a/src/tc/filters/flower/core.rs +++ b/src/tc/filters/flower/core.rs @@ -3,7 +3,6 @@ use super::TcFilterFlowerMplsOption; use crate::ip::{parse_ipv4_addr, parse_ipv6_addr}; use crate::tc::TcAction; -use anyhow::Context; use byteorder::{BigEndian, ByteOrder, NativeEndian}; use netlink_packet_utils::{ nla::{DefaultNla, Nla, NlaBuffer, NlasIterator, NLA_F_NESTED}, @@ -128,13 +127,6 @@ fn parse_bytes_16(payload: &[u8]) -> Result<[u8; 16], DecodeError> { Ok(data) } -macro_rules! nla_err { - // Match rule that takes an argument expression - ($message:expr) => { - format!("failed to parse {} value", stringify!($message)) - }; -} - #[derive(Debug, PartialEq, Eq, Clone)] #[non_exhaustive] pub struct TcFilterFlower {} @@ -574,411 +566,226 @@ impl Nla for TcFilterFlowerOption { } } -impl<'a, T: AsRef<[u8]> + ?Sized> Parseable> +impl + ?Sized> Parseable> for TcFilterFlowerOption { - fn parse(buf: &NlaBuffer<&'a T>) -> Result { + type Error = DecodeError; + + fn parse(buf: &NlaBuffer<&T>) -> Result { let payload = buf.value(); Ok(match buf.kind() { // TCA_FLOWER_CLASSID => Self::ClassId(TcHandle::from( // parse_u32(payload).context("failed to parse // TCA_FLOWER_CLASSID")?, )), - TCA_FLOWER_INDEV => Self::InDev( - parse_u32(payload).context(nla_err!(TCA_FLOWER_INDEV))?, - ), + TCA_FLOWER_INDEV => Self::InDev(parse_u32(payload)?), TCA_FLOWER_ACT => { let mut acts = vec![]; for act in NlasIterator::new(payload) { - let act = act.context("invalid TCA_FLOWER_ACT")?; - acts.push( - TcAction::parse(&act) - .context(nla_err!(TCA_FLOWER_ACT))?, - ); + acts.push(TcAction::parse(&act?)?); } Self::Actions(acts) } - TCA_FLOWER_KEY_ETH_DST => Self::EthDst( - parse_mac(payload).context(nla_err!(TCA_FLOWER_KEY_ETH_DST))?, - ), - TCA_FLOWER_KEY_ETH_DST_MASK => Self::EthDstMask( - parse_mac(payload) - .context(nla_err!(TCA_FLOWER_KEY_ETH_DST_MASK))?, - ), - TCA_FLOWER_KEY_ETH_SRC => Self::EthSrc( - parse_mac(payload).context(nla_err!(TCA_FLOWER_KEY_ETH_SRC))?, - ), - TCA_FLOWER_KEY_ETH_SRC_MASK => Self::EthSrcMask( - parse_mac(payload) - .context(nla_err!(TCA_FLOWER_KEY_ETH_SRC_MASK))?, - ), - TCA_FLOWER_KEY_ETH_TYPE => Self::EthType( - parse_u16_be(payload) - .context(nla_err!(TCA_FLOWER_KEY_ETH_TYPE))?, - ), - TCA_FLOWER_KEY_IP_PROTO => Self::IpProto( - parse_u8(payload).context(nla_err!(TCA_FLOWER_KEY_IP_PROTO))?, - ), - TCA_FLOWER_KEY_IP_TTL => Self::IpTtl( - parse_u8(payload).context(nla_err!(TCA_FLOWER_KEY_IP_TTL))?, - ), - TCA_FLOWER_KEY_IP_TTL_MASK => Self::IpTtlMask( - parse_u8(payload) - .context(nla_err!(TCA_FLOWER_KEY_IP_TTL_MASK))?, - ), - TCA_FLOWER_KEY_IP_TOS => Self::IpTos( - parse_u8(payload).context(nla_err!(TCA_FLOWER_KEY_IP_TOS))?, - ), - TCA_FLOWER_KEY_IP_TOS_MASK => Self::IpTosMask( - parse_u8(payload) - .context(nla_err!(TCA_FLOWER_KEY_IP_TOS_MASK))?, - ), - TCA_FLOWER_KEY_IPV4_SRC => Self::Ipv4Src( - parse_ipv4_addr(payload) - .context(nla_err!(TCA_FLOWER_KEY_IPV4_SRC))?, - ), - TCA_FLOWER_KEY_IPV4_SRC_MASK => Self::Ipv4SrcMask( - parse_ipv4_addr(payload) - .context(nla_err!(TCA_FLOWER_KEY_IPV4_SRC_MASK))?, - ), - TCA_FLOWER_KEY_IPV4_DST => Self::Ipv4Dst( - parse_ipv4_addr(payload) - .context(nla_err!(TCA_FLOWER_KEY_IPV4_DST))?, - ), - TCA_FLOWER_KEY_IPV4_DST_MASK => Self::Ipv4DstMask( - parse_ipv4_addr(payload) - .context(nla_err!(TCA_FLOWER_KEY_IPV4_DST_MASK))?, - ), - TCA_FLOWER_KEY_IPV6_SRC => Self::Ipv6Src( - parse_ipv6_addr(payload) - .context(nla_err!(TCA_FLOWER_KEY_IPV6_SRC))?, - ), - TCA_FLOWER_KEY_IPV6_SRC_MASK => Self::Ipv6SrcMask( - parse_ipv6_addr(payload) - .context(nla_err!(TCA_FLOWER_KEY_IPV6_SRC_MASK))?, - ), - TCA_FLOWER_KEY_IPV6_DST => Self::Ipv6Dst( - parse_ipv6_addr(payload) - .context(nla_err!(TCA_FLOWER_KEY_IPV6_DST))?, - ), - TCA_FLOWER_KEY_IPV6_DST_MASK => Self::Ipv6DstMask( - parse_ipv6_addr(payload) - .context(nla_err!(TCA_FLOWER_KEY_IPV6_DST_MASK))?, - ), - TCA_FLOWER_KEY_TCP_SRC => Self::TcpSrc( - parse_u16_be(payload) - .context(nla_err!(TCA_FLOWER_KEY_TCP_SRC))?, - ), - TCA_FLOWER_KEY_TCP_DST => Self::TcpDst( - parse_u16_be(payload) - .context(nla_err!(TCA_FLOWER_KEY_TCP_DST))?, - ), - TCA_FLOWER_KEY_TCP_SRC_MASK => Self::TcpSrcMask( - parse_u16_be(payload) - .context(nla_err!(TCA_FLOWER_KEY_TCP_SRC_MASK))?, - ), - TCA_FLOWER_KEY_TCP_DST_MASK => Self::TcpDstMask( - parse_u16_be(payload) - .context(nla_err!(TCA_FLOWER_KEY_TCP_DST_MASK))?, - ), - TCA_FLOWER_KEY_UDP_SRC => Self::UdpSrc( - parse_u16_be(payload) - .context(nla_err!(TCA_FLOWER_KEY_UDP_SRC))?, - ), - TCA_FLOWER_KEY_UDP_DST => Self::UdpDst( - parse_u16_be(payload) - .context(nla_err!(TCA_FLOWER_KEY_UDP_DST))?, - ), - TCA_FLOWER_KEY_UDP_SRC_MASK => Self::UdpSrcMask( - parse_u16_be(payload) - .context(nla_err!(TCA_FLOWER_KEY_UDP_SRC_MASK))?, - ), - TCA_FLOWER_KEY_UDP_DST_MASK => Self::UdpDstMask( - parse_u16_be(payload) - .context(nla_err!(TCA_FLOWER_KEY_UDP_DST_MASK))?, - ), - TCA_FLOWER_KEY_SCTP_SRC => Self::SctpSrc( - parse_u16_be(payload) - .context(nla_err!(TCA_FLOWER_KEY_SCTP_SRC))?, - ), - TCA_FLOWER_KEY_SCTP_DST => Self::SctpDst( - parse_u16_be(payload) - .context(nla_err!(TCA_FLOWER_KEY_SCTP_DST))?, - ), - TCA_FLOWER_KEY_SCTP_SRC_MASK => Self::SctpSrcMask( - parse_u16_be(payload) - .context(nla_err!(TCA_FLOWER_KEY_SCTP_SRC_MASK))?, - ), - TCA_FLOWER_KEY_SCTP_DST_MASK => Self::SctpDstMask( - parse_u16_be(payload) - .context(nla_err!(TCA_FLOWER_KEY_SCTP_DST_MASK))?, - ), + TCA_FLOWER_KEY_ETH_DST => Self::EthDst(parse_mac(payload)?), + TCA_FLOWER_KEY_ETH_DST_MASK => { + Self::EthDstMask(parse_mac(payload)?) + } + TCA_FLOWER_KEY_ETH_SRC => Self::EthSrc(parse_mac(payload)?), + TCA_FLOWER_KEY_ETH_SRC_MASK => { + Self::EthSrcMask(parse_mac(payload)?) + } + TCA_FLOWER_KEY_ETH_TYPE => Self::EthType(parse_u16_be(payload)?), + TCA_FLOWER_KEY_IP_PROTO => Self::IpProto(parse_u8(payload)?), + TCA_FLOWER_KEY_IP_TTL => Self::IpTtl(parse_u8(payload)?), + TCA_FLOWER_KEY_IP_TTL_MASK => Self::IpTtlMask(parse_u8(payload)?), + TCA_FLOWER_KEY_IP_TOS => Self::IpTos(parse_u8(payload)?), + TCA_FLOWER_KEY_IP_TOS_MASK => Self::IpTosMask(parse_u8(payload)?), + TCA_FLOWER_KEY_IPV4_SRC => Self::Ipv4Src(parse_ipv4_addr(payload)?), + TCA_FLOWER_KEY_IPV4_SRC_MASK => { + Self::Ipv4SrcMask(parse_ipv4_addr(payload)?) + } + TCA_FLOWER_KEY_IPV4_DST => Self::Ipv4Dst(parse_ipv4_addr(payload)?), + TCA_FLOWER_KEY_IPV4_DST_MASK => { + Self::Ipv4DstMask(parse_ipv4_addr(payload)?) + } + TCA_FLOWER_KEY_IPV6_SRC => Self::Ipv6Src(parse_ipv6_addr(payload)?), + TCA_FLOWER_KEY_IPV6_SRC_MASK => { + Self::Ipv6SrcMask(parse_ipv6_addr(payload)?) + } + TCA_FLOWER_KEY_IPV6_DST => Self::Ipv6Dst(parse_ipv6_addr(payload)?), + TCA_FLOWER_KEY_IPV6_DST_MASK => { + Self::Ipv6DstMask(parse_ipv6_addr(payload)?) + } + TCA_FLOWER_KEY_TCP_SRC => Self::TcpSrc(parse_u16_be(payload)?), + TCA_FLOWER_KEY_TCP_DST => Self::TcpDst(parse_u16_be(payload)?), + TCA_FLOWER_KEY_TCP_SRC_MASK => { + Self::TcpSrcMask(parse_u16_be(payload)?) + } + TCA_FLOWER_KEY_TCP_DST_MASK => { + Self::TcpDstMask(parse_u16_be(payload)?) + } + TCA_FLOWER_KEY_UDP_SRC => Self::UdpSrc(parse_u16_be(payload)?), + TCA_FLOWER_KEY_UDP_DST => Self::UdpDst(parse_u16_be(payload)?), + TCA_FLOWER_KEY_UDP_SRC_MASK => { + Self::UdpSrcMask(parse_u16_be(payload)?) + } + TCA_FLOWER_KEY_UDP_DST_MASK => { + Self::UdpDstMask(parse_u16_be(payload)?) + } + TCA_FLOWER_KEY_SCTP_SRC => Self::SctpSrc(parse_u16_be(payload)?), + TCA_FLOWER_KEY_SCTP_DST => Self::SctpDst(parse_u16_be(payload)?), + TCA_FLOWER_KEY_SCTP_SRC_MASK => { + Self::SctpSrcMask(parse_u16_be(payload)?) + } + TCA_FLOWER_KEY_SCTP_DST_MASK => { + Self::SctpDstMask(parse_u16_be(payload)?) + } - TCA_FLOWER_FLAGS => Self::Flags( - parse_u32(payload).context(nla_err!(TCA_FLOWER_FLAGS))?, - ), + TCA_FLOWER_FLAGS => Self::Flags(parse_u32(payload)?), - TCA_FLOWER_KEY_VLAN_ID => Self::VlanId( - parse_u16(payload).context(nla_err!(TCA_FLOWER_KEY_VLAN_ID))?, - ), - TCA_FLOWER_KEY_VLAN_PRIO => Self::VlanPrio( - parse_u8(payload) - .context(nla_err!(TCA_FLOWER_KEY_VLAN_PRIO))?, - ), - TCA_FLOWER_KEY_VLAN_ETH_TYPE => Self::VlanEthType( - parse_u16_be(payload) - .context(nla_err!(TCA_FLOWER_KEY_VLAN_ETH_TYPE))?, - ), - TCA_FLOWER_KEY_CVLAN_ID => Self::CvlanId( - parse_u16(payload) - .context(nla_err!(TCA_FLOWER_KEY_CVLAN_ID))?, - ), - TCA_FLOWER_KEY_CVLAN_PRIO => Self::CvlanPrio( - parse_u8(payload) - .context(nla_err!(TCA_FLOWER_KEY_CVLAN_PRIO))?, - ), - TCA_FLOWER_KEY_CVLAN_ETH_TYPE => Self::CvlanEthType( - parse_u16_be(payload) - .context(nla_err!(TCA_FLOWER_KEY_CVLAN_ETH_TYPE))?, - ), - TCA_FLOWER_KEY_ENC_KEY_ID => Self::EncKeyId( - parse_u32_be(payload) - .context(nla_err!(TCA_FLOWER_KEY_ENC_KEY_ID))?, - ), - TCA_FLOWER_KEY_ENC_UDP_SRC_PORT => Self::EncKeyUdpSrcPort( - parse_u16_be(payload) - .context(nla_err!(TCA_FLOWER_KEY_ENC_UDP_SRC_PORT))?, - ), - TCA_FLOWER_KEY_ENC_UDP_SRC_PORT_MASK => Self::EncKeyUdpSrcPortMask( - parse_u16_be(payload) - .context(nla_err!(TCA_FLOWER_KEY_ENC_UDP_SRC_PORT_MASK))?, - ), - TCA_FLOWER_KEY_ENC_UDP_DST_PORT => Self::EncKeyUdpDstPort( - parse_u16_be(payload) - .context(nla_err!(TCA_FLOWER_KEY_ENC_UDP_DST_PORT))?, - ), - TCA_FLOWER_KEY_ENC_UDP_DST_PORT_MASK => Self::EncKeyUdpDstPortMask( - parse_u16_be(payload) - .context(nla_err!(TCA_FLOWER_KEY_ENC_UDP_DST_PORT_MASK))?, - ), - TCA_FLOWER_KEY_ICMPV4_CODE => Self::Icmpv4Code( - parse_u8(payload) - .context(nla_err!(TCA_FLOWER_KEY_ICMPV4_CODE))?, - ), - TCA_FLOWER_KEY_ICMPV4_CODE_MASK => Self::Icmpv4CodeMask( - parse_u8(payload) - .context(nla_err!(TCA_FLOWER_KEY_ICMPV4_CODE_MASK))?, - ), - TCA_FLOWER_KEY_ICMPV4_TYPE => Self::Icmpv4Type( - parse_u8(payload) - .context(nla_err!(TCA_FLOWER_KEY_ICMPV4_TYPE))?, - ), - TCA_FLOWER_KEY_ICMPV4_TYPE_MASK => Self::Icmpv4TypeMask( - parse_u8(payload) - .context(nla_err!(TCA_FLOWER_KEY_ICMPV4_TYPE_MASK))?, - ), - TCA_FLOWER_KEY_ICMPV6_CODE => Self::Icmpv6Code( - parse_u8(payload) - .context(nla_err!(TCA_FLOWER_KEY_ICMPV6_CODE))?, - ), - TCA_FLOWER_KEY_ICMPV6_CODE_MASK => Self::Icmpv6CodeMask( - parse_u8(payload) - .context(nla_err!(TCA_FLOWER_KEY_ICMPV6_CODE_MASK))?, - ), - TCA_FLOWER_KEY_ICMPV6_TYPE => Self::Icmpv6Type( - parse_u8(payload) - .context(nla_err!(TCA_FLOWER_KEY_ICMPV6_TYPE))?, - ), - TCA_FLOWER_KEY_ICMPV6_TYPE_MASK => Self::Icmpv6TypeMask( - parse_u8(payload) - .context(nla_err!(TCA_FLOWER_KEY_ICMPV6_TYPE_MASK))?, - ), - TCA_FLOWER_KEY_ARP_SIP => Self::ArpSip( - parse_ipv4_addr(payload) - .context(nla_err!(TCA_FLOWER_KEY_ARP_SIP))?, - ), - TCA_FLOWER_KEY_ARP_SIP_MASK => Self::ArpSipMask( - parse_ipv4_addr(payload) - .context(nla_err!(TCA_FLOWER_KEY_ARP_SIP_MASK))?, - ), - TCA_FLOWER_KEY_ARP_TIP => Self::ArpTip( - parse_ipv4_addr(payload) - .context(nla_err!(TCA_FLOWER_KEY_ARP_TIP))?, - ), - TCA_FLOWER_KEY_ARP_TIP_MASK => Self::ArpTipMask( - parse_ipv4_addr(payload) - .context(nla_err!(TCA_FLOWER_KEY_ARP_TIP_MASK))?, - ), - TCA_FLOWER_KEY_ARP_OP => Self::ArpOp( - parse_u8(payload).context(nla_err!(TCA_FLOWER_KEY_ARP_OP))?, - ), - TCA_FLOWER_KEY_ARP_OP_MASK => Self::ArpOpMask( - parse_u8(payload) - .context(nla_err!(TCA_FLOWER_KEY_ARP_OP_MASK))?, - ), - TCA_FLOWER_KEY_ARP_SHA => Self::ArpSha( - parse_mac(payload).context(nla_err!(TCA_FLOWER_KEY_ARP_SHA))?, - ), - TCA_FLOWER_KEY_ARP_SHA_MASK => Self::ArpShaMask( - parse_mac(payload) - .context(nla_err!(TCA_FLOWER_KEY_ARP_SHA_MASK))?, - ), - TCA_FLOWER_KEY_ARP_THA => Self::ArpTha( - parse_mac(payload).context(nla_err!(TCA_FLOWER_KEY_ARP_THA))?, - ), - TCA_FLOWER_KEY_ARP_THA_MASK => Self::ArpThaMask( - parse_mac(payload) - .context(nla_err!(TCA_FLOWER_KEY_ARP_THA_MASK))?, - ), - TCA_FLOWER_KEY_MPLS_TTL => Self::MplsTtl( - parse_u8(payload).context(nla_err!(TCA_FLOWER_KEY_MPLS_TTL))?, - ), - TCA_FLOWER_KEY_MPLS_BOS => Self::MplsBos( - parse_u8(payload).context(nla_err!(TCA_FLOWER_KEY_MPLS_BOS))?, - ), - TCA_FLOWER_KEY_MPLS_TC => Self::MplsTc( - parse_u8(payload).context(nla_err!(TCA_FLOWER_KEY_MPLS_TC))?, - ), - TCA_FLOWER_KEY_MPLS_LABEL => Self::MplsLabel( - parse_u32(payload) - .context(nla_err!(TCA_FLOWER_KEY_MPLS_LABEL))?, - ), - TCA_FLOWER_KEY_TCP_FLAGS => Self::TcpFlags( - parse_u16_be(payload) - .context(nla_err!(TCA_FLOWER_KEY_TCP_FLAGS))?, - ), - TCA_FLOWER_KEY_TCP_FLAGS_MASK => Self::TcpFlagsMask( - parse_u16_be(payload) - .context(nla_err!(TCA_FLOWER_KEY_TCP_FLAGS_MASK))?, - ), - TCA_FLOWER_KEY_FLAGS => Self::KeyFlags( - parse_u32_be(payload) - .context(nla_err!(TCA_FLOWER_KEY_FLAGS))?, - ), - TCA_FLOWER_KEY_FLAGS_MASK => Self::KeyFlagsMask( - parse_u32_be(payload) - .context(nla_err!(TCA_FLOWER_KEY_FLAGS_MASK))?, - ), + TCA_FLOWER_KEY_VLAN_ID => Self::VlanId(parse_u16(payload)?), + TCA_FLOWER_KEY_VLAN_PRIO => Self::VlanPrio(parse_u8(payload)?), + TCA_FLOWER_KEY_VLAN_ETH_TYPE => { + Self::VlanEthType(parse_u16_be(payload)?) + } + TCA_FLOWER_KEY_CVLAN_ID => Self::CvlanId(parse_u16(payload)?), + TCA_FLOWER_KEY_CVLAN_PRIO => Self::CvlanPrio(parse_u8(payload)?), + TCA_FLOWER_KEY_CVLAN_ETH_TYPE => { + Self::CvlanEthType(parse_u16_be(payload)?) + } + TCA_FLOWER_KEY_ENC_KEY_ID => Self::EncKeyId(parse_u32_be(payload)?), + TCA_FLOWER_KEY_ENC_UDP_SRC_PORT => { + Self::EncKeyUdpSrcPort(parse_u16_be(payload)?) + } + TCA_FLOWER_KEY_ENC_UDP_SRC_PORT_MASK => { + Self::EncKeyUdpSrcPortMask(parse_u16_be(payload)?) + } + TCA_FLOWER_KEY_ENC_UDP_DST_PORT => { + Self::EncKeyUdpDstPort(parse_u16_be(payload)?) + } + TCA_FLOWER_KEY_ENC_UDP_DST_PORT_MASK => { + Self::EncKeyUdpDstPortMask(parse_u16_be(payload)?) + } + TCA_FLOWER_KEY_ICMPV4_CODE => Self::Icmpv4Code(parse_u8(payload)?), + TCA_FLOWER_KEY_ICMPV4_CODE_MASK => { + Self::Icmpv4CodeMask(parse_u8(payload)?) + } + TCA_FLOWER_KEY_ICMPV4_TYPE => Self::Icmpv4Type(parse_u8(payload)?), + TCA_FLOWER_KEY_ICMPV4_TYPE_MASK => { + Self::Icmpv4TypeMask(parse_u8(payload)?) + } + TCA_FLOWER_KEY_ICMPV6_CODE => Self::Icmpv6Code(parse_u8(payload)?), + TCA_FLOWER_KEY_ICMPV6_CODE_MASK => { + Self::Icmpv6CodeMask(parse_u8(payload)?) + } + TCA_FLOWER_KEY_ICMPV6_TYPE => Self::Icmpv6Type(parse_u8(payload)?), + TCA_FLOWER_KEY_ICMPV6_TYPE_MASK => { + Self::Icmpv6TypeMask(parse_u8(payload)?) + } + TCA_FLOWER_KEY_ARP_SIP => Self::ArpSip(parse_ipv4_addr(payload)?), + TCA_FLOWER_KEY_ARP_SIP_MASK => { + Self::ArpSipMask(parse_ipv4_addr(payload)?) + } + TCA_FLOWER_KEY_ARP_TIP => Self::ArpTip(parse_ipv4_addr(payload)?), + TCA_FLOWER_KEY_ARP_TIP_MASK => { + Self::ArpTipMask(parse_ipv4_addr(payload)?) + } + TCA_FLOWER_KEY_ARP_OP => Self::ArpOp(parse_u8(payload)?), + TCA_FLOWER_KEY_ARP_OP_MASK => Self::ArpOpMask(parse_u8(payload)?), + TCA_FLOWER_KEY_ARP_SHA => Self::ArpSha(parse_mac(payload)?), + TCA_FLOWER_KEY_ARP_SHA_MASK => { + Self::ArpShaMask(parse_mac(payload)?) + } + TCA_FLOWER_KEY_ARP_THA => Self::ArpTha(parse_mac(payload)?), + TCA_FLOWER_KEY_ARP_THA_MASK => { + Self::ArpThaMask(parse_mac(payload)?) + } + TCA_FLOWER_KEY_MPLS_TTL => Self::MplsTtl(parse_u8(payload)?), + TCA_FLOWER_KEY_MPLS_BOS => Self::MplsBos(parse_u8(payload)?), + TCA_FLOWER_KEY_MPLS_TC => Self::MplsTc(parse_u8(payload)?), + TCA_FLOWER_KEY_MPLS_LABEL => Self::MplsLabel(parse_u32(payload)?), + TCA_FLOWER_KEY_TCP_FLAGS => Self::TcpFlags(parse_u16_be(payload)?), + TCA_FLOWER_KEY_TCP_FLAGS_MASK => { + Self::TcpFlagsMask(parse_u16_be(payload)?) + } + TCA_FLOWER_KEY_FLAGS => Self::KeyFlags(parse_u32_be(payload)?), + TCA_FLOWER_KEY_FLAGS_MASK => { + Self::KeyFlagsMask(parse_u32_be(payload)?) + } - TCA_FLOWER_KEY_ENC_IP_TTL => Self::EncKeyIpTtl( - parse_u8(payload) - .context(nla_err!(TCA_FLOWER_KEY_ENC_IP_TTL))?, - ), - TCA_FLOWER_KEY_ENC_IP_TTL_MASK => Self::EncKeyIpTtlMask( - parse_u8(payload) - .context(nla_err!(TCA_FLOWER_KEY_ENC_IP_TTL_MASK))?, - ), - TCA_FLOWER_KEY_ENC_IP_TOS => Self::EncKeyIpTos( - parse_u8(payload) - .context(nla_err!(TCA_FLOWER_KEY_ENC_IP_TOS))?, - ), - TCA_FLOWER_KEY_ENC_IP_TOS_MASK => Self::EncKeyIpTosMask( - parse_u8(payload) - .context(nla_err!(TCA_FLOWER_KEY_ENC_IP_TOS_MASK))?, - ), - TCA_FLOWER_KEY_ENC_IPV4_SRC => Self::EncKeyIpv4Src( - parse_ipv4_addr(payload) - .context(nla_err!(TCA_FLOWER_KEY_ENC_IPV4_SRC))?, - ), - TCA_FLOWER_KEY_ENC_IPV4_SRC_MASK => Self::EncKeyIpv4SrcMask( - parse_ipv4_addr(payload) - .context(nla_err!(TCA_FLOWER_KEY_ENC_IPV4_SRC_MASK))?, - ), - TCA_FLOWER_KEY_ENC_IPV4_DST => Self::EncKeyIpv4Dst( - parse_ipv4_addr(payload) - .context(nla_err!(TCA_FLOWER_KEY_ENC_IPV4_DST))?, - ), - TCA_FLOWER_KEY_ENC_IPV4_DST_MASK => Self::EncKeyIpv4DstMask( - parse_ipv4_addr(payload) - .context(nla_err!(TCA_FLOWER_KEY_ENC_IPV4_DST_MASK))?, - ), - TCA_FLOWER_KEY_ENC_IPV6_SRC => Self::EncKeyIpv6Src( - parse_ipv6_addr(payload) - .context(nla_err!(TCA_FLOWER_KEY_ENC_IPV6_SRC))?, - ), - TCA_FLOWER_KEY_ENC_IPV6_SRC_MASK => Self::EncKeyIpv6SrcMask( - parse_ipv6_addr(payload) - .context(nla_err!(TCA_FLOWER_KEY_ENC_IPV6_SRC_MASK))?, - ), - TCA_FLOWER_KEY_ENC_IPV6_DST => Self::EncKeyIpv6Dst( - parse_ipv6_addr(payload) - .context(nla_err!(TCA_FLOWER_KEY_ENC_IPV6_DST))?, - ), - TCA_FLOWER_KEY_ENC_IPV6_DST_MASK => Self::EncKeyIpv6DstMask( - parse_ipv6_addr(payload) - .context(nla_err!(TCA_FLOWER_KEY_ENC_IPV6_DST_MASK))?, - ), - TCA_FLOWER_IN_HW_COUNT => Self::InHwCount( - parse_u32(payload).context(nla_err!(TCA_FLOWER_IN_HW_COUNT))?, - ), - TCA_FLOWER_KEY_PORT_SRC_MIN => Self::PortSrcMin( - parse_u16_be(payload) - .context(nla_err!(TCA_FLOWER_KEY_PORT_SRC_MIN))?, - ), - TCA_FLOWER_KEY_PORT_SRC_MAX => Self::PortSrcMax( - parse_u16_be(payload) - .context(nla_err!(TCA_FLOWER_KEY_PORT_SRC_MAX))?, - ), - TCA_FLOWER_KEY_PORT_DST_MIN => Self::PortDstMin( - parse_u16_be(payload) - .context(nla_err!(TCA_FLOWER_KEY_PORT_DST_MIN))?, - ), - TCA_FLOWER_KEY_PORT_DST_MAX => Self::PortDstMax( - parse_u16_be(payload) - .context(nla_err!(TCA_FLOWER_KEY_PORT_DST_MAX))?, - ), - TCA_FLOWER_KEY_CT_STATE => Self::CtState( - parse_u16(payload) - .context(nla_err!(TCA_FLOWER_KEY_CT_STATE))?, - ), - TCA_FLOWER_KEY_CT_STATE_MASK => Self::CtStateMask( - parse_u16(payload) - .context(nla_err!(TCA_FLOWER_KEY_CT_STATE_MASK))?, - ), - TCA_FLOWER_KEY_CT_ZONE => Self::CtZone( - parse_u16(payload).context(nla_err!(TCA_FLOWER_KEY_CT_ZONE))?, - ), - TCA_FLOWER_KEY_CT_ZONE_MASK => Self::CtZoneMask( - parse_u16(payload) - .context(nla_err!(TCA_FLOWER_KEY_CT_ZONE_MASK))?, - ), - TCA_FLOWER_KEY_CT_MARK => Self::CtMark( - parse_u32(payload).context(nla_err!(TCA_FLOWER_KEY_CT_MARK))?, - ), - TCA_FLOWER_KEY_CT_MARK_MASK => Self::CtMarkMask( - parse_u32(payload) - .context(nla_err!(TCA_FLOWER_KEY_CT_MARK_MASK))?, - ), - TCA_FLOWER_KEY_CT_LABELS => Self::CtLabels( - parse_bytes_16(payload) - .context(nla_err!(TCA_FLOWER_KEY_CT_LABELS))?, - ), - TCA_FLOWER_KEY_CT_LABELS_MASK => Self::CtLabelsMask( - parse_bytes_16(payload) - .context(nla_err!(TCA_FLOWER_KEY_CT_LABELS_MASK))?, - ), + TCA_FLOWER_KEY_ENC_IP_TTL => Self::EncKeyIpTtl(parse_u8(payload)?), + TCA_FLOWER_KEY_ENC_IP_TTL_MASK => { + Self::EncKeyIpTtlMask(parse_u8(payload)?) + } + TCA_FLOWER_KEY_ENC_IP_TOS => Self::EncKeyIpTos(parse_u8(payload)?), + TCA_FLOWER_KEY_ENC_IP_TOS_MASK => { + Self::EncKeyIpTosMask(parse_u8(payload)?) + } + TCA_FLOWER_KEY_ENC_IPV4_SRC => { + Self::EncKeyIpv4Src(parse_ipv4_addr(payload)?) + } + TCA_FLOWER_KEY_ENC_IPV4_SRC_MASK => { + Self::EncKeyIpv4SrcMask(parse_ipv4_addr(payload)?) + } + TCA_FLOWER_KEY_ENC_IPV4_DST => { + Self::EncKeyIpv4Dst(parse_ipv4_addr(payload)?) + } + TCA_FLOWER_KEY_ENC_IPV4_DST_MASK => { + Self::EncKeyIpv4DstMask(parse_ipv4_addr(payload)?) + } + TCA_FLOWER_KEY_ENC_IPV6_SRC => { + Self::EncKeyIpv6Src(parse_ipv6_addr(payload)?) + } + TCA_FLOWER_KEY_ENC_IPV6_SRC_MASK => { + Self::EncKeyIpv6SrcMask(parse_ipv6_addr(payload)?) + } + TCA_FLOWER_KEY_ENC_IPV6_DST => { + Self::EncKeyIpv6Dst(parse_ipv6_addr(payload)?) + } + TCA_FLOWER_KEY_ENC_IPV6_DST_MASK => { + Self::EncKeyIpv6DstMask(parse_ipv6_addr(payload)?) + } + TCA_FLOWER_IN_HW_COUNT => Self::InHwCount(parse_u32(payload)?), + TCA_FLOWER_KEY_PORT_SRC_MIN => { + Self::PortSrcMin(parse_u16_be(payload)?) + } + TCA_FLOWER_KEY_PORT_SRC_MAX => { + Self::PortSrcMax(parse_u16_be(payload)?) + } + TCA_FLOWER_KEY_PORT_DST_MIN => { + Self::PortDstMin(parse_u16_be(payload)?) + } + TCA_FLOWER_KEY_PORT_DST_MAX => { + Self::PortDstMax(parse_u16_be(payload)?) + } + TCA_FLOWER_KEY_CT_STATE => Self::CtState(parse_u16(payload)?), + TCA_FLOWER_KEY_CT_STATE_MASK => { + Self::CtStateMask(parse_u16(payload)?) + } + TCA_FLOWER_KEY_CT_ZONE => Self::CtZone(parse_u16(payload)?), + TCA_FLOWER_KEY_CT_ZONE_MASK => { + Self::CtZoneMask(parse_u16(payload)?) + } + TCA_FLOWER_KEY_CT_MARK => Self::CtMark(parse_u32(payload)?), + TCA_FLOWER_KEY_CT_MARK_MASK => { + Self::CtMarkMask(parse_u32(payload)?) + } + TCA_FLOWER_KEY_CT_LABELS => { + Self::CtLabels(parse_bytes_16(payload)?) + } + TCA_FLOWER_KEY_CT_LABELS_MASK => { + Self::CtLabelsMask(parse_bytes_16(payload)?) + } TCA_FLOWER_KEY_MPLS_OPTS => { let mut nlas = vec![]; for nla in NlasIterator::new(payload) { - let nla = - nla.context("invalid TCA_FLOWER_KEY_MPLS_OPTS nla")?; - nlas.push( - TcFilterFlowerMplsOption::parse(&nla) - .context(nla_err!(TCA_FLOWER_KEY_MPLS_OPTS))?, - ) + nlas.push(TcFilterFlowerMplsOption::parse(&nla?)?) } Self::MplsOpts(nlas) } - TCA_FLOWER_KEY_HASH => Self::KeyHash( - parse_u32(payload).context(nla_err!(TCA_FLOWER_KEY_HASH))?, - ), - TCA_FLOWER_KEY_HASH_MASK => Self::KeyHashMask( - parse_u32(payload) - .context(nla_err!(TCA_FLOWER_KEY_HASH_MASK))?, - ), + TCA_FLOWER_KEY_HASH => Self::KeyHash(parse_u32(payload)?), + TCA_FLOWER_KEY_HASH_MASK => Self::KeyHashMask(parse_u32(payload)?), - _ => Self::Other( - DefaultNla::parse(buf).context("failed to parse flower nla")?, - ), + _ => Self::Other(DefaultNla::parse(buf)?), }) } } diff --git a/src/tc/filters/flower/mpls.rs b/src/tc/filters/flower/mpls.rs index 22768352..52e4d5aa 100644 --- a/src/tc/filters/flower/mpls.rs +++ b/src/tc/filters/flower/mpls.rs @@ -1,6 +1,5 @@ // SPDX-License-Identifier: MIT -use anyhow::Context; use byteorder::{ByteOrder, NativeEndian}; use netlink_packet_utils::{ nla::{DefaultNla, Nla, NlaBuffer, NlasIterator, NLA_F_NESTED}, @@ -9,13 +8,6 @@ use netlink_packet_utils::{ DecodeError, Parseable, }; -macro_rules! nla_err { - // Match rule that takes an argument expression - ($message:expr) => { - format!("failed to parse {} value", stringify!($message)) - }; -} - /* * NLA layout: * TCA_FLOWER_KEY_MPLS_OPTS @@ -60,27 +52,21 @@ impl Nla for TcFilterFlowerMplsOption { } } -impl<'a, T: AsRef<[u8]> + ?Sized> Parseable> +impl + ?Sized> Parseable> for TcFilterFlowerMplsOption { - fn parse(buf: &NlaBuffer<&'a T>) -> Result { + type Error = DecodeError; + + fn parse(buf: &NlaBuffer<&T>) -> Result { Ok(match buf.kind() { TCA_FLOWER_KEY_MPLS_OPT_LSE => { let mut nlas = vec![]; for nla in NlasIterator::new(buf.value()) { - let nla = - nla.context(nla_err!(TCA_FLOWER_KEY_MPLS_OPT_LSE))?; - nlas.push( - TcFilterFlowerMplsLseOption::parse(&nla) - .context(nla_err!(TCA_FLOWER_KEY_MPLS_OPT_LSE))?, - ) + nlas.push(TcFilterFlowerMplsLseOption::parse(&nla?)?) } Self::Lse(nlas) } - _ => Self::Other( - DefaultNla::parse(buf) - .context("failed to parse mpls option nla")?, - ), + _ => Self::Other(DefaultNla::parse(buf)?), }) } } @@ -141,38 +127,27 @@ impl Nla for TcFilterFlowerMplsLseOption { } } -impl<'a, T: AsRef<[u8]> + ?Sized> Parseable> +impl + ?Sized> Parseable> for TcFilterFlowerMplsLseOption { - fn parse(buf: &NlaBuffer<&'a T>) -> Result { + type Error = DecodeError; + + fn parse(buf: &NlaBuffer<&T>) -> Result { let payload = buf.value(); Ok(match buf.kind() { - TCA_FLOWER_KEY_MPLS_OPT_LSE_DEPTH => Self::LseDepth( - parse_u8(payload) - .context(nla_err!(TCA_FLOWER_KEY_MPLS_OPT_LSE_DEPTH))?, - ), - TCA_FLOWER_KEY_MPLS_OPT_LSE_TTL => Self::LseTtl( - parse_u8(payload) - .context(nla_err!(TCA_FLOWER_KEY_MPLS_OPT_LSE_TTL))?, - ), - TCA_FLOWER_KEY_MPLS_OPT_LSE_BOS => Self::LseBos( - parse_u8(payload) - .context(nla_err!(TCA_FLOWER_KEY_MPLS_OPT_LSE_BOS))?, - ), - - TCA_FLOWER_KEY_MPLS_OPT_LSE_TC => Self::LseTc( - parse_u8(payload) - .context(nla_err!(TCA_FLOWER_KEY_MPLS_OPT_LSE_TC))?, - ), - - TCA_FLOWER_KEY_MPLS_OPT_LSE_LABEL => Self::LseLabel( - parse_u32(payload) - .context(nla_err!(TCA_FLOWER_KEY_MPLS_OPT_LSE_LABEL))?, - ), - - _ => Self::Other( - DefaultNla::parse(buf).context("failed to parse mpls nla")?, - ), + TCA_FLOWER_KEY_MPLS_OPT_LSE_DEPTH => { + Self::LseDepth(parse_u8(payload)?) + } + TCA_FLOWER_KEY_MPLS_OPT_LSE_TTL => Self::LseTtl(parse_u8(payload)?), + TCA_FLOWER_KEY_MPLS_OPT_LSE_BOS => Self::LseBos(parse_u8(payload)?), + + TCA_FLOWER_KEY_MPLS_OPT_LSE_TC => Self::LseTc(parse_u8(payload)?), + + TCA_FLOWER_KEY_MPLS_OPT_LSE_LABEL => { + Self::LseLabel(parse_u32(payload)?) + } + + _ => Self::Other(DefaultNla::parse(buf)?), }) } } diff --git a/src/tc/filters/matchall.rs b/src/tc/filters/matchall.rs index 280f8a24..37c9b6fc 100644 --- a/src/tc/filters/matchall.rs +++ b/src/tc/filters/matchall.rs @@ -3,7 +3,6 @@ /// Matchall filter /// /// Matches all packets and performs an action on them. -use anyhow::Context; use byteorder::{ByteOrder, NativeEndian}; use netlink_packet_utils::{ nla::{DefaultNla, Nla, NlaBuffer, NlasIterator}, @@ -71,33 +70,22 @@ impl Nla for TcFilterMatchAllOption { impl<'a, T: AsRef<[u8]> + ?Sized> Parseable> for TcFilterMatchAllOption { - fn parse(buf: &NlaBuffer<&'a T>) -> Result { + type Error = DecodeError; + + fn parse(buf: &NlaBuffer<&'a T>) -> Result { let payload = buf.value(); Ok(match buf.kind() { - TCA_MATCHALL_CLASSID => Self::ClassId( - parse_u32(payload) - .context("failed to parse TCA_MATCHALL_UNSPEC")? - .into(), - ), + TCA_MATCHALL_CLASSID => Self::ClassId(parse_u32(payload)?.into()), TCA_MATCHALL_ACT => { let mut acts = vec![]; for act in NlasIterator::new(payload) { - let act = act.context("invalid TCA_MATCHALL_ACT")?; - acts.push( - TcAction::parse(&act) - .context("failed to parse TCA_MATCHALL_ACT")?, - ); + acts.push(TcAction::parse(&act?)?); } Self::Action(acts) } TCA_MATCHALL_PCNT => Self::Pnct(payload.to_vec()), - TCA_MATCHALL_FLAGS => Self::Flags( - parse_u32(payload) - .context("failed to parse TCA_MATCHALL_FLAGS")?, - ), - _ => Self::Other( - DefaultNla::parse(buf).context("failed to parse u32 nla")?, - ), + TCA_MATCHALL_FLAGS => Self::Flags(parse_u32(payload)?), + _ => Self::Other(DefaultNla::parse(buf)?), }) } } diff --git a/src/tc/header.rs b/src/tc/header.rs index 1b4dc824..cab1fa7c 100644 --- a/src/tc/header.rs +++ b/src/tc/header.rs @@ -1,7 +1,7 @@ // SPDX-License-Identifier: MIT use netlink_packet_utils::{ - nla::{NlaBuffer, NlasIterator}, + nla::{NlaBuffer, NlaError, NlasIterator}, traits::{Emitable, Parseable}, DecodeError, }; @@ -24,7 +24,7 @@ buffer!(TcMessageBuffer(TC_HEADER_LEN) { impl<'a, T: AsRef<[u8]> + ?Sized> TcMessageBuffer<&'a T> { pub fn attributes( &self, - ) -> impl Iterator, DecodeError>> { + ) -> impl Iterator, NlaError>> { NlasIterator::new(self.payload()) } } @@ -61,7 +61,9 @@ impl Emitable for TcHeader { } impl> Parseable> for TcHeader { - fn parse(buf: &TcMessageBuffer) -> Result { + type Error = DecodeError; + + fn parse(buf: &TcMessageBuffer) -> Result { Ok(Self { family: buf.family().into(), index: buf.index(), diff --git a/src/tc/message.rs b/src/tc/message.rs index 00a6d7bf..9823f189 100644 --- a/src/tc/message.rs +++ b/src/tc/message.rs @@ -1,6 +1,5 @@ // SPDX-License-Identifier: MIT -use anyhow::Context; use netlink_packet_utils::{ traits::{Emitable, Parseable, ParseableParametrized}, DecodeError, @@ -36,21 +35,21 @@ impl TcMessage { } } -impl<'a, T: AsRef<[u8]> + 'a> Parseable> for TcMessage { - fn parse(buf: &TcMessageBuffer<&'a T>) -> Result { +impl> Parseable> for TcMessage { + type Error = DecodeError; + + fn parse(buf: &TcMessageBuffer<&T>) -> Result { Ok(Self { - header: TcHeader::parse(buf) - .context("failed to parse tc message header")?, - attributes: Vec::::parse(buf) - .context("failed to parse tc message NLAs")?, + header: TcHeader::parse(buf)?, + attributes: Vec::::parse(buf)?, }) } } -impl<'a, T: AsRef<[u8]> + 'a> Parseable> - for Vec -{ - fn parse(buf: &TcMessageBuffer<&'a T>) -> Result { +impl> Parseable> for Vec { + type Error = DecodeError; + + fn parse(buf: &TcMessageBuffer<&T>) -> Result { let mut attributes = vec![]; let mut kind = String::new(); diff --git a/src/tc/options.rs b/src/tc/options.rs index a13c38ce..1bc6ff8f 100644 --- a/src/tc/options.rs +++ b/src/tc/options.rs @@ -1,6 +1,5 @@ // SPDX-License-Identifier: MIT -use anyhow::Context; use netlink_packet_utils::{ nla::{DefaultNla, Nla, NlaBuffer, NlasIterator}, traits::{Parseable, ParseableParametrized}, @@ -63,37 +62,29 @@ impl Nla for TcOption { } } -impl<'a, T> ParseableParametrized, &str> for TcOption +impl ParseableParametrized, &str> for TcOption where T: AsRef<[u8]> + ?Sized, { + type Error = DecodeError; + fn parse_with_param( - buf: &NlaBuffer<&'a T>, + buf: &NlaBuffer<&T>, kind: &str, - ) -> Result { + ) -> Result { Ok(match kind { TcQdiscIngress::KIND => { - Self::Ingress(TcQdiscIngressOption::parse(buf).context( - "failed to parse ingress TCA_OPTIONS attributes", - )?) + Self::Ingress(TcQdiscIngressOption::parse(buf)?) + } + TcFilterFlower::KIND => { + Self::Flower(TcFilterFlowerOption::parse(buf)?) } - TcFilterFlower::KIND => Self::Flower( - TcFilterFlowerOption::parse(buf) - .context("failed to parse flower TCA_OPTIONS attributes")?, - ), TcQdiscFqCodel::KIND => { - Self::FqCodel(TcQdiscFqCodelOption::parse(buf).context( - "failed to parse fq_codel TCA_OPTIONS attributes", - )?) + Self::FqCodel(TcQdiscFqCodelOption::parse(buf)?) } - TcFilterU32::KIND => Self::U32( - TcFilterU32Option::parse(buf) - .context("failed to parse u32 TCA_OPTIONS attributes")?, - ), + TcFilterU32::KIND => Self::U32(TcFilterU32Option::parse(buf)?), TcFilterMatchAll::KIND => { - Self::MatchAll(TcFilterMatchAllOption::parse(buf).context( - "failed to parse matchall TCA_OPTIONS attributes", - )?) + Self::MatchAll(TcFilterMatchAllOption::parse(buf)?) } _ => Self::Other(DefaultNla::parse(buf)?), }) @@ -102,14 +93,16 @@ where pub(crate) struct VecTcOption(pub(crate) Vec); -impl<'a, T> ParseableParametrized, &str> for VecTcOption +impl ParseableParametrized, &str> for VecTcOption where T: AsRef<[u8]> + ?Sized, { + type Error = DecodeError; + fn parse_with_param( - buf: &NlaBuffer<&'a T>, + buf: &NlaBuffer<&T>, kind: &str, - ) -> Result { + ) -> Result { Ok(match kind { TcFilterU32::KIND | TcFilterMatchAll::KIND @@ -118,16 +111,7 @@ where | TcQdiscFqCodel::KIND => { let mut nlas = vec![]; for nla in NlasIterator::new(buf.value()) { - let nla = nla.context(format!( - "Invalid TCA_OPTIONS for kind: {kind}", - ))?; - nlas.push( - TcOption::parse_with_param(&nla, kind).context( - format!( - "Failed to parse TCA_OPTIONS for kind: {kind}", - ), - )?, - ) + nlas.push(TcOption::parse_with_param(&nla?, kind)?) } Self(nlas) } diff --git a/src/tc/qdiscs/fq_codel.rs b/src/tc/qdiscs/fq_codel.rs index a19484b4..b351707a 100644 --- a/src/tc/qdiscs/fq_codel.rs +++ b/src/tc/qdiscs/fq_codel.rs @@ -1,6 +1,5 @@ // SPDX-License-Identifier: MIT -use anyhow::Context; use byteorder::{ByteOrder, NativeEndian}; use netlink_packet_utils::{ nla::{DefaultNla, Nla, NlaBuffer}, @@ -32,7 +31,9 @@ pub enum TcFqCodelXstats { } impl + ?Sized> Parseable for TcFqCodelXstats { - fn parse(buf: &T) -> Result { + type Error = DecodeError; + + fn parse(buf: &T) -> Result { if buf.as_ref().len() < 4 { return Err(DecodeError::from(format!( "Invalid TcFqCodelXstats {:?}", @@ -117,7 +118,9 @@ buffer!(TcFqCodelQdStatsBuffer(TC_FQ_CODEL_QD_STATS_LEN) { }); impl> Parseable> for TcFqCodelQdStats { - fn parse(buf: &TcFqCodelQdStatsBuffer) -> Result { + type Error = DecodeError; + + fn parse(buf: &TcFqCodelQdStatsBuffer) -> Result { Ok(Self { maxpacket: buf.maxpacket(), drop_overlimit: buf.drop_overlimit(), @@ -172,7 +175,9 @@ buffer!(TcFqCodelClStatsBuffer(TC_FQ_CODEL_CL_STATS_LEN) { }); impl> Parseable> for TcFqCodelClStats { - fn parse(buf: &TcFqCodelClStatsBuffer) -> Result { + type Error = DecodeError; + + fn parse(buf: &TcFqCodelClStatsBuffer) -> Result { Ok(Self { deficit: buf.deficit(), ldelay: buf.ldelay(), @@ -285,58 +290,29 @@ impl Nla for TcQdiscFqCodelOption { impl<'a, T: AsRef<[u8]> + ?Sized> Parseable> for TcQdiscFqCodelOption { - fn parse(buf: &NlaBuffer<&'a T>) -> Result { + type Error = DecodeError; + + fn parse(buf: &NlaBuffer<&'a T>) -> Result { let payload = buf.value(); Ok(match buf.kind() { - TCA_FQ_CODEL_TARGET => Self::Target( - parse_u32(payload) - .context("failed to parse TCA_FQ_CODEL_TARGET")?, - ), - TCA_FQ_CODEL_LIMIT => Self::Limit( - parse_u32(payload) - .context("failed to parse TCA_FQ_CODEL_LIMIT")?, - ), - TCA_FQ_CODEL_INTERVAL => Self::Interval( - parse_u32(payload) - .context("failed to parse TCA_FQ_CODEL_INTERVAL")?, - ), - TCA_FQ_CODEL_ECN => Self::Ecn( - parse_u32(payload) - .context("failed to parse TCA_FQ_CODEL_ECN")?, - ), - TCA_FQ_CODEL_FLOWS => Self::Flows( - parse_u32(payload) - .context("failed to parse TCA_FQ_CODEL_FLOWS")?, - ), - TCA_FQ_CODEL_QUANTUM => Self::Quantum( - parse_u32(payload) - .context("failed to parse TCA_FQ_CODEL_QUANTUM")?, - ), - TCA_FQ_CODEL_CE_THRESHOLD => Self::CeThreshold( - parse_u32(payload) - .context("failed to parse TCA_FQ_CODEL_CETHRESHOLD")?, - ), - TCA_FQ_CODEL_DROP_BATCH_SIZE => Self::DropBatchSize( - parse_u32(payload) - .context("failed to parse TCA_FQ_CODEL_DROP_BATCH_SIZE")?, - ), - TCA_FQ_CODEL_MEMORY_LIMIT => Self::MemoryLimit( - parse_u32(payload) - .context("failed to parse TCA_FQ_CODEL_MEMORY_LIMIT")?, - ), + TCA_FQ_CODEL_TARGET => Self::Target(parse_u32(payload)?), + TCA_FQ_CODEL_LIMIT => Self::Limit(parse_u32(payload)?), + TCA_FQ_CODEL_INTERVAL => Self::Interval(parse_u32(payload)?), + TCA_FQ_CODEL_ECN => Self::Ecn(parse_u32(payload)?), + TCA_FQ_CODEL_FLOWS => Self::Flows(parse_u32(payload)?), + TCA_FQ_CODEL_QUANTUM => Self::Quantum(parse_u32(payload)?), + TCA_FQ_CODEL_CE_THRESHOLD => Self::CeThreshold(parse_u32(payload)?), + TCA_FQ_CODEL_DROP_BATCH_SIZE => { + Self::DropBatchSize(parse_u32(payload)?) + } + TCA_FQ_CODEL_MEMORY_LIMIT => Self::MemoryLimit(parse_u32(payload)?), TCA_FQ_CODEL_CE_THRESHOLD_SELECTOR => { - Self::CeThresholdSelector(parse_u8(payload).context( - "failed to parse TCA_FQ_CODEL_CE_THRESHOLD_SELECTOR", - )?) + Self::CeThresholdSelector(parse_u8(payload)?) } TCA_FQ_CODEL_CE_THRESHOLD_MASK => { - Self::CeThresholdMask(parse_u8(payload).context( - "failed to parse TCA_FQ_CODEL_CE_THRESHOLD_MASK", - )?) + Self::CeThresholdMask(parse_u8(payload)?) } - _ => Self::Other( - DefaultNla::parse(buf).context("failed to parse u32 nla")?, - ), + _ => Self::Other(DefaultNla::parse(buf)?), }) } } diff --git a/src/tc/qdiscs/ingress.rs b/src/tc/qdiscs/ingress.rs index c87a29e0..b15e98ec 100644 --- a/src/tc/qdiscs/ingress.rs +++ b/src/tc/qdiscs/ingress.rs @@ -3,7 +3,6 @@ // Currently, the qdisc ingress does not have any attribute, kernel // just start a empty nla_nest. This is just a place holder -use anyhow::Context; use netlink_packet_utils::{ nla::{DefaultNla, Nla, NlaBuffer}, DecodeError, Parseable, @@ -46,9 +45,9 @@ impl Nla for TcQdiscIngressOption { impl<'a, T: AsRef<[u8]> + ?Sized> Parseable> for TcQdiscIngressOption { - fn parse(buf: &NlaBuffer<&'a T>) -> Result { - Ok(Self::Other( - DefaultNla::parse(buf).context("failed to parse ingress nla")?, - )) + type Error = DecodeError; + + fn parse(buf: &NlaBuffer<&'a T>) -> Result { + Ok(Self::Other(DefaultNla::parse(buf)?)) } } diff --git a/src/tc/stats/basic.rs b/src/tc/stats/basic.rs index 786fee9c..43fccca4 100644 --- a/src/tc/stats/basic.rs +++ b/src/tc/stats/basic.rs @@ -24,7 +24,9 @@ buffer!(TcStatsBasicBuffer(STATS_BASIC_LEN) { }); impl> Parseable> for TcStatsBasic { - fn parse(buf: &TcStatsBasicBuffer) -> Result { + type Error = DecodeError; + + fn parse(buf: &TcStatsBasicBuffer) -> Result { Ok(TcStatsBasic { bytes: buf.bytes(), packets: buf.packets(), diff --git a/src/tc/stats/compat.rs b/src/tc/stats/compat.rs index 5d8cd397..5c743426 100644 --- a/src/tc/stats/compat.rs +++ b/src/tc/stats/compat.rs @@ -41,7 +41,9 @@ buffer!(TcStatsBuffer(STATS_LEN) { }); impl> Parseable> for TcStats { - fn parse(buf: &TcStatsBuffer) -> Result { + type Error = DecodeError; + + fn parse(buf: &TcStatsBuffer) -> Result { Ok(Self { bytes: buf.bytes(), packets: buf.packets(), diff --git a/src/tc/stats/queue.rs b/src/tc/stats/queue.rs index 9909e819..be8e7a12 100644 --- a/src/tc/stats/queue.rs +++ b/src/tc/stats/queue.rs @@ -32,7 +32,9 @@ buffer!(TcStatsQueueBuffer( STATS_QUEUE_LEN) { }); impl> Parseable> for TcStatsQueue { - fn parse(buf: &TcStatsQueueBuffer) -> Result { + type Error = DecodeError; + + fn parse(buf: &TcStatsQueueBuffer) -> Result { Ok(Self { qlen: buf.qlen(), backlog: buf.backlog(), diff --git a/src/tc/stats/stats2.rs b/src/tc/stats/stats2.rs index 9cab4f1e..16f7515c 100644 --- a/src/tc/stats/stats2.rs +++ b/src/tc/stats/stats2.rs @@ -61,12 +61,13 @@ impl Nla for TcStats2 { } } -impl<'a, T> ParseableParametrized, &str> for TcStats2 +impl ParseableParametrized, &str> for TcStats2 where T: AsRef<[u8]> + ?Sized, { + type Error = DecodeError; fn parse_with_param( - buf: &NlaBuffer<&'a T>, + buf: &NlaBuffer<&T>, kind: &str, ) -> Result { let payload = buf.value(); diff --git a/src/tc/stats/xstats.rs b/src/tc/stats/xstats.rs index 38522e2a..c239682a 100644 --- a/src/tc/stats/xstats.rs +++ b/src/tc/stats/xstats.rs @@ -31,14 +31,16 @@ impl Emitable for TcXstats { } } -impl<'a, T> ParseableParametrized, &str> for TcXstats +impl ParseableParametrized, &str> for TcXstats where T: AsRef<[u8]> + ?Sized, { + type Error = DecodeError; + fn parse_with_param( - buf: &NlaBuffer<&'a T>, + buf: &NlaBuffer<&T>, kind: &str, - ) -> Result { + ) -> Result { Ok(match kind { TcQdiscFqCodel::KIND => { TcXstats::FqCodel(TcFqCodelXstats::parse(buf.value())?) diff --git a/src/tests.rs b/src/tests.rs index 952734c8..8236d194 100644 --- a/src/tests.rs +++ b/src/tests.rs @@ -4,7 +4,7 @@ // detailed sub-component parsing. Each component has their own tests moduel. use netlink_packet_core::{NetlinkHeader, NetlinkMessage, NetlinkPayload}; -use netlink_packet_utils::Emitable; +use netlink_packet_utils::traits::Emitable; use crate::{ link::{LinkAttribute, LinkExtentMask, LinkMessage},