use nftnl::{nft_expr, set::Set, Batch, Chain, FinalizedBatch, ProtoFamily, Rule, Table}; use std::{ffi::CString, io::*, net::Ipv4Addr}; fn main() -> std::result::Result<(), Error> { let table_name = format!("ipblc4"); let table = Table::new( &CString::new(format!("{table_name}")).unwrap(), ProtoFamily::Ipv4, ); let mut batch = Batch::new(); batch.add(&table, nftnl::MsgType::Add); batch.add(&table, nftnl::MsgType::Del); batch.add(&table, nftnl::MsgType::Add); let mut chain = Chain::new(&CString::new("test").unwrap(), &table); chain.set_hook(nftnl::Hook::In, 1); chain.set_policy(nftnl::Policy::Accept); batch.add(&chain, nftnl::MsgType::Add); batch.add(&Rule::new(&chain), nftnl::MsgType::Del); let mut rule = Rule::new(&chain); rule.add_expr(&nft_expr!(ct state)); rule.add_expr(&nft_expr!(bitwise mask 4u32, xor 0u32)); rule.add_expr(&nft_expr!(cmp != 0u32)); rule.add_expr(&nft_expr!(counter)); rule.add_expr(&nft_expr!(verdict accept)); batch.add(&rule, nftnl::MsgType::Add); let finalized_batch = batch.finalize(); send_and_process(&finalized_batch)?; Ok(()) } fn send_and_process(batch: &FinalizedBatch) -> std::result::Result<(), Error> { let seq: u32 = 2; let socket = mnl::Socket::new(mnl::Bus::Netfilter)?; socket.send_all(batch)?; let mut buffer = vec![0; nftnl::nft_nlmsg_maxsize() as usize]; while let Some(message) = socket_recv(&socket, &mut buffer[..])? { match mnl::cb_run(message, seq, socket.portid())? { mnl::CbResult::Stop => { break; } mnl::CbResult::Ok => (), } } Ok(()) } fn socket_recv<'a>( socket: &mnl::Socket, buf: &'a mut [u8], ) -> std::result::Result, Error> { let ret = socket.recv(buf)?; if ret > 0 { Ok(Some(&buf[..ret])) } else { Ok(None) } }