aboutsummaryrefslogtreecommitdiff
path: root/src/expr
diff options
context:
space:
mode:
Diffstat (limited to 'src/expr')
-rw-r--r--src/expr/bitwise.rs39
-rw-r--r--src/expr/immediate.rs14
-rw-r--r--src/expr/log.rs73
-rw-r--r--src/expr/meta.rs230
-rw-r--r--src/expr/mod.rs175
-rw-r--r--src/expr/verdict.rs18
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))
}
}