aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--rustables/Cargo.toml1
-rw-r--r--rustables/examples/add-rules.rs67
-rw-r--r--rustables/examples/filter-ethernet.rs41
-rw-r--r--rustables/src/batch.rs16
-rw-r--r--rustables/src/chain.rs21
-rw-r--r--rustables/src/lib.rs19
-rw-r--r--rustables/src/rule.rs21
-rw-r--r--rustables/src/set.rs6
-rw-r--r--rustables/src/table.rs10
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