diff options
Diffstat (limited to 'src/expr/bitwise.rs')
-rw-r--r-- | src/expr/bitwise.rs | 100 |
1 files changed, 39 insertions, 61 deletions
diff --git a/src/expr/bitwise.rs b/src/expr/bitwise.rs index d34d22c..fb40a04 100644 --- a/src/expr/bitwise.rs +++ b/src/expr/bitwise.rs @@ -1,69 +1,47 @@ -use super::{Expression, Rule, ToSlice}; -use crate::sys::{self, libc}; -use std::ffi::c_void; -use std::os::raw::c_char; - -/// Expression for performing bitwise masking and XOR on the data in a register. -pub struct Bitwise<M: ToSlice, X: ToSlice> { - mask: M, - xor: X, +use rustables_macros::nfnetlink_struct; + +use super::{Expression, Register}; +use crate::error::BuilderError; +use crate::parser_impls::NfNetlinkData; +use crate::sys::{ + NFTA_BITWISE_DREG, NFTA_BITWISE_LEN, NFTA_BITWISE_MASK, NFTA_BITWISE_SREG, NFTA_BITWISE_XOR, +}; + +#[derive(Clone, PartialEq, Eq, Default, Debug)] +#[nfnetlink_struct] +pub struct Bitwise { + #[field(NFTA_BITWISE_SREG)] + sreg: Register, + #[field(NFTA_BITWISE_DREG)] + dreg: Register, + #[field(NFTA_BITWISE_LEN)] + len: u32, + #[field(NFTA_BITWISE_MASK)] + mask: NfNetlinkData, + #[field(NFTA_BITWISE_XOR)] + xor: NfNetlinkData, } -impl<M: ToSlice, X: ToSlice> Bitwise<M, X> { - /// Returns a new `Bitwise` instance that first masks the value it's applied to with `mask` and - /// then performs xor with the value in `xor`. - pub fn new(mask: M, xor: X) -> Self { - Self { mask, xor } +impl Expression for Bitwise { + fn get_name() -> &'static str { + "bitwise" } } -impl<M: ToSlice, X: ToSlice> Expression for Bitwise<M, X> { - fn get_raw_name() -> *const c_char { - b"bitwise\0" as *const _ as *const c_char - } - - fn to_expr(&self, _rule: &Rule) -> *mut sys::nftnl_expr { - unsafe { - let expr = try_alloc!(sys::nftnl_expr_alloc(Self::get_raw_name())); - - let mask = self.mask.to_slice(); - let xor = self.xor.to_slice(); - assert!(mask.len() == xor.len()); - let len = mask.len() as u32; - - sys::nftnl_expr_set_u32( - expr, - sys::NFTNL_EXPR_BITWISE_SREG as u16, - libc::NFT_REG_1 as u32, - ); - sys::nftnl_expr_set_u32( - expr, - sys::NFTNL_EXPR_BITWISE_DREG as u16, - libc::NFT_REG_1 as u32, - ); - sys::nftnl_expr_set_u32(expr, sys::NFTNL_EXPR_BITWISE_LEN as u16, len); - - sys::nftnl_expr_set( - expr, - sys::NFTNL_EXPR_BITWISE_MASK as u16, - mask.as_ref() as *const _ as *const c_void, - len, - ); - sys::nftnl_expr_set( - expr, - sys::NFTNL_EXPR_BITWISE_XOR as u16, - xor.as_ref() as *const _ as *const c_void, - len, - ); - - expr +impl Bitwise { + /// Returns a new `Bitwise` instance that first masks the value it's applied to with `mask` and + /// then performs xor with the value in `xor` + pub fn new(mask: impl Into<Vec<u8>>, xor: impl Into<Vec<u8>>) -> Result<Self, BuilderError> { + let mask = mask.into(); + let xor = xor.into(); + if mask.len() != xor.len() { + return Err(BuilderError::IncompatibleLength); } + Ok(Bitwise::default() + .with_sreg(Register::Reg1) + .with_dreg(Register::Reg1) + .with_len(mask.len() as u32) + .with_xor(NfNetlinkData::default().with_value(xor)) + .with_mask(NfNetlinkData::default().with_value(mask))) } } - -#[macro_export] -macro_rules! nft_expr_bitwise { - (mask $mask:expr,xor $xor:expr) => { - $crate::expr::Bitwise::new($mask, $xor) - }; -} |