diff options
-rw-r--r-- | rustables/Cargo.toml | 1 | ||||
-rw-r--r-- | rustables/examples/add-rules.rs | 67 | ||||
-rw-r--r-- | rustables/examples/filter-ethernet.rs | 41 | ||||
-rw-r--r-- | rustables/src/batch.rs | 16 | ||||
-rw-r--r-- | rustables/src/chain.rs | 21 | ||||
-rw-r--r-- | rustables/src/lib.rs | 19 | ||||
-rw-r--r-- | rustables/src/rule.rs | 21 | ||||
-rw-r--r-- | rustables/src/set.rs | 6 | ||||
-rw-r--r-- | rustables/src/table.rs | 10 |
9 files changed, 111 insertions, 91 deletions
diff --git a/rustables/Cargo.toml b/rustables/Cargo.toml index 83788cc..bf9ee2e 100644 --- a/rustables/Cargo.toml +++ b/rustables/Cargo.toml @@ -12,6 +12,7 @@ edition = "2018" [features] query = [] +unsafe-raw-handles = [] nftnl-1-0-7 = ["rustables-sys/nftnl-1-0-7"] nftnl-1-0-8 = ["rustables-sys/nftnl-1-0-8"] nftnl-1-0-9 = ["rustables-sys/nftnl-1-0-9"] diff --git a/rustables/examples/add-rules.rs b/rustables/examples/add-rules.rs index d114ef1..4fea491 100644 --- a/rustables/examples/add-rules.rs +++ b/rustables/examples/add-rules.rs @@ -37,11 +37,12 @@ //! ``` use ipnetwork::{IpNetwork, Ipv4Network}; -use nftnl::{nft_expr, nftnl_sys::libc, Batch, Chain, FinalizedBatch, ProtoFamily, Rule, Table}; +use rustables::{nft_expr, rustables_sys::libc, Batch, Chain, FinalizedBatch, ProtoFamily, Rule, Table}; use std::{ ffi::{self, CString}, io, net::Ipv4Addr, + rc::Rc }; const TABLE_NAME: &str = "example-table"; @@ -55,34 +56,37 @@ fn main() -> Result<(), Error> { let mut batch = Batch::new(); // Create a netfilter table operating on both IPv4 and IPv6 (ProtoFamily::Inet) - let table = Table::new(&CString::new(TABLE_NAME).unwrap(), ProtoFamily::Inet); + let table = Rc::new(Table::new(&CString::new(TABLE_NAME).unwrap(), ProtoFamily::Inet)); // Add the table to the batch with the `MsgType::Add` type, thus instructing netfilter to add // this table under its `ProtoFamily::Inet` ruleset. - batch.add(&table, nftnl::MsgType::Add); + batch.add(&Rc::clone(&table), rustables::MsgType::Add); // Create input and output chains under the table we created above. - let mut out_chain = Chain::new(&CString::new(OUT_CHAIN_NAME).unwrap(), &table); - let mut in_chain = Chain::new(&CString::new(IN_CHAIN_NAME).unwrap(), &table); - // Hook the chains to the input and output event hooks, with highest priority (priority zero). // See the `Chain::set_hook` documentation for details. - out_chain.set_hook(nftnl::Hook::Out, 0); - in_chain.set_hook(nftnl::Hook::In, 0); + let mut out_chain = Chain::new(&CString::new(OUT_CHAIN_NAME).unwrap(), Rc::clone(&table)); + let mut in_chain = Chain::new(&CString::new(IN_CHAIN_NAME).unwrap(), Rc::clone(&table)); + + out_chain.set_hook(rustables::Hook::Out, 0); + in_chain.set_hook(rustables::Hook::In, 0); // Set the default policies on the chains. If no rule matches a packet processed by the // `out_chain` or the `in_chain` it will accept the packet. - out_chain.set_policy(nftnl::Policy::Accept); - in_chain.set_policy(nftnl::Policy::Accept); + out_chain.set_policy(rustables::Policy::Accept); + in_chain.set_policy(rustables::Policy::Accept); + + let out_chain = Rc::new(out_chain); + let in_chain = Rc::new(in_chain); // Add the two chains to the batch with the `MsgType` to tell netfilter to create the chains // under the table. - batch.add(&out_chain, nftnl::MsgType::Add); - batch.add(&in_chain, nftnl::MsgType::Add); + batch.add(&Rc::clone(&out_chain), rustables::MsgType::Add); + batch.add(&Rc::clone(&in_chain), rustables::MsgType::Add); // === ADD RULE ALLOWING ALL TRAFFIC TO THE LOOPBACK DEVICE === // Create a new rule object under the input chain. - let mut allow_loopback_in_rule = Rule::new(&in_chain); + let mut allow_loopback_in_rule = Rule::new(Rc::clone(&in_chain)); // Lookup the interface index of the loopback interface. let lo_iface_index = iface_index("lo")?; @@ -103,11 +107,11 @@ fn main() -> Result<(), Error> { allow_loopback_in_rule.add_expr(&nft_expr!(verdict accept)); // Add the rule to the batch. - batch.add(&allow_loopback_in_rule, nftnl::MsgType::Add); + batch.add(&allow_loopback_in_rule, rustables::MsgType::Add); // === ADD A RULE ALLOWING (AND COUNTING) ALL PACKETS TO THE 10.1.0.0/24 NETWORK === - let mut block_out_to_private_net_rule = Rule::new(&out_chain); + let mut block_out_to_private_net_rule = Rule::new(Rc::clone(&out_chain)); let private_net_ip = Ipv4Addr::new(10, 1, 0, 0); let private_net_prefix = 24; let private_net = IpNetwork::V4(Ipv4Network::new(private_net_ip, private_net_prefix)?); @@ -140,11 +144,11 @@ fn main() -> Result<(), Error> { // Add the rule to the batch. Without this nothing would be sent over netlink and netfilter, // and all the work on `block_out_to_private_net_rule` so far would go to waste. - batch.add(&block_out_to_private_net_rule, nftnl::MsgType::Add); + batch.add(&block_out_to_private_net_rule, rustables::MsgType::Add); // === ADD A RULE ALLOWING ALL OUTGOING ICMPv6 PACKETS WITH TYPE 133 AND CODE 0 === - let mut allow_router_solicitation = Rule::new(&out_chain); + let mut allow_router_solicitation = Rule::new(Rc::clone(&out_chain)); // Check that the packet is IPv6 and ICMPv6 allow_router_solicitation.add_expr(&nft_expr!(meta nfproto)); @@ -152,18 +156,18 @@ fn main() -> Result<(), Error> { allow_router_solicitation.add_expr(&nft_expr!(meta l4proto)); allow_router_solicitation.add_expr(&nft_expr!(cmp == libc::IPPROTO_ICMPV6 as u8)); - allow_router_solicitation.add_expr(&nftnl::expr::Payload::Transport( - nftnl::expr::TransportHeaderField::Icmpv6(nftnl::expr::Icmpv6HeaderField::Type), + allow_router_solicitation.add_expr(&rustables::expr::Payload::Transport( + rustables::expr::TransportHeaderField::Icmpv6(rustables::expr::Icmpv6HeaderField::Type), )); allow_router_solicitation.add_expr(&nft_expr!(cmp == 133u8)); - allow_router_solicitation.add_expr(&nftnl::expr::Payload::Transport( - nftnl::expr::TransportHeaderField::Icmpv6(nftnl::expr::Icmpv6HeaderField::Code), + allow_router_solicitation.add_expr(&rustables::expr::Payload::Transport( + rustables::expr::TransportHeaderField::Icmpv6(rustables::expr::Icmpv6HeaderField::Code), )); allow_router_solicitation.add_expr(&nft_expr!(cmp == 0u8)); allow_router_solicitation.add_expr(&nft_expr!(verdict accept)); - batch.add(&allow_router_solicitation, nftnl::MsgType::Add); + batch.add(&allow_router_solicitation, rustables::MsgType::Add); // === FINALIZE THE TRANSACTION AND SEND THE DATA TO NETFILTER === @@ -171,11 +175,14 @@ fn main() -> Result<(), Error> { // netfilter the we reached the end of the transaction message. It's also converted to a type // that implements `IntoIterator<Item = &'a [u8]>`, thus allowing us to get the raw netlink data // out so it can be sent over a netlink socket to netfilter. - let finalized_batch = batch.finalize(); - - // Send the entire batch and process any returned messages. - send_and_process(&finalized_batch)?; - Ok(()) + match batch.finalize() { + Some(mut finalized_batch) => { + // Send the entire batch and process any returned messages. + send_and_process(&mut finalized_batch)?; + Ok(()) + }, + None => todo!() + } } // Look up the interface index for a given interface name. @@ -189,15 +196,15 @@ fn iface_index(name: &str) -> Result<libc::c_uint, Error> { } } -fn send_and_process(batch: &FinalizedBatch) -> Result<(), Error> { +fn send_and_process(batch: &mut FinalizedBatch) -> Result<(), Error> { // Create a netlink socket to netfilter. let socket = mnl::Socket::new(mnl::Bus::Netfilter)?; // Send all the bytes in the batch. - socket.send_all(batch)?; + socket.send_all(&mut *batch)?; // Try to parse the messages coming back from netfilter. This part is still very unclear. let portid = socket.portid(); - let mut buffer = vec![0; nftnl::nft_nlmsg_maxsize() as usize]; + let mut buffer = vec![0; rustables::nft_nlmsg_maxsize() as usize]; let very_unclear_what_this_is_for = 2; while let Some(message) = socket_recv(&socket, &mut buffer[..])? { match mnl::cb_run(message, very_unclear_what_this_is_for, portid)? { diff --git a/rustables/examples/filter-ethernet.rs b/rustables/examples/filter-ethernet.rs index 6cebfc4..23be8a1 100644 --- a/rustables/examples/filter-ethernet.rs +++ b/rustables/examples/filter-ethernet.rs @@ -22,8 +22,8 @@ //! # nft delete table inet example-filter-ethernet //! ``` -use nftnl::{nft_expr, nftnl_sys::libc, Batch, Chain, FinalizedBatch, ProtoFamily, Rule, Table}; -use std::{ffi::CString, io}; +use rustables::{nft_expr, rustables_sys::libc, Batch, Chain, FinalizedBatch, ProtoFamily, Rule, Table}; +use std::{ffi::CString, io, rc::Rc}; const TABLE_NAME: &str = "example-filter-ethernet"; const OUT_CHAIN_NAME: &str = "chain-for-outgoing-packets"; @@ -34,17 +34,18 @@ fn main() -> Result<(), Error> { // For verbose explanations of what all these lines up until the rule creation does, see the // `add-rules` example. let mut batch = Batch::new(); - let table = Table::new(&CString::new(TABLE_NAME).unwrap(), ProtoFamily::Inet); - batch.add(&table, nftnl::MsgType::Add); + let table = Rc::new(Table::new(&CString::new(TABLE_NAME).unwrap(), ProtoFamily::Inet)); + batch.add(&Rc::clone(&table), rustables::MsgType::Add); - let mut out_chain = Chain::new(&CString::new(OUT_CHAIN_NAME).unwrap(), &table); - out_chain.set_hook(nftnl::Hook::Out, 3); - out_chain.set_policy(nftnl::Policy::Accept); - batch.add(&out_chain, nftnl::MsgType::Add); + let mut out_chain = Chain::new(&CString::new(OUT_CHAIN_NAME).unwrap(), Rc::clone(&table)); + out_chain.set_hook(rustables::Hook::Out, 3); + out_chain.set_policy(rustables::Policy::Accept); + let out_chain = Rc::new(out_chain); + batch.add(&Rc::clone(&out_chain), rustables::MsgType::Add); // === ADD RULE DROPPING ALL TRAFFIC TO THE MAC ADDRESS IN `BLOCK_THIS_MAC` === - let mut block_ethernet_rule = Rule::new(&out_chain); + let mut block_ethernet_rule = Rule::new(Rc::clone(&out_chain)); // Check that the interface type is an ethernet interface. Must be done before we can check // payload values in the ethernet header. @@ -58,7 +59,7 @@ fn main() -> Result<(), Error> { // Drop the matching packets. block_ethernet_rule.add_expr(&nft_expr!(verdict drop)); - batch.add(&block_ethernet_rule, nftnl::MsgType::Add); + batch.add(&block_ethernet_rule, rustables::MsgType::Add); // === FOR FUN, ADD A PACKET THAT MATCHES 50% OF ALL PACKETS === @@ -66,7 +67,7 @@ fn main() -> Result<(), Error> { // So after a number of packets has passed through this rule, the first counter should have a // value approximately double that of the second counter. This rule has no verdict, so it never // does anything with the matching packets. - let mut random_rule = Rule::new(&out_chain); + let mut random_rule = Rule::new(Rc::clone(&out_chain)); // This counter expression will be evaluated (and increment the counter) for all packets coming // through. random_rule.add_expr(&nft_expr!(counter)); @@ -79,24 +80,28 @@ fn main() -> Result<(), Error> { // Add a second counter. This will only be incremented for the packets passing the random check. random_rule.add_expr(&nft_expr!(counter)); - batch.add(&random_rule, nftnl::MsgType::Add); + batch.add(&random_rule, rustables::MsgType::Add); // === FINALIZE THE TRANSACTION AND SEND THE DATA TO NETFILTER === - let finalized_batch = batch.finalize(); - send_and_process(&finalized_batch)?; - Ok(()) + match batch.finalize() { + Some(mut finalized_batch) => { + send_and_process(&mut finalized_batch)?; + Ok(()) + }, + None => todo!() + } } -fn send_and_process(batch: &FinalizedBatch) -> Result<(), Error> { +fn send_and_process(batch: &mut FinalizedBatch) -> Result<(), Error> { // Create a netlink socket to netfilter. let socket = mnl::Socket::new(mnl::Bus::Netfilter)?; // Send all the bytes in the batch. - socket.send_all(batch)?; + socket.send_all(&mut *batch)?; // Try to parse the messages coming back from netfilter. This part is still very unclear. let portid = socket.portid(); - let mut buffer = vec![0; nftnl::nft_nlmsg_maxsize() as usize]; + let mut buffer = vec![0; rustables::nft_nlmsg_maxsize() as usize]; let very_unclear_what_this_is_for = 2; while let Some(message) = socket_recv(&socket, &mut buffer[..])? { match mnl::cb_run(message, very_unclear_what_this_is_for, portid)? { diff --git a/rustables/src/batch.rs b/rustables/src/batch.rs index 24eca8e..2af1a7c 100644 --- a/rustables/src/batch.rs +++ b/rustables/src/batch.rs @@ -27,11 +27,6 @@ pub struct Batch { is_empty: bool, } -// Safety: It should be safe to pass this around and *read* from it -// from multiple threads -unsafe impl Send for Batch {} -unsafe impl Sync for Batch {} - impl Batch { /// Creates a new nftnl batch with the [default page size]. /// @@ -120,11 +115,13 @@ impl Batch { self.next(); } + #[cfg(feature = "unsafe-raw-handles")] /// Returns the raw handle. pub fn as_ptr(&self) -> *const sys::nftnl_batch { self.batch as *const sys::nftnl_batch } + #[cfg(feature = "unsafe-raw-handles")] /// Returns a mutable version of the raw handle. pub fn as_mut_ptr(&mut self) -> *mut sys::nftnl_batch { self.batch @@ -151,7 +148,7 @@ pub struct FinalizedBatch { impl FinalizedBatch { /// Returns the iterator over byte buffers to send to netlink. pub fn iter(&mut self) -> Iter<'_> { - let num_pages = unsafe { sys::nftnl_batch_iovec_len(self.batch.as_mut_ptr()) as usize }; + let num_pages = unsafe { sys::nftnl_batch_iovec_len(self.batch.batch) as usize }; let mut iovecs = vec![ libc::iovec { iov_base: ptr::null_mut(), @@ -161,7 +158,7 @@ impl FinalizedBatch { ]; let iovecs_ptr = iovecs.as_mut_ptr() as *mut [u8; 0]; unsafe { - sys::nftnl_batch_iovec(self.batch.as_mut_ptr(), iovecs_ptr, num_pages as u32); + sys::nftnl_batch_iovec(self.batch.batch, iovecs_ptr, num_pages as u32); } Iter { iovecs: iovecs.into_iter(), @@ -184,11 +181,6 @@ pub struct Iter<'a> { _marker: ::std::marker::PhantomData<&'a ()>, } -// Safety: It should be safe to pass this around and *read* from it -// from multiple threads. -unsafe impl<'a> Send for Iter<'a> {} -unsafe impl<'a> Sync for Iter<'a> {} - impl<'a> Iterator for Iter<'a> { type Item = &'a [u8]; diff --git a/rustables/src/chain.rs b/rustables/src/chain.rs index 516536c..a5e732e 100644 --- a/rustables/src/chain.rs +++ b/rustables/src/chain.rs @@ -1,11 +1,11 @@ use crate::{MsgType, Table}; use rustables_sys::{self as sys, libc}; -use std::sync::Arc; use std::{ convert::TryFrom, ffi::{c_void, CStr, CString}, fmt, os::raw::c_char, + rc::Rc, }; pub type Priority = i32; @@ -71,19 +71,14 @@ impl ChainType { /// [`set_hook`]: #method.set_hook pub struct Chain { chain: *mut sys::nftnl_chain, - table: Arc<Table>, + table: Rc<Table>, } -// Safety: It should be safe to pass this around and *read* from it -// from multiple threads -unsafe impl Send for Chain {} -unsafe impl Sync for Chain {} - impl Chain { /// Creates a new chain instance inside the given [`Table`] and with the given name. /// /// [`Table`]: struct.Table.html - pub fn new<T: AsRef<CStr>>(name: &T, table: Arc<Table>) -> Chain { + pub fn new<T: AsRef<CStr>>(name: &T, table: Rc<Table>) -> Chain { unsafe { let chain = try_alloc!(sys::nftnl_chain_alloc()); sys::nftnl_chain_set_u32( @@ -101,7 +96,7 @@ impl Chain { } } - pub unsafe fn from_raw(chain: *mut sys::nftnl_chain, table: Arc<Table>) -> Self { + pub unsafe fn from_raw(chain: *mut sys::nftnl_chain, table: Rc<Table>) -> Self { Chain { chain, table } } @@ -183,15 +178,17 @@ impl Chain { /// Returns a reference to the [`Table`] this chain belongs to /// /// [`Table`]: struct.Table.html - pub fn get_table(&self) -> Arc<Table> { + pub fn get_table(&self) -> Rc<Table> { self.table.clone() } + #[cfg(feature = "unsafe-raw-handles")] /// Returns the raw handle. pub fn as_ptr(&self) -> *const sys::nftnl_chain { self.chain as *const sys::nftnl_chain } + #[cfg(feature = "unsafe-raw-handles")] /// Returns a mutable version of the raw handle. pub fn as_mut_ptr(&mut self) -> *mut sys::nftnl_chain { self.chain @@ -241,7 +238,7 @@ impl Drop for Chain { #[cfg(feature = "query")] pub fn get_chains_cb<'a>( header: &libc::nlmsghdr, - (table, chains): &mut (&Arc<Table>, &mut Vec<Chain>), + (table, chains): &mut (&Rc<Table>, &mut Vec<Chain>), ) -> libc::c_int { unsafe { let chain = sys::nftnl_chain_alloc(); @@ -285,6 +282,6 @@ pub fn get_chains_cb<'a>( } #[cfg(feature = "query")] -pub fn list_chains_for_table(table: Arc<Table>) -> Result<Vec<Chain>, crate::query::Error> { +pub fn list_chains_for_table(table: Rc<Table>) -> Result<Vec<Chain>, crate::query::Error> { crate::query::list_objects_with_data(libc::NFT_MSG_GETCHAIN as u16, get_chains_cb, &table, None) } diff --git a/rustables/src/lib.rs b/rustables/src/lib.rs index c5d53c0..1397245 100644 --- a/rustables/src/lib.rs +++ b/rustables/src/lib.rs @@ -48,6 +48,25 @@ //! See the documentation for the corresponding sys crate for details: [`rustables-sys`]. //! This crate has the same features as the sys crate, and selecting version works the same. //! +//! # Access to raw handles +//! +//! Retrieving raw handles is considered unsafe and should only ever be enabled if you absoluetely +//! need it. It is disabled by default and hidden behind the feature gate `unsafe-raw-handles`. +//! The reason for that special treatment is we cannot guarantee the lack of aliasing. For example, +//! a program using a const handle to a object in a thread and writing through a mutable handle +//! in another could reach all kind of undefined (and dangerous!) behaviors. +//! By enabling that feature flag, you acknowledge that guaranteeing the respect of safety +//! invariants is now your responsibility! +//! Despite these shortcomings, that feature is still available because it may allow you to perform +//! manipulations that this library doesn't currently expose. If that is your case, we would +//! be very happy to hear from you and maybe help you get the necessary functionality upstream. +//! +//! Our current lack of confidence in our availability to provide a safe abstraction over the +//! use of raw handles in the face of concurrency is the reason we decided to settly on `Rc` +//! pointers instead of `Arc` (besides, this should gives us some nice performance boost, not +//! that it matters much of course) and why we do not declare the types exposes by the library +//! as `Send` nor `Sync`. +//! //! [`libnftnl`]: https://netfilter.org/projects/libnftnl/ //! [`nftables`]: https://netfilter.org/projects/nftables/ //! [`rustables-sys`]: https://crates.io/crates/rustables-sys diff --git a/rustables/src/rule.rs b/rustables/src/rule.rs index cdd1876..6e15db7 100644 --- a/rustables/src/rule.rs +++ b/rustables/src/rule.rs @@ -3,24 +3,19 @@ use rustables_sys::{self as sys, libc}; use std::ffi::{c_void, CStr, CString}; use std::fmt::Debug; use std::os::raw::c_char; -use std::sync::Arc; +use std::rc::Rc; /// A nftables firewall rule. pub struct Rule { rule: *mut sys::nftnl_rule, - chain: Arc<Chain>, + chain: Rc<Chain>, } -// 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 Rule { /// Creates a new rule object in the given [`Chain`]. /// /// [`Chain`]: struct.Chain.html - pub fn new(chain: Arc<Chain>) -> Rule { + pub fn new(chain: Rc<Chain>) -> Rule { unsafe { let rule = try_alloc!(sys::nftnl_rule_alloc()); sys::nftnl_rule_set_u32( @@ -43,7 +38,7 @@ impl Rule { } } - pub unsafe fn from_raw(rule: *mut sys::nftnl_rule, chain: Arc<Chain>) -> Self { + pub unsafe fn from_raw(rule: *mut sys::nftnl_rule, chain: Rc<Chain>) -> Self { Rule { rule, chain } } @@ -79,7 +74,7 @@ impl Rule { /// Returns a reference to the [`Chain`] this rule lives in. /// /// [`Chain`]: struct.Chain.html - pub fn get_chain(&self) -> Arc<Chain> { + pub fn get_chain(&self) -> Rc<Chain> { self.chain.clone() } @@ -116,11 +111,13 @@ impl Rule { } } + #[cfg(feature = "unsafe-raw-handles")] /// Returns the raw handle. pub fn as_ptr(&self) -> *const sys::nftnl_rule { self.rule as *const sys::nftnl_rule } + #[cfg(feature = "unsafe-raw-handles")] /// Returns a mutable version of the raw handle. pub fn as_mut_ptr(&mut self) -> *mut sys::nftnl_rule { self.rule @@ -169,7 +166,7 @@ impl Drop for Rule { #[cfg(feature = "query")] pub fn get_rules_cb( header: &libc::nlmsghdr, - (chain, rules): &mut (&Arc<Chain>, &mut Vec<Rule>), + (chain, rules): &mut (&Rc<Chain>, &mut Vec<Rule>), ) -> libc::c_int { unsafe { let rule = sys::nftnl_rule_alloc(); @@ -189,7 +186,7 @@ pub fn get_rules_cb( } #[cfg(feature = "query")] -pub fn list_rules_for_chain(chain: &Arc<Chain>) -> Result<Vec<Rule>, crate::query::Error> { +pub fn list_rules_for_chain(chain: &Rc<Chain>) -> Result<Vec<Rule>, crate::query::Error> { crate::query::list_objects_with_data( libc::NFT_MSG_GETRULE as u16, get_rules_cb, diff --git a/rustables/src/set.rs b/rustables/src/set.rs index 9791e7f..d8c84d6 100644 --- a/rustables/src/set.rs +++ b/rustables/src/set.rs @@ -99,11 +99,13 @@ impl<'a, K> Set<'a, K> { SetElemsIter::new(self) } + #[cfg(feature = "unsafe-raw-handles")] /// Returns the raw handle. pub fn as_ptr(&self) -> *const sys::nftnl_set { self.set as *const sys::nftnl_set } + #[cfg(feature = "unsafe-raw-handles")] /// Returns a mutable version of the raw handle. pub fn as_mut_ptr(&self) -> *mut sys::nftnl_set { self.set @@ -177,7 +179,9 @@ pub struct SetElemsIter<'a, K> { impl<'a, K> SetElemsIter<'a, K> { fn new(set: &'a Set<'a, K>) -> Self { - let iter = try_alloc!(unsafe { sys::nftnl_set_elems_iter_create(set.as_ptr()) }); + let iter = try_alloc!(unsafe { + sys::nftnl_set_elems_iter_create(set.set as *const sys::nftnl_set) + }); SetElemsIter { set, iter, diff --git a/rustables/src/table.rs b/rustables/src/table.rs index 447d035..dc09b5e 100644 --- a/rustables/src/table.rs +++ b/rustables/src/table.rs @@ -1,7 +1,8 @@ use crate::{MsgType, ProtoFamily}; use rustables_sys::{self as sys, libc}; +#[cfg(feature = "query")] +use std::convert::TryFrom; use std::{ - convert::TryFrom, ffi::{c_void, CStr, CString}, fmt::Debug, os::raw::c_char, @@ -16,11 +17,6 @@ pub struct Table { family: ProtoFamily, } -// Safety: It should be safe to pass this around and *read* from it -// from multiple threads -unsafe impl Send for Table {} -unsafe impl Sync for Table {} - impl Table { /// Creates a new table instance with the given name and protocol family. pub fn new<T: AsRef<CStr>>(name: &T, family: ProtoFamily) -> Table { @@ -84,11 +80,13 @@ impl Table { } } + #[cfg(feature = "unsafe-raw-handles")] /// Returns the raw handle. pub fn as_ptr(&self) -> *const sys::nftnl_table { self.table as *const sys::nftnl_table } + #[cfg(feature = "unsafe-raw-handles")] /// Returns a mutable version of the raw handle. pub fn as_mut_ptr(&self) -> *mut sys::nftnl_table { self.table |