diff options
Diffstat (limited to 'src/rule.rs')
-rw-r--r-- | src/rule.rs | 73 |
1 files changed, 22 insertions, 51 deletions
diff --git a/src/rule.rs b/src/rule.rs index 5d13ac4..7f732d3 100644 --- a/src/rule.rs +++ b/src/rule.rs @@ -1,22 +1,24 @@ +use std::fmt::Debug; + use rustables_macros::nfnetlink_struct; +use crate::chain::Chain; +use crate::error::{BuilderError, QueryError}; use crate::expr::ExpressionList; -use crate::nlmsg::{NfNetlinkAttribute, NfNetlinkDeserializable, NfNetlinkObject, NfNetlinkWriter}; -use crate::parser::{DecodeError, Parsable}; +use crate::nlmsg::NfNetlinkObject; use crate::query::list_objects_with_data; use crate::sys::{ NFTA_RULE_CHAIN, NFTA_RULE_EXPRESSIONS, NFTA_RULE_HANDLE, NFTA_RULE_ID, NFTA_RULE_POSITION, - NFTA_RULE_TABLE, NFTA_RULE_USERDATA, NFT_MSG_DELRULE, NFT_MSG_NEWRULE, NLM_F_ACK, NLM_F_CREATE, + NFTA_RULE_TABLE, NFTA_RULE_USERDATA, NFT_MSG_DELRULE, NFT_MSG_NEWRULE, NLM_F_APPEND, + NLM_F_CREATE, }; use crate::ProtocolFamily; -use crate::{chain::Chain, MsgType}; -use std::convert::TryFrom; -use std::fmt::Debug; /// A nftables firewall rule. #[derive(Clone, PartialEq, Eq, Default, Debug)] #[nfnetlink_struct(derive_deserialize = false)] pub struct Rule { + family: ProtocolFamily, #[field(NFTA_RULE_TABLE)] table: String, #[field(NFTA_RULE_CHAIN)] @@ -31,78 +33,47 @@ pub struct Rule { userdata: Vec<u8>, #[field(NFTA_RULE_ID)] id: u32, - family: ProtocolFamily, } impl Rule { /// Creates a new rule object in the given [`Chain`]. /// /// [`Chain`]: struct.Chain.html - pub fn new(chain: &Chain) -> Result<Rule, DecodeError> { + pub fn new(chain: &Chain) -> Result<Rule, BuilderError> { Ok(Rule::default() .with_family(chain.get_family()) .with_table( chain .get_table() - .ok_or(DecodeError::MissingChainInformationError)?, + .ok_or(BuilderError::MissingChainInformationError)?, ) .with_chain( chain .get_name() - .ok_or(DecodeError::MissingChainInformationError)?, + .ok_or(BuilderError::MissingChainInformationError)?, )) } +} + +impl NfNetlinkObject for Rule { + const MSG_TYPE_ADD: u32 = NFT_MSG_NEWRULE; + const MSG_TYPE_DEL: u32 = NFT_MSG_DELRULE; - pub fn get_family(&self) -> ProtocolFamily { + fn get_family(&self) -> ProtocolFamily { self.family } - pub fn set_family(&mut self, family: ProtocolFamily) { + fn set_family(&mut self, family: ProtocolFamily) { self.family = family; } - pub fn with_family(mut self, family: ProtocolFamily) -> Self { - self.set_family(family); - self - } -} - -impl NfNetlinkObject for Rule { - fn add_or_remove<'a>(&self, writer: &mut NfNetlinkWriter<'a>, msg_type: MsgType, seq: u32) { - let raw_msg_type = match msg_type { - MsgType::Add => NFT_MSG_NEWRULE, - MsgType::Del => NFT_MSG_DELRULE, - } as u16; - writer.write_header( - raw_msg_type, - self.family, - (if let MsgType::Add = msg_type { - NLM_F_CREATE - } else { - 0 - } | NLM_F_ACK) as u16, - seq, - None, - ); - let buf = writer.add_data_zeroed(self.get_size()); - unsafe { - self.write_payload(buf.as_mut_ptr()); - } - writer.finalize_writing_object(); - } -} - -impl NfNetlinkDeserializable for Rule { - fn deserialize(buf: &[u8]) -> Result<(Self, &[u8]), DecodeError> { - let (mut obj, nfgenmsg, remaining_data) = - Self::parse_object(buf, NFT_MSG_NEWRULE, NFT_MSG_DELRULE)?; - obj.family = ProtocolFamily::try_from(nfgenmsg.nfgen_family as i32)?; - - Ok((obj, remaining_data)) + // append at the end of the chain, instead of the beginning + fn get_add_flags(&self) -> u32 { + NLM_F_CREATE | NLM_F_APPEND } } -pub fn list_rules_for_chain(chain: &Chain) -> Result<Vec<Rule>, crate::query::Error> { +pub fn list_rules_for_chain(chain: &Chain) -> Result<Vec<Rule>, QueryError> { let mut result = Vec::new(); list_objects_with_data( libc::NFT_MSG_GETRULE as u16, |