diff options
author | David Lönnhager <david.l@mullvad.net> | 2020-05-18 14:44:30 +0200 |
---|---|---|
committer | David Lönnhager <david.l@mullvad.net> | 2020-05-19 11:00:23 +0200 |
commit | 0fcc1f74a7a203b075ea9a0e84818902bab54c53 (patch) | |
tree | 9d1bd45dc77bdfca803d1ba0921f1e9e9a591e37 | |
parent | e50e459d506f0f6e9e58e6d0298f1754e90aef98 (diff) |
Move Verdict to its own module since it does not depend only on 'immediate' expressions
-rw-r--r-- | nftnl/src/expr/immediate.rs | 137 | ||||
-rw-r--r-- | nftnl/src/expr/mod.rs | 3 | ||||
-rw-r--r-- | nftnl/src/expr/verdict.rs | 138 |
3 files changed, 142 insertions, 136 deletions
diff --git a/nftnl/src/expr/immediate.rs b/nftnl/src/expr/immediate.rs index c8885a3..b2f8e0c 100644 --- a/nftnl/src/expr/immediate.rs +++ b/nftnl/src/expr/immediate.rs @@ -1,7 +1,7 @@ use super::Expression; use libc; use nftnl_sys::{self as sys, libc::{c_char, c_void}}; -use std::{ffi::{CStr, CString}, mem::size_of_val}; +use std::mem::size_of_val; /// An immediate expression. Used to set immediate data. /// Verdicts are handled separately by [Verdict]. @@ -41,138 +41,3 @@ macro_rules! nft_expr_immediate { $crate::expr::Immediate { data: $value } }; } - -/// A verdict expression. In the background, this is usually an "Immediate" expression in nftnl -/// terms, but here it is simplified to only represent a verdict. -#[derive(Debug, Clone, Eq, PartialEq, Hash)] -pub enum Verdict { - /// Silently drop the packet. - Drop, - /// Accept the packet and let it pass. - Accept, - /// Reject the packet and return a message. - Reject, - Queue, - Continue, - Break, - Jump { - chain: CString, - }, - Goto { - chain: CString, - }, - Return, -} - -impl Verdict { - fn immediate_const(&self) -> Option<i32> { - match *self { - Verdict::Drop => Some(libc::NF_DROP), - Verdict::Accept => Some(libc::NF_ACCEPT), - Verdict::Queue => Some(libc::NF_QUEUE), - Verdict::Continue => Some(libc::NFT_CONTINUE), - Verdict::Break => Some(libc::NFT_BREAK), - Verdict::Jump { .. } => Some(libc::NFT_JUMP), - Verdict::Goto { .. } => Some(libc::NFT_GOTO), - Verdict::Return => Some(libc::NFT_RETURN), - _ => None, - } - } - - unsafe fn immediate_to_expr(&self, immediate_const: i32) -> *mut sys::nftnl_expr { - let expr = try_alloc!(sys::nftnl_expr_alloc( - b"immediate\0" as *const _ as *const c_char - )); - - sys::nftnl_expr_set_u32( - expr, - sys::NFTNL_EXPR_IMM_DREG as u16, - libc::NFT_REG_VERDICT as u32, - ); - - if let Some(chain) = self.chain() { - sys::nftnl_expr_set_str(expr, sys::NFTNL_EXPR_IMM_CHAIN as u16, chain.as_ptr()); - } - sys::nftnl_expr_set_u32( - expr, - sys::NFTNL_EXPR_IMM_VERDICT as u16, - immediate_const as u32, - ); - - expr - } - - fn chain(&self) -> Option<&CStr> { - match *self { - Verdict::Jump { ref chain } => Some(chain.as_c_str()), - Verdict::Goto { ref chain } => Some(chain.as_c_str()), - _ => None, - } - } -} - -impl Expression for Verdict { - - fn to_expr(&self) -> *mut sys::nftnl_expr { - if let Some(immediate_const) = self.immediate_const() { - return unsafe { self.immediate_to_expr(immediate_const) }; - } - - match *self { - Verdict::Reject => { - unsafe { - let expr = try_alloc!(sys::nftnl_expr_alloc( - b"reject\0" as *const _ as *const c_char - )); - - sys::nftnl_expr_set_u32( - expr, - sys::NFTNL_EXPR_REJECT_TYPE as u16, - libc::NFT_REJECT_ICMPX_UNREACH as u32, - ); - - // TODO: Allow setting the ICMP code - sys::nftnl_expr_set_u8( - expr, - sys::NFTNL_EXPR_REJECT_CODE as u16, - libc::NFT_REJECT_ICMPX_HOST_UNREACH as u8, - ); - - expr - } - } - _ => unreachable!("unsupported verdict"), - } - } -} - -#[macro_export] -macro_rules! nft_expr_verdict { - (drop) => { - $crate::expr::Verdict::Drop - }; - (accept) => { - $crate::expr::Verdict::Accept - }; - (reject) => { - $crate::expr::Verdict::Reject - }; - (queue) => { - $crate::expr::Verdict::Queue - }; - (continue) => { - $crate::expr::Verdict::Continue - }; - (break) => { - $crate::expr::Verdict::Break - }; - (jump $chain:expr) => { - $crate::expr::Verdict::Jump { chain: $chain } - }; - (goto $chain:expr) => { - $crate::expr::Verdict::Goto { chain: $chain } - }; - (return) => { - $crate::expr::Verdict::Return - }; -} diff --git a/nftnl/src/expr/mod.rs b/nftnl/src/expr/mod.rs index 84d7035..3b49951 100644 --- a/nftnl/src/expr/mod.rs +++ b/nftnl/src/expr/mod.rs @@ -39,6 +39,9 @@ pub use self::meta::*; mod payload; pub use self::payload::*; +mod verdict; +pub use self::verdict::*; + #[macro_export(local_inner_macros)] macro_rules! nft_expr { (bitwise mask $mask:expr,xor $xor:expr) => { diff --git a/nftnl/src/expr/verdict.rs b/nftnl/src/expr/verdict.rs new file mode 100644 index 0000000..35bc893 --- /dev/null +++ b/nftnl/src/expr/verdict.rs @@ -0,0 +1,138 @@ +use super::Expression; +use nftnl_sys::{self as sys, libc::{self, c_char}}; +use std::{ffi::{CStr, CString}}; + +/// A verdict expression. In the background, this is usually an "Immediate" expression in nftnl +/// terms, but here it is simplified to only represent a verdict. +#[derive(Debug, Clone, Eq, PartialEq, Hash)] +pub enum Verdict { + /// Silently drop the packet. + Drop, + /// Accept the packet and let it pass. + Accept, + /// Reject the packet and return a message. + Reject, + Queue, + Continue, + Break, + Jump { + chain: CString, + }, + Goto { + chain: CString, + }, + Return, +} + +impl Verdict { + fn immediate_const(&self) -> Option<i32> { + match *self { + Verdict::Drop => Some(libc::NF_DROP), + Verdict::Accept => Some(libc::NF_ACCEPT), + Verdict::Queue => Some(libc::NF_QUEUE), + Verdict::Continue => Some(libc::NFT_CONTINUE), + Verdict::Break => Some(libc::NFT_BREAK), + Verdict::Jump { .. } => Some(libc::NFT_JUMP), + Verdict::Goto { .. } => Some(libc::NFT_GOTO), + Verdict::Return => Some(libc::NFT_RETURN), + _ => None, + } + } + + unsafe fn immediate_to_expr(&self, immediate_const: i32) -> *mut sys::nftnl_expr { + let expr = try_alloc!(sys::nftnl_expr_alloc( + b"immediate\0" as *const _ as *const c_char + )); + + sys::nftnl_expr_set_u32( + expr, + sys::NFTNL_EXPR_IMM_DREG as u16, + libc::NFT_REG_VERDICT as u32, + ); + + if let Some(chain) = self.chain() { + sys::nftnl_expr_set_str(expr, sys::NFTNL_EXPR_IMM_CHAIN as u16, chain.as_ptr()); + } + sys::nftnl_expr_set_u32( + expr, + sys::NFTNL_EXPR_IMM_VERDICT as u16, + immediate_const as u32, + ); + + expr + } + + fn chain(&self) -> Option<&CStr> { + match *self { + Verdict::Jump { ref chain } => Some(chain.as_c_str()), + Verdict::Goto { ref chain } => Some(chain.as_c_str()), + _ => None, + } + } +} + +impl Expression for Verdict { + + fn to_expr(&self) -> *mut sys::nftnl_expr { + if let Some(immediate_const) = self.immediate_const() { + return unsafe { self.immediate_to_expr(immediate_const) }; + } + + match *self { + Verdict::Reject => { + unsafe { + let expr = try_alloc!(sys::nftnl_expr_alloc( + b"reject\0" as *const _ as *const c_char + )); + + sys::nftnl_expr_set_u32( + expr, + sys::NFTNL_EXPR_REJECT_TYPE as u16, + libc::NFT_REJECT_ICMPX_UNREACH as u32, + ); + + // TODO: Allow setting the ICMP code + sys::nftnl_expr_set_u8( + expr, + sys::NFTNL_EXPR_REJECT_CODE as u16, + libc::NFT_REJECT_ICMPX_HOST_UNREACH as u8, + ); + + expr + } + } + _ => unreachable!("unsupported verdict"), + } + } +} + +#[macro_export] +macro_rules! nft_expr_verdict { + (drop) => { + $crate::expr::Verdict::Drop + }; + (accept) => { + $crate::expr::Verdict::Accept + }; + (reject) => { + $crate::expr::Verdict::Reject + }; + (queue) => { + $crate::expr::Verdict::Queue + }; + (continue) => { + $crate::expr::Verdict::Continue + }; + (break) => { + $crate::expr::Verdict::Break + }; + (jump $chain:expr) => { + $crate::expr::Verdict::Jump { chain: $chain } + }; + (goto $chain:expr) => { + $crate::expr::Verdict::Goto { chain: $chain } + }; + (return) => { + $crate::expr::Verdict::Return + }; +} |