From ae7a95222b0b5fd3e8484177b3bf09a9195dcae9 Mon Sep 17 00:00:00 2001 From: Simon THOBY Date: Mon, 15 Nov 2021 21:41:17 +0100 Subject: tests: move common test code to a separate file Also: fix a few TODOs with the current expressions Fun fact: the test identified a problem in our implementation of Payload::Transport::build ! --- src/expr/payload.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/expr/payload.rs b/src/expr/payload.rs index 7612fd9..4ba47df 100644 --- a/src/expr/payload.rs +++ b/src/expr/payload.rs @@ -28,7 +28,7 @@ impl Payload { }), Payload::Transport(ref f) => RawPayload::Transport(RawPayloadData { offset: f.offset(), - len: f.offset(), + len: f.len(), }), } } -- cgit v1.2.3 From 4716eb28408422f1a5249eb39f75f67916ec5781 Mon Sep 17 00:00:00 2001 From: Simon THOBY Date: Mon, 15 Nov 2021 22:38:03 +0100 Subject: tests: add tests for `Set`s --- src/lib.rs | 3 ++- tests/lib.rs | 19 ++++++++++++++--- tests/set.rs | 68 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 86 insertions(+), 4 deletions(-) create mode 100644 tests/set.rs (limited to 'src') diff --git a/src/lib.rs b/src/lib.rs index 5cf9ca6..665f752 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -77,8 +77,8 @@ use thiserror::Error; extern crate log; pub mod sys; -use sys::libc; use std::{convert::TryFrom, ffi::c_void, ops::Deref}; +use sys::libc; macro_rules! try_alloc { ($e:expr) => {{ @@ -123,6 +123,7 @@ mod rule_methods; pub use rule_methods::{iface_index, Protocol, RuleMethods, Error as MatchError}; pub mod set; +pub use set::Set; /// The type of the message as it's sent to netfilter. A message consists of an object, such as a /// [`Table`], [`Chain`] or [`Rule`] for example, and a [`MsgType`] to describe what to do with diff --git a/tests/lib.rs b/tests/lib.rs index af599a5..c30f881 100644 --- a/tests/lib.rs +++ b/tests/lib.rs @@ -1,6 +1,7 @@ #![allow(dead_code)] use libc::{nlmsghdr, AF_UNIX, NFNETLINK_V0, NFNL_SUBSYS_NFTABLES}; -use rustables::{nft_nlmsg_maxsize, Chain, MsgType, NlMsg, ProtoFamily, Rule, Table}; +use rustables::set::SetKey; +use rustables::{nft_nlmsg_maxsize, Chain, MsgType, NlMsg, ProtoFamily, Rule, Set, Table}; use std::ffi::{c_void, CStr}; use std::mem::size_of; use std::rc::Rc; @@ -15,10 +16,14 @@ pub fn get_operation_from_nlmsghdr_type(x: u16) -> u8 { pub const TABLE_NAME: &[u8; 10] = b"mocktable\0"; pub const CHAIN_NAME: &[u8; 10] = b"mockchain\0"; +pub const SET_NAME: &[u8; 8] = b"mockset\0"; pub const TABLE_USERDATA: &[u8; 14] = b"mocktabledata\0"; pub const CHAIN_USERDATA: &[u8; 14] = b"mockchaindata\0"; pub const RULE_USERDATA: &[u8; 13] = b"mockruledata\0"; +pub const SET_USERDATA: &[u8; 12] = b"mocksetdata\0"; + +pub const SET_ID: u32 = 123456; type NetLinkType = u16; @@ -107,8 +112,16 @@ pub fn get_test_chain() -> Chain { } pub fn get_test_rule() -> Rule { - let rule = Rule::new(Rc::new(get_test_chain())); - rule + Rule::new(Rc::new(get_test_chain())) +} + +pub fn get_test_set<'a, T: SetKey>(table: &'a Table) -> Set<'a, T> { + Set::new( + CStr::from_bytes_with_nul(SET_NAME).unwrap(), + SET_ID, + table, + ProtoFamily::Ipv4, + ) } pub fn get_test_nlmsg_with_msg_type( diff --git a/tests/set.rs b/tests/set.rs new file mode 100644 index 0000000..a357a13 --- /dev/null +++ b/tests/set.rs @@ -0,0 +1,68 @@ +mod sys; +use std::net::{Ipv4Addr, Ipv6Addr}; + +use rustables::{set::SetKey, MsgType}; +use sys::*; + +mod lib; +use lib::*; + +#[test] +fn new_empty_set() { + let table = get_test_table(); + let mut set = get_test_set::(&table); + let (nlmsghdr, _nfgenmsg, raw_expr) = get_test_nlmsg(&mut set); + assert_eq!( + get_operation_from_nlmsghdr_type(nlmsghdr.nlmsg_type), + NFT_MSG_NEWSET as u8 + ); + assert_eq!(nlmsghdr.nlmsg_len, 80); + + assert_eq!( + raw_expr, + NetlinkExpr::List(vec![ + NetlinkExpr::Final(NFTA_SET_TABLE, TABLE_NAME.to_vec()), + NetlinkExpr::Final(NFTA_SET_NAME, SET_NAME.to_vec()), + NetlinkExpr::Final( + NFTA_SET_FLAGS, + ((libc::NFT_SET_ANONYMOUS | libc::NFT_SET_CONSTANT) as u32) + .to_be_bytes() + .to_vec() + ), + NetlinkExpr::Final(NFTA_SET_KEY_TYPE, Ipv4Addr::TYPE.to_be_bytes().to_vec()), + NetlinkExpr::Final(NFTA_SET_KEY_LEN, Ipv4Addr::LEN.to_be_bytes().to_vec()), + NetlinkExpr::Final(NFTA_SET_ID, SET_ID.to_be_bytes().to_vec()), + ]) + .to_raw() + ); +} + +#[test] +fn delete_empty_set() { + let table = get_test_table(); + let mut set = get_test_set::(&table); + let (nlmsghdr, _nfgenmsg, raw_expr) = get_test_nlmsg_with_msg_type(&mut set, MsgType::Del); + assert_eq!( + get_operation_from_nlmsghdr_type(nlmsghdr.nlmsg_type), + NFT_MSG_DELSET as u8 + ); + assert_eq!(nlmsghdr.nlmsg_len, 80); + + assert_eq!( + raw_expr, + NetlinkExpr::List(vec![ + NetlinkExpr::Final(NFTA_SET_TABLE, TABLE_NAME.to_vec()), + NetlinkExpr::Final(NFTA_SET_NAME, SET_NAME.to_vec()), + NetlinkExpr::Final( + NFTA_SET_FLAGS, + ((libc::NFT_SET_ANONYMOUS | libc::NFT_SET_CONSTANT) as u32) + .to_be_bytes() + .to_vec() + ), + NetlinkExpr::Final(NFTA_SET_KEY_TYPE, Ipv6Addr::TYPE.to_be_bytes().to_vec()), + NetlinkExpr::Final(NFTA_SET_KEY_LEN, Ipv6Addr::LEN.to_be_bytes().to_vec()), + NetlinkExpr::Final(NFTA_SET_ID, SET_ID.to_be_bytes().to_vec()), + ]) + .to_raw() + ); +} -- cgit v1.2.3 From c67c3d1e8d0c414dee5b0c947c6af1b4a30411bd Mon Sep 17 00:00:00 2001 From: Simon THOBY Date: Mon, 15 Nov 2021 23:23:12 +0100 Subject: ergonomic change: delete the reference on `Set` objects --- src/expr/lookup.rs | 2 +- src/set.rs | 28 ++++++++++++++-------------- tests/expr.rs | 2 +- tests/lib.rs | 4 ++-- tests/set.rs | 6 ++---- 5 files changed, 20 insertions(+), 22 deletions(-) (limited to 'src') diff --git a/src/expr/lookup.rs b/src/expr/lookup.rs index 8e288a0..fa12197 100644 --- a/src/expr/lookup.rs +++ b/src/expr/lookup.rs @@ -13,7 +13,7 @@ pub struct Lookup { impl Lookup { /// Creates a new lookup entry. /// May return None if the set have no name. - pub fn new(set: &Set<'_, K>) -> Option { + pub fn new(set: &Set) -> Option { set.get_name().map(|set_name| Lookup { set_name: set_name.to_owned(), set_id: set.get_id(), diff --git a/src/set.rs b/src/set.rs index d6b9514..1e20475 100644 --- a/src/set.rs +++ b/src/set.rs @@ -1,5 +1,5 @@ -use crate::{table::Table, MsgType, ProtoFamily}; use crate::sys::{self, libc}; +use crate::{table::Table, MsgType, ProtoFamily}; use std::{ cell::Cell, ffi::{c_void, CStr, CString}, @@ -26,15 +26,15 @@ macro_rules! nft_set { }}; } -pub struct Set<'a, K> { +pub struct Set { pub(crate) set: *mut sys::nftnl_set, - pub(crate) table: &'a Table, + pub(crate) table: Rc, pub(crate) family: ProtoFamily, _marker: ::std::marker::PhantomData, } -impl<'a, K> Set<'a, K> { - pub fn new(name: &CStr, id: u32, table: &'a Table, family: ProtoFamily) -> Self +impl Set { + pub fn new(name: &CStr, id: u32, table: Rc
, family: ProtoFamily) -> Self where K: SetKey, { @@ -63,7 +63,7 @@ impl<'a, K> Set<'a, K> { } } - pub unsafe fn from_raw(set: *mut sys::nftnl_set, table: &'a Table, family: ProtoFamily) -> Self + pub unsafe fn from_raw(set: *mut sys::nftnl_set, table: Rc
, family: ProtoFamily) -> Self where K: SetKey, { @@ -95,7 +95,7 @@ impl<'a, K> Set<'a, K> { } } - pub fn elems_iter(&'a self) -> SetElemsIter<'a, K> { + pub fn elems_iter(&self) -> SetElemsIter { SetElemsIter::new(self) } @@ -146,13 +146,13 @@ impl<'a, K> Set<'a, K> { } } -impl<'a, K> Debug for Set<'a, K> { +impl Debug for Set { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { write!(f, "{:?}", self.get_str()) } } -unsafe impl<'a, K> crate::NlMsg for Set<'a, K> { +unsafe impl crate::NlMsg for Set { unsafe fn write(&self, buf: *mut c_void, seq: u32, msg_type: MsgType) { let type_ = match msg_type { MsgType::Add => libc::NFT_MSG_NEWSET, @@ -169,20 +169,20 @@ unsafe impl<'a, K> crate::NlMsg for Set<'a, K> { } } -impl<'a, K> Drop for Set<'a, K> { +impl Drop for Set { fn drop(&mut self) { unsafe { sys::nftnl_set_free(self.set) }; } } pub struct SetElemsIter<'a, K> { - set: &'a Set<'a, K>, + set: &'a Set, iter: *mut sys::nftnl_set_elems_iter, ret: Rc>, } impl<'a, K> SetElemsIter<'a, K> { - fn new(set: &'a Set<'a, K>) -> Self { + fn new(set: &'a Set) -> Self { let iter = try_alloc!(unsafe { sys::nftnl_set_elems_iter_create(set.set as *const sys::nftnl_set) }); @@ -194,7 +194,7 @@ impl<'a, K> SetElemsIter<'a, K> { } } -impl<'a, K: 'a> Iterator for SetElemsIter<'a, K> { +impl<'a, K> Iterator for SetElemsIter<'a, K> { type Item = SetElemsMsg<'a, K>; fn next(&mut self) -> Option { @@ -219,7 +219,7 @@ impl<'a, K> Drop for SetElemsIter<'a, K> { } pub struct SetElemsMsg<'a, K> { - set: &'a Set<'a, K>, + set: &'a Set, iter: *mut sys::nftnl_set_elems_iter, ret: Rc>, } diff --git a/tests/expr.rs b/tests/expr.rs index 9f1644c..4af18f2 100644 --- a/tests/expr.rs +++ b/tests/expr.rs @@ -281,7 +281,7 @@ fn lookup_expr_is_valid() { let set_name = &CStr::from_bytes_with_nul(b"mockset\0").unwrap(); let mut rule = get_test_rule(); let table = rule.get_chain().get_table(); - let mut set = Set::new(set_name, 0, &table, ProtoFamily::Inet); + let mut set = Set::new(set_name, 0, table, ProtoFamily::Inet); let address: Ipv4Addr = [8, 8, 8, 8].into(); set.add(&address); let lookup = Lookup::new(&set).unwrap(); diff --git a/tests/lib.rs b/tests/lib.rs index c30f881..0d7132c 100644 --- a/tests/lib.rs +++ b/tests/lib.rs @@ -115,11 +115,11 @@ pub fn get_test_rule() -> Rule { Rule::new(Rc::new(get_test_chain())) } -pub fn get_test_set<'a, T: SetKey>(table: &'a Table) -> Set<'a, T> { +pub fn get_test_set() -> Set { Set::new( CStr::from_bytes_with_nul(SET_NAME).unwrap(), SET_ID, - table, + Rc::new(get_test_table()), ProtoFamily::Ipv4, ) } diff --git a/tests/set.rs b/tests/set.rs index a357a13..d5b2ad7 100644 --- a/tests/set.rs +++ b/tests/set.rs @@ -9,8 +9,7 @@ use lib::*; #[test] fn new_empty_set() { - let table = get_test_table(); - let mut set = get_test_set::(&table); + let mut set = get_test_set::(); let (nlmsghdr, _nfgenmsg, raw_expr) = get_test_nlmsg(&mut set); assert_eq!( get_operation_from_nlmsghdr_type(nlmsghdr.nlmsg_type), @@ -39,8 +38,7 @@ fn new_empty_set() { #[test] fn delete_empty_set() { - let table = get_test_table(); - let mut set = get_test_set::(&table); + let mut set = get_test_set::(); let (nlmsghdr, _nfgenmsg, raw_expr) = get_test_nlmsg_with_msg_type(&mut set, MsgType::Del); assert_eq!( get_operation_from_nlmsghdr_type(nlmsghdr.nlmsg_type), -- cgit v1.2.3