diff options
author | Simon THOBY <git@nightmared.fr> | 2022-11-15 22:25:36 +0100 |
---|---|---|
committer | Simon THOBY <git@nightmared.fr> | 2022-11-15 22:25:36 +0100 |
commit | d1170d81c85254d2fe5ef5d3fc92cc6eb35357a4 (patch) | |
tree | 6f5645e3b7313681f083135a3718a8da129574f3 /src/expr/bitwise.rs | |
parent | 22edb0197854bf4f504e833e69b0e545d382f065 (diff) |
exprs: implement bitwise and add support for unknown expressions
Diffstat (limited to 'src/expr/bitwise.rs')
-rw-r--r-- | src/expr/bitwise.rs | 127 |
1 files changed, 66 insertions, 61 deletions
diff --git a/src/expr/bitwise.rs b/src/expr/bitwise.rs index d34d22c..38c0383 100644 --- a/src/expr/bitwise.rs +++ b/src/expr/bitwise.rs @@ -1,69 +1,74 @@ -use super::{Expression, Rule, ToSlice}; -use crate::sys::{self, libc}; -use std::ffi::c_void; -use std::os::raw::c_char; +use super::{Expression, ExpressionData, Register}; +use crate::create_expr_type; +use crate::parser::DecodeError; +use crate::sys; -/// Expression for performing bitwise masking and XOR on the data in a register. -pub struct Bitwise<M: ToSlice, X: ToSlice> { - mask: M, - xor: X, -} +create_expr_type!( + inline with_builder : Bitwise, + [ + ( + get_dreg, + set_dreg, + with_dreg, + sys::NFTA_BITWISE_DREG, + Register, + Register + ), + ( + get_sreg, + set_sreg, + with_sreg, + sys::NFTA_BITWISE_SREG, + Register, + Register + ), + ( + get_len, + set_len, + with_len, + sys::NFTA_BITWISE_LEN, + U32, + u32 + ), + ( + get_mask, + set_mask, + with_mask, + sys::NFTA_BITWISE_MASK, + ExprData, + ExpressionData + ), + ( + get_xor, + set_xor, + with_xor, + sys::NFTA_BITWISE_XOR, + ExprData, + ExpressionData + ) + ] +); -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, DecodeError> { + let mask = mask.into(); + let xor = xor.into(); + if mask.len() != xor.len() { + return Err(DecodeError::IncompatibleLength); } + Ok(Self::builder() + .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))) } } - -#[macro_export] -macro_rules! nft_expr_bitwise { - (mask $mask:expr,xor $xor:expr) => { - $crate::expr::Bitwise::new($mask, $xor) - }; -} |