diff options
Diffstat (limited to 'src/expr')
-rw-r--r-- | src/expr/bitwise.rs | 39 | ||||
-rw-r--r-- | src/expr/immediate.rs | 14 | ||||
-rw-r--r-- | src/expr/log.rs | 73 | ||||
-rw-r--r-- | src/expr/meta.rs | 230 | ||||
-rw-r--r-- | src/expr/mod.rs | 175 | ||||
-rw-r--r-- | src/expr/verdict.rs | 18 |
6 files changed, 177 insertions, 372 deletions
diff --git a/src/expr/bitwise.rs b/src/expr/bitwise.rs index 38c0383..73c2467 100644 --- a/src/expr/bitwise.rs +++ b/src/expr/bitwise.rs @@ -1,41 +1,34 @@ use super::{Expression, ExpressionData, Register}; -use crate::create_expr_type; +use crate::create_wrapper_type; use crate::parser::DecodeError; use crate::sys; -create_expr_type!( - inline with_builder : Bitwise, +create_wrapper_type!( + inline: Bitwise, [ ( - get_dreg, - set_dreg, - with_dreg, - sys::NFTA_BITWISE_DREG, - Register, - Register - ), - ( get_sreg, set_sreg, with_sreg, sys::NFTA_BITWISE_SREG, - Register, + sreg, Register ), ( - get_len, - set_len, - with_len, - sys::NFTA_BITWISE_LEN, - U32, - u32 + get_dreg, + set_dreg, + with_dreg, + sys::NFTA_BITWISE_DREG, + dreg, + Register ), + (get_len, set_len, with_len, sys::NFTA_BITWISE_LEN, len, u32), ( get_mask, set_mask, with_mask, sys::NFTA_BITWISE_MASK, - ExprData, + mask, ExpressionData ), ( @@ -43,7 +36,7 @@ create_expr_type!( set_xor, with_xor, sys::NFTA_BITWISE_XOR, - ExprData, + xor, ExpressionData ) ] @@ -64,11 +57,11 @@ impl Bitwise { if mask.len() != xor.len() { return Err(DecodeError::IncompatibleLength); } - Ok(Self::builder() + Ok(Bitwise::default() .with_sreg(Register::Reg1) .with_dreg(Register::Reg1) .with_len(mask.len() as u32) - .with_xor(ExpressionData::builder().with_value(xor)) - .with_mask(ExpressionData::builder().with_value(mask))) + .with_xor(ExpressionData::default().with_value(xor)) + .with_mask(ExpressionData::default().with_value(mask))) } } diff --git a/src/expr/immediate.rs b/src/expr/immediate.rs index 6f26bc3..925ca06 100644 --- a/src/expr/immediate.rs +++ b/src/expr/immediate.rs @@ -1,15 +1,15 @@ use super::{Expression, ExpressionData, Register}; -use crate::{create_expr_type, sys}; +use crate::{create_wrapper_type, sys}; -create_expr_type!( - inline with_builder : Immediate, +create_wrapper_type!( + inline: Immediate, [ ( get_dreg, set_dreg, with_dreg, sys::NFTA_IMMEDIATE_DREG, - Register, + dreg, Register ), ( @@ -17,7 +17,7 @@ create_expr_type!( set_data, with_data, sys::NFTA_IMMEDIATE_DATA, - ExprData, + data, ExpressionData ) ] @@ -25,9 +25,9 @@ create_expr_type!( impl Immediate { pub fn new_data(data: Vec<u8>, register: Register) -> Self { - Immediate::builder() + Immediate::default() .with_dreg(register) - .with_data(ExpressionData::builder().with_value(data)) + .with_data(ExpressionData::default().with_value(data)) } } diff --git a/src/expr/log.rs b/src/expr/log.rs index cf50cb2..82c201d 100644 --- a/src/expr/log.rs +++ b/src/expr/log.rs @@ -1,18 +1,17 @@ use super::{Expression, ExpressionError}; -use crate::create_expr_type; -use crate::nlmsg::NfNetlinkAttributes; +use crate::create_wrapper_type; use crate::sys; // A Log expression will log all packets that match the rule. -create_expr_type!( - inline with_builder : Log, +create_wrapper_type!( + inline: Log, [ ( get_group, set_group, with_group, sys::NFTA_LOG_GROUP, - U32, + group, u32 ), ( @@ -20,7 +19,7 @@ create_expr_type!( set_prefix, with_prefix, sys::NFTA_LOG_PREFIX, - String, + prefix, String ) ] @@ -31,11 +30,7 @@ impl Log { group: Option<u16>, prefix: Option<impl Into<String>>, ) -> Result<Log, ExpressionError> { - let mut res = Log { - inner: NfNetlinkAttributes::new(), - //pub group: Option<LogGroup>, - //pub prefix: Option<LogPrefix>, - }; + let mut res = Log::default(); if let Some(group) = group { res.set_group(group); } @@ -55,60 +50,4 @@ impl Expression for Log { fn get_name() -> &'static str { "log" } - /* - fn from_expr(expr: *const sys::nftnl_expr) -> Result<Self, DeserializationError> - where - Self: Sized, - { - unsafe { - let mut group = None; - if sys::nftnl_expr_is_set(expr, sys::NFTNL_EXPR_LOG_GROUP as u16) { - group = Some(LogGroup(sys::nftnl_expr_get_u32( - expr, - sys::NFTNL_EXPR_LOG_GROUP as u16, - ) as u16)); - } - let mut prefix = None; - if sys::nftnl_expr_is_set(expr, sys::NFTNL_EXPR_LOG_PREFIX as u16) { - let raw_prefix = sys::nftnl_expr_get_str(expr, sys::NFTNL_EXPR_LOG_PREFIX as u16); - if raw_prefix.is_null() { - return Err(DeserializationError::NullPointer); - } else { - prefix = Some(LogPrefix(CStr::from_ptr(raw_prefix).to_owned())); - } - } - Ok(Log { group, prefix }) - } - } - - fn to_expr(&self, _rule: &Rule) -> *mut sys::nftnl_expr { - unsafe { - let expr = try_alloc!(sys::nftnl_expr_alloc(b"log\0" as *const _ as *const c_char)); - if let Some(log_group) = self.group { - sys::nftnl_expr_set_u32(expr, sys::NFTNL_EXPR_LOG_GROUP as u16, log_group.0 as u32); - }; - if let Some(LogPrefix(prefix)) = &self.prefix { - sys::nftnl_expr_set_str(expr, sys::NFTNL_EXPR_LOG_PREFIX as u16, prefix.as_ptr()); - }; - - expr - } - } - */ -} - -#[macro_export] -macro_rules! nft_expr_log { - (group $group:ident prefix $prefix:expr) => { - $crate::expr::Log::new(Some($group), Some($prefix)) - }; - (prefix $prefix:expr) => { - $crate::expr::Log::new(None, Some($prefix)) - }; - (group $group:ident) => { - $crate::expr::Log::new(Some($group), None) - }; - () => { - $crate::expr::Log::new(None, None) - }; } diff --git a/src/expr/meta.rs b/src/expr/meta.rs index a015f65..bb8023d 100644 --- a/src/expr/meta.rs +++ b/src/expr/meta.rs @@ -1,175 +1,115 @@ -use super::{DeserializationError, Expression, Rule}; -use crate::sys::{self, libc}; -use std::os::raw::c_char; +use super::{Expression, Register, Rule}; +use crate::{ + create_wrapper_type, + nlmsg::{NfNetlinkAttribute, NfNetlinkDeserializable}, + parser::DecodeError, + sys, +}; +use std::convert::TryFrom; /// A meta expression refers to meta data associated with a packet. #[derive(Debug, Copy, Clone, Eq, PartialEq)] +#[repr(u32)] #[non_exhaustive] -pub enum Meta { +pub enum MetaType { /// Packet ethertype protocol (skb->protocol), invalid in OUTPUT. - Protocol, + Protocol = sys::NFT_META_PROTOCOL, /// Packet mark. - Mark { set: bool }, + Mark = sys::NFT_META_MARK, /// Packet input interface index (dev->ifindex). - Iif, + Iif = sys::NFT_META_IIF, /// Packet output interface index (dev->ifindex). - Oif, + Oif = sys::NFT_META_OIF, /// Packet input interface name (dev->name). - IifName, + IifName = sys::NFT_META_IIFNAME, /// Packet output interface name (dev->name). - OifName, + OifName = sys::NFT_META_OIFNAME, /// Packet input interface type (dev->type). - IifType, + IifType = sys::NFT_META_IFTYPE, /// Packet output interface type (dev->type). - OifType, + OifType = sys::NFT_META_OIFTYPE, /// Originating socket UID (fsuid). - SkUid, + SkUid = sys::NFT_META_SKUID, /// Originating socket GID (fsgid). - SkGid, + SkGid = sys::NFT_META_SKGID, /// Netfilter protocol (Transport layer protocol). - NfProto, + NfProto = sys::NFT_META_NFPROTO, /// Layer 4 protocol number. - L4Proto, + L4Proto = sys::NFT_META_L4PROTO, /// Socket control group (skb->sk->sk_classid). - Cgroup, + Cgroup = sys::NFT_META_CGROUP, /// A 32bit pseudo-random number. - PRandom, + PRandom = sys::NFT_META_PRANDOM, } -impl Meta { - /// Returns the corresponding `NFT_*` constant for this meta expression. - pub fn to_raw_key(&self) -> u32 { - use Meta::*; - match *self { - Protocol => libc::NFT_META_PROTOCOL as u32, - Mark { .. } => libc::NFT_META_MARK as u32, - Iif => libc::NFT_META_IIF as u32, - Oif => libc::NFT_META_OIF as u32, - IifName => libc::NFT_META_IIFNAME as u32, - OifName => libc::NFT_META_OIFNAME as u32, - IifType => libc::NFT_META_IIFTYPE as u32, - OifType => libc::NFT_META_OIFTYPE as u32, - SkUid => libc::NFT_META_SKUID as u32, - SkGid => libc::NFT_META_SKGID as u32, - NfProto => libc::NFT_META_NFPROTO as u32, - L4Proto => libc::NFT_META_L4PROTO as u32, - Cgroup => libc::NFT_META_CGROUP as u32, - PRandom => libc::NFT_META_PRANDOM as u32, - } +impl NfNetlinkAttribute for MetaType { + fn get_size(&self) -> usize { + (*self as u32).get_size() } - fn from_raw(val: u32) -> Result<Self, DeserializationError> { - match val as i32 { - libc::NFT_META_PROTOCOL => Ok(Self::Protocol), - libc::NFT_META_MARK => Ok(Self::Mark { set: false }), - libc::NFT_META_IIF => Ok(Self::Iif), - libc::NFT_META_OIF => Ok(Self::Oif), - libc::NFT_META_IIFNAME => Ok(Self::IifName), - libc::NFT_META_OIFNAME => Ok(Self::OifName), - libc::NFT_META_IIFTYPE => Ok(Self::IifType), - libc::NFT_META_OIFTYPE => Ok(Self::OifType), - libc::NFT_META_SKUID => Ok(Self::SkUid), - libc::NFT_META_SKGID => Ok(Self::SkGid), - libc::NFT_META_NFPROTO => Ok(Self::NfProto), - libc::NFT_META_L4PROTO => Ok(Self::L4Proto), - libc::NFT_META_CGROUP => Ok(Self::Cgroup), - libc::NFT_META_PRANDOM => Ok(Self::PRandom), - _ => Err(DeserializationError::InvalidValue), - } + unsafe fn write_payload(&self, addr: *mut u8) { + (*self as u32).write_payload(addr); } } -impl Expression for Meta { - fn get_raw_name() -> *const libc::c_char { - b"meta\0" as *const _ as *const c_char - } - - fn from_expr(expr: *const sys::nftnl_expr) -> Result<Self, DeserializationError> - where - Self: Sized, - { - unsafe { - let mut ret = Self::from_raw(sys::nftnl_expr_get_u32( - expr, - sys::NFTNL_EXPR_META_KEY as u16, - ))?; - - if let Self::Mark { ref mut set } = ret { - *set = sys::nftnl_expr_is_set(expr, sys::NFTNL_EXPR_META_SREG as u16); - } - - Ok(ret) - } +impl NfNetlinkDeserializable for MetaType { + fn deserialize(buf: &[u8]) -> Result<(Self, &[u8]), DecodeError> { + let (v, remaining_data) = u32::deserialize(buf)?; + Ok(( + match v { + sys::NFT_META_PROTOCOL => Self::Protocol, + sys::NFT_META_MARK => Self::Mark, + sys::NFT_META_IIF => Self::Iif, + sys::NFT_META_OIF => Self::Oif, + sys::NFT_META_IIFNAME => Self::IifName, + sys::NFT_META_OIFNAME => Self::OifName, + sys::NFT_META_IFTYPE => Self::IifType, + sys::NFT_META_OIFTYPE => Self::OifType, + sys::NFT_META_SKUID => Self::SkUid, + sys::NFT_META_SKGID => Self::SkGid, + sys::NFT_META_NFPROTO => Self::NfProto, + sys::NFT_META_L4PROTO => Self::L4Proto, + sys::NFT_META_CGROUP => Self::Cgroup, + sys::NFT_META_PRANDOM => Self::PRandom, + value => return Err(DecodeError::UnknownMetaType(value)), + }, + remaining_data, + )) } +} - fn to_expr(&self, _rule: &Rule) -> *mut sys::nftnl_expr { - unsafe { - let expr = try_alloc!(sys::nftnl_expr_alloc(Self::get_raw_name())); +create_wrapper_type!( + inline: Meta, + [ + ( + get_dreg, + set_dreg, + with_dreg, + sys::NFTA_META_DREG, + dreg, + Register + ), + ( + get_key, + set_key, + with_key, + sys::NFTA_META_KEY, + key, + MetaType + ), + ( + get_sreg, + set_sreg, + with_sreg, + sys::NFTA_META_SREG, + sreg, + Register + ) + ] +); - if let Meta::Mark { set: true } = self { - sys::nftnl_expr_set_u32( - expr, - sys::NFTNL_EXPR_META_SREG as u16, - libc::NFT_REG_1 as u32, - ); - } else { - sys::nftnl_expr_set_u32( - expr, - sys::NFTNL_EXPR_META_DREG as u16, - libc::NFT_REG_1 as u32, - ); - } - sys::nftnl_expr_set_u32(expr, sys::NFTNL_EXPR_META_KEY as u16, self.to_raw_key()); - expr - } +impl Expression for Meta { + fn get_name() -> &'static str { + "meta" } } - -#[macro_export] -macro_rules! nft_expr_meta { - (proto) => { - $crate::expr::Meta::Protocol - }; - (mark set) => { - $crate::expr::Meta::Mark { set: true } - }; - (mark) => { - $crate::expr::Meta::Mark { set: false } - }; - (iif) => { - $crate::expr::Meta::Iif - }; - (oif) => { - $crate::expr::Meta::Oif - }; - (iifname) => { - $crate::expr::Meta::IifName - }; - (oifname) => { - $crate::expr::Meta::OifName - }; - (iiftype) => { - $crate::expr::Meta::IifType - }; - (oiftype) => { - $crate::expr::Meta::OifType - }; - (skuid) => { - $crate::expr::Meta::SkUid - }; - (skgid) => { - $crate::expr::Meta::SkGid - }; - (nfproto) => { - $crate::expr::Meta::NfProto - }; - (l4proto) => { - $crate::expr::Meta::L4Proto - }; - (cgroup) => { - $crate::expr::Meta::Cgroup - }; - (random) => { - $crate::expr::Meta::PRandom - }; -} diff --git a/src/expr/mod.rs b/src/expr/mod.rs index 78b1717..6dfa6c7 100644 --- a/src/expr/mod.rs +++ b/src/expr/mod.rs @@ -12,14 +12,13 @@ use std::net::Ipv6Addr; use std::slice::Iter; use super::rule::Rule; +use crate::create_wrapper_type; use crate::nlmsg::AttributeDecoder; use crate::nlmsg::NfNetlinkAttribute; -use crate::nlmsg::NfNetlinkAttributes; use crate::nlmsg::NfNetlinkDeserializable; use crate::parser::pad_netlink_object; use crate::parser::pad_netlink_object_with_variable_size; use crate::parser::write_attribute; -use crate::parser::AttributeType; use crate::parser::DecodeError; use crate::parser::InnerFormat; use crate::sys::{self, nlattr}; @@ -52,10 +51,12 @@ pub use self::lookup::*; mod masquerade; pub use self::masquerade::*; +*/ mod meta; pub use self::meta::*; +/* mod nat; pub use self::nat::*; @@ -111,91 +112,15 @@ pub trait Expression { fn get_name() -> &'static str; } -// wrapper for the general case, as we need to create many holder types given the depth of some -// netlink expressions -#[macro_export] -macro_rules! create_expr_type { - (without_decoder : $struct:ident, [$(($getter_name:ident, $setter_name:ident, $in_place_edit_name:ident, $attr_name:expr, $internal_name:ident, $type:ty)),+]) => { - #[derive(Clone, PartialEq, Eq)] - pub struct $struct { - inner: $crate::nlmsg::NfNetlinkAttributes, - } - - - $crate::impl_attr_getters_and_setters!(without_decoder $struct, [$(($getter_name, $setter_name, $in_place_edit_name, $attr_name, $internal_name, $type)),+]); - - impl std::fmt::Debug for $struct { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - use $crate::parser::InnerFormat; - self.inner_format_struct(f.debug_struct(stringify!($struct)))? - .finish() - } - } - - - impl $crate::nlmsg::NfNetlinkDeserializable for $struct { - fn deserialize(buf: &[u8]) -> Result<(Self, &[u8]), $crate::parser::DecodeError> { - let reader = $crate::parser::NfNetlinkAttributeReader::new(buf, buf.len())?; - let inner = reader.decode::<Self>()?; - Ok(($struct { inner }, &[])) - } - } - - }; - ($struct:ident, [$(($getter_name:ident, $setter_name:ident, $in_place_edit_name:ident, $attr_name:expr, $internal_name:ident, $type:ty)),+]) => { - create_expr_type!(without_decoder : $struct, [$(($getter_name, $setter_name, $in_place_edit_name, $attr_name, $internal_name, $type)),+]); - $crate::impl_attr_getters_and_setters!(decoder $struct, [$(($getter_name, $setter_name, $in_place_edit_name, $attr_name, $internal_name, $type)),+]); - }; - (with_builder : $struct:ident, [$(($getter_name:ident, $setter_name:ident, $in_place_edit_name:ident, $attr_name:expr, $internal_name:ident, $type:ty)),+]) => { - create_expr_type!($struct, [$(($getter_name, $setter_name, $in_place_edit_name, $attr_name, $internal_name, $type)),+]); - - impl $struct { - pub fn builder() -> Self { - Self { inner: $crate::nlmsg::NfNetlinkAttributes::new() } - } - } - }; - (inline $($($attrs:ident) +)? : $struct:ident, [$(($getter_name:ident, $setter_name:ident, $in_place_edit_name:ident, $attr_name:expr, $internal_name:ident, $type:ty)),+]) => { - create_expr_type!($($($attrs) + :)? $struct, [$(($getter_name, $setter_name, $in_place_edit_name, $attr_name, $internal_name, $type)),+]); - - impl $crate::nlmsg::NfNetlinkAttribute for $struct { - fn get_size(&self) -> usize { - self.inner.get_size() - } - - unsafe fn write_payload(&self, addr: *mut u8) { - self.inner.write_payload(addr) - } - } - }; - (nested $($($attrs:ident) +)? : $struct:ident, [$(($getter_name:ident, $setter_name:ident, $in_place_edit_name:ident, $attr_name:expr, $internal_name:ident, $type:ty)),+]) => { - create_expr_type!($($($attrs) + :)? $struct, [$(($getter_name, $setter_name, $in_place_edit_name, $attr_name, $internal_name, $type)),+]); - - impl $crate::nlmsg::NfNetlinkAttribute for $struct { - fn is_nested(&self) -> bool { - true - } - - fn get_size(&self) -> usize { - self.inner.get_size() - } - - unsafe fn write_payload(&self, addr: *mut u8) { - self.inner.write_payload(addr) - } - } - }; -} - -create_expr_type!( - nested without_decoder : ExpressionHolder, [ +create_wrapper_type!( + nested without_deser : RawExpression, [ // Define the action netfilter will apply to packets processed by this chain, but that did not match any rules in it. ( get_name, set_name, with_name, sys::NFTA_EXPR_NAME, - String, + name, String ), ( @@ -203,22 +128,20 @@ create_expr_type!( set_data, with_data, sys::NFTA_EXPR_DATA, - ExpressionVariant, + data, ExpressionVariant ) ]); -impl ExpressionHolder { +impl RawExpression { pub fn new<T>(expr: T) -> Self where T: Expression, ExpressionVariant: From<T>, { - ExpressionHolder { - inner: NfNetlinkAttributes::new(), - } - .with_name(T::get_name()) - .with_data(ExpressionVariant::from(expr)) + RawExpression::default() + .with_name(T::get_name()) + .with_data(ExpressionVariant::from(expr)) } } @@ -262,44 +185,45 @@ macro_rules! create_expr_variant { } )+ - impl AttributeDecoder for ExpressionHolder { + impl $crate::nlmsg::AttributeDecoder for RawExpression { fn decode_attribute( - attrs: &NfNetlinkAttributes, + &mut self, attr_type: u16, buf: &[u8], - ) -> Result<AttributeType, DecodeError> { + ) -> Result<(), $crate::parser::DecodeError> { debug!("Decoding attribute {} in an expression", attr_type); match attr_type { x if x == sys::NFTA_EXPR_NAME => { debug!("Calling {}::deserialize()", std::any::type_name::<String>()); let (val, remaining) = String::deserialize(buf)?; if remaining.len() != 0 { - return Err(DecodeError::InvalidDataSize); + return Err($crate::parser::DecodeError::InvalidDataSize); } - Ok(AttributeType::String(val)) + self.name = Some(val); + Ok(()) }, x if x == sys::NFTA_EXPR_DATA => { // we can assume we have already the name parsed, as that's how we identify the // type of expression - let name = attrs - .get_attr(sys::NFTA_EXPR_NAME) - .ok_or(DecodeError::MissingExpressionName)?; + let name = self.name.as_ref() + .ok_or($crate::parser::DecodeError::MissingExpressionName)?; match name { $( - AttributeType::String(x) if x == <$type>::get_name() => { + x if x == <$type>::get_name() => { debug!("Calling {}::deserialize()", std::any::type_name::<$type>()); let (res, remaining) = <$type>::deserialize(buf)?; if remaining.len() != 0 { return Err($crate::parser::DecodeError::InvalidDataSize); } - Ok(AttributeType::ExpressionVariant(ExpressionVariant::from(res))) + self.data = Some(ExpressionVariant::from(res)); + Ok(()) }, )+ - AttributeType::String(name) => { + name => { info!("Unrecognized expression '{}', generating an ExpressionRaw", name); - ExpressionRaw::deserialize(buf).map(|(res, _)| AttributeType::ExpressionVariant(ExpressionVariant::ExpressionRaw(res))) - }, - _ => unreachable!() + self.data = Some(ExpressionVariant::ExpressionRaw(ExpressionRaw::deserialize(buf)?.0)); + Ok(()) + } } }, _ => Err(DecodeError::UnsupportedAttributeType(attr_type)), @@ -314,12 +238,13 @@ create_expr_variant!( [Log, Log], [Immediate, Immediate], [Bitwise, Bitwise], - [ExpressionRaw, ExpressionRaw] + [ExpressionRaw, ExpressionRaw], + [Meta, Meta] ); -#[derive(Debug, Clone, PartialEq, Eq)] +#[derive(Debug, Clone, PartialEq, Eq, Default)] pub struct ExpressionList { - exprs: Vec<AttributeType>, + exprs: Vec<RawExpression>, } impl ExpressionList { @@ -327,9 +252,9 @@ impl ExpressionList { Self { exprs: Vec::new() } } - /// Useful to add raw expressions because ExpressionHolder cannot infer alone its type - pub fn add_raw_expression(&mut self, e: ExpressionHolder) { - self.exprs.push(AttributeType::Expression(e)); + /// Useful to add raw expressions because RawExpression cannot infer alone its type + pub fn add_raw_expression(&mut self, e: RawExpression) { + self.exprs.push(e); } pub fn add_expression<T>(&mut self, e: T) @@ -337,8 +262,7 @@ impl ExpressionList { T: Expression, ExpressionVariant: From<T>, { - self.exprs - .push(AttributeType::Expression(ExpressionHolder::new(e))); + self.exprs.push(RawExpression::new(e)); } pub fn with_expression<T>(mut self, e: T) -> Self @@ -351,10 +275,7 @@ impl ExpressionList { } pub fn iter<'a>(&'a self) -> impl Iterator<Item = &'a ExpressionVariant> { - self.exprs.iter().map(|t| match t { - AttributeType::Expression(e) => e.get_data().unwrap(), - _ => unreachable!(), - }) + self.exprs.iter().map(|e| e.get_data().unwrap()) } } @@ -392,13 +313,13 @@ impl NfNetlinkDeserializable for ExpressionList { return Err(DecodeError::UnsupportedAttributeType(nla_type)); } - let (expr, remaining) = ExpressionHolder::deserialize( + let (expr, remaining) = RawExpression::deserialize( &buf[pos + pad_netlink_object::<nlattr>()..pos + nlattr.nla_len as usize], )?; if remaining.len() != 0 { return Err(DecodeError::InvalidDataSize); } - exprs.push(AttributeType::Expression(expr)); + exprs.push(expr); pos += pad_netlink_object_with_variable_size(nlattr.nla_len as usize); } @@ -411,15 +332,27 @@ impl NfNetlinkDeserializable for ExpressionList { } } -create_expr_type!( - nested with_builder : ExpressionData, +impl<T> From<Vec<T>> for ExpressionList +where + ExpressionVariant: From<T>, + T: Expression, +{ + fn from(v: Vec<T>) -> Self { + ExpressionList { + exprs: v.into_iter().map(RawExpression::new).collect(), + } + } +} + +create_wrapper_type!( + nested : ExpressionData, [ ( get_value, set_value, with_value, sys::NFTA_DATA_VALUE, - VecU8, + value, Vec<u8> ), ( @@ -427,7 +360,7 @@ create_expr_type!( set_verdict, with_verdict, sys::NFTA_DATA_VERDICT, - ExprVerdictAttribute, + verdict, VerdictAttribute ) ] @@ -454,7 +387,7 @@ impl NfNetlinkDeserializable for ExpressionRaw { } // Because we loose the name of the expression when parsing, this is the only expression -// where deserializing a message and the reserializing it alter its content +// where deserializing a message and then reserializing it is invalid impl Expression for ExpressionRaw { fn get_name() -> &'static str { "unknown_expression" diff --git a/src/expr/verdict.rs b/src/expr/verdict.rs index 7c27af6..547ba91 100644 --- a/src/expr/verdict.rs +++ b/src/expr/verdict.rs @@ -4,7 +4,7 @@ use libc::{NF_ACCEPT, NF_DROP, NF_QUEUE}; use super::{ExpressionData, Immediate, Register}; use crate::{ - create_expr_type, + create_wrapper_type, nlmsg::{NfNetlinkAttribute, NfNetlinkDeserializable}, parser::DecodeError, sys::{self, NFT_BREAK, NFT_CONTINUE, NFT_GOTO, NFT_JUMP, NFT_RETURN}, @@ -53,15 +53,15 @@ impl NfNetlinkDeserializable for VerdictType { } } -create_expr_type!( - nested with_builder : VerdictAttribute, +create_wrapper_type!( + nested: VerdictAttribute, [ ( get_code, set_code, with_code, sys::NFTA_VERDICT_CODE, - ExprVerdictType, + code, VerdictType ), ( @@ -69,7 +69,7 @@ create_expr_type!( set_chain, with_chain, sys::NFTA_VERDICT_CHAIN, - String, + chain, String ), ( @@ -77,7 +77,7 @@ create_expr_type!( set_chain_id, with_chain_id, sys::NFTA_VERDICT_CHAIN_ID, - U32, + chain_id, u32 ) ] @@ -113,12 +113,12 @@ impl Immediate { VerdictKind::Goto { .. } => VerdictType::Goto, VerdictKind::Return => VerdictType::Return, }; - let mut data = VerdictAttribute::builder().with_code(code); + let mut data = VerdictAttribute::default().with_code(code); if let VerdictKind::Jump { chain } | VerdictKind::Goto { chain } = kind { data.set_chain(chain); } - Immediate::builder() + Immediate::default() .with_dreg(Register::Verdict) - .with_data(ExpressionData::builder().with_verdict(data)) + .with_data(ExpressionData::default().with_verdict(data)) } } |