-
Notifications
You must be signed in to change notification settings - Fork 29
/
Copy pathrule.rs
98 lines (88 loc) · 3.06 KB
/
rule.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
use crate::{chain::Chain, expr::Expression, MsgType};
use nftnl_sys::{self as sys, libc};
use std::ffi::c_void;
use std::os::raw::c_char;
/// A nftables firewall rule.
pub struct Rule<'a> {
rule: *mut sys::nftnl_rule,
chain: &'a Chain<'a>,
}
// Safety: It should be safe to pass this around and *read* from it
// from multiple threads
unsafe impl Send for Rule<'_> {}
unsafe impl Sync for Rule<'_> {}
impl<'a> Rule<'a> {
/// Creates a new rule object in the given [`Chain`].
///
/// [`Chain`]: struct.Chain.html
pub fn new(chain: &'a Chain<'_>) -> Rule<'a> {
unsafe {
let rule = try_alloc!(sys::nftnl_rule_alloc());
sys::nftnl_rule_set_u32(
rule,
sys::NFTNL_RULE_FAMILY as u16,
chain.get_table().get_family() as u32,
);
sys::nftnl_rule_set_str(
rule,
sys::NFTNL_RULE_TABLE as u16,
chain.get_table().get_name().as_ptr(),
);
sys::nftnl_rule_set_str(
rule,
sys::NFTNL_RULE_CHAIN as u16,
chain.get_name().as_ptr(),
);
Rule { rule, chain }
}
}
/// Sets the position of this rule within the chain it lives in. By default a new rule is added
/// to the end of the chain.
pub fn set_position(&mut self, position: u64) {
unsafe {
sys::nftnl_rule_set_u64(self.rule, sys::NFTNL_RULE_POSITION as u16, position);
}
}
pub fn set_handle(&mut self, handle: u64) {
unsafe {
sys::nftnl_rule_set_u64(self.rule, sys::NFTNL_RULE_HANDLE as u16, handle);
}
}
/// Adds an expression to this rule. Expressions are evaluated from first to last added.
/// As soon as an expression does not match the packet it's being evaluated for, evaluation
/// stops and the packet is evaluated against the next rule in the chain.
pub fn add_expr(&mut self, expr: &impl Expression) {
unsafe { sys::nftnl_rule_add_expr(self.rule, expr.to_expr(self)) }
}
/// Returns a reference to the [`Chain`] this rule lives in.
///
/// [`Chain`]: struct.Chain.html
pub fn get_chain(&self) -> &Chain<'_> {
self.chain
}
}
unsafe impl crate::NlMsg for Rule<'_> {
unsafe fn write(&self, buf: *mut c_void, seq: u32, msg_type: MsgType) {
let type_ = match msg_type {
MsgType::Add => libc::NFT_MSG_NEWRULE,
MsgType::Del => libc::NFT_MSG_DELRULE,
};
let flags: u16 = match msg_type {
MsgType::Add => (libc::NLM_F_CREATE | libc::NLM_F_APPEND | libc::NLM_F_EXCL) as u16,
MsgType::Del => 0u16,
};
let header = sys::nftnl_nlmsg_build_hdr(
buf as *mut c_char,
type_ as u16,
self.chain.get_table().get_family() as u16,
flags,
seq,
);
sys::nftnl_rule_nlmsg_build_payload(header, self.rule);
}
}
impl Drop for Rule<'_> {
fn drop(&mut self) {
unsafe { sys::nftnl_rule_free(self.rule) };
}
}