aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Lönnhager <david.l@mullvad.net>2020-05-18 14:44:30 +0200
committerDavid Lönnhager <david.l@mullvad.net>2020-05-19 11:00:23 +0200
commit0fcc1f74a7a203b075ea9a0e84818902bab54c53 (patch)
tree9d1bd45dc77bdfca803d1ba0921f1e9e9a591e37
parente50e459d506f0f6e9e58e6d0298f1754e90aef98 (diff)
Move Verdict to its own module since it does not depend only on 'immediate' expressions
-rw-r--r--nftnl/src/expr/immediate.rs137
-rw-r--r--nftnl/src/expr/mod.rs3
-rw-r--r--nftnl/src/expr/verdict.rs138
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
+ };
+}