From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from firstgate.proxmox.com (firstgate.proxmox.com [212.224.123.68]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits)) (No client certificate requested) by lists.proxmox.com (Postfix) with ESMTPS id C41D06CF29 for ; Wed, 3 Feb 2021 15:25:47 +0100 (CET) Received: from firstgate.proxmox.com (localhost [127.0.0.1]) by firstgate.proxmox.com (Proxmox) with ESMTP id C15821B1FB for ; Wed, 3 Feb 2021 15:25:47 +0100 (CET) Received: from proxmox-new.maurer-it.com (proxmox-new.maurer-it.com [212.186.127.180]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits)) (No client certificate requested) by firstgate.proxmox.com (Proxmox) with ESMTPS id 5A7AE1B1B7 for ; Wed, 3 Feb 2021 15:25:45 +0100 (CET) Received: from proxmox-new.maurer-it.com (localhost.localdomain [127.0.0.1]) by proxmox-new.maurer-it.com (Proxmox) with ESMTP id 1DF2A461A6 for ; Wed, 3 Feb 2021 15:25:45 +0100 (CET) From: Mira Limbeck To: pve-devel@lists.proxmox.com Date: Wed, 3 Feb 2021 15:25:35 +0100 Message-Id: <20210203142536.28480-5-m.limbeck@proxmox.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20210203142536.28480-1-m.limbeck@proxmox.com> References: <20210203142536.28480-1-m.limbeck@proxmox.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-SPAM-LEVEL: Spam detection results: 0 AWL -0.244 Adjusted score from AWL reputation of From: address KAM_DMARC_STATUS 0.01 Test Rule for DKIM or SPF Failure with Strict Alignment KAM_LAZY_DOMAIN_SECURITY 1 Sending domain does not have any anti-forgery methods NO_DNS_FOR_FROM 0.379 Envelope sender has no MX or A DNS records RCVD_IN_DNSWL_MED -2.3 Sender listed at https://www.dnswl.org/, medium trust SPF_HELO_NONE 0.001 SPF: HELO does not publish an SPF Record SPF_NONE 0.001 SPF: sender does not publish an SPF Record URIBL_BLOCKED 0.001 ADMINISTRATOR NOTICE: The query to URIBL was blocked. See http://wiki.apache.org/spamassassin/DnsBlocklists#dnsbl-block for more information. [main.rs] Subject: [pve-devel] [PATCH conntrack-tool v2 5/5] replace C callback with closures X-BeenThere: pve-devel@lists.proxmox.com X-Mailman-Version: 2.1.29 Precedence: list List-Id: Proxmox VE development discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 03 Feb 2021 14:25:47 -0000 Internally we still have to use a C callback, but all it does is forward to the closure we pass to it. Signed-off-by: Mira Limbeck --- v2: - new addition src/main.rs | 208 +++++++++++++++++++++++++++------------------------- 1 file changed, 109 insertions(+), 99 deletions(-) diff --git a/src/main.rs b/src/main.rs index 79779ff..0930f92 100644 --- a/src/main.rs +++ b/src/main.rs @@ -83,24 +83,6 @@ fn main() -> Result<()> { Ok(()) } -extern "C" fn query_cts_cb(nlh: *const libc::nlmsghdr, data_ptr: *mut libc::c_void) -> libc::c_int { - let ct = unsafe { nfct_new() }; - unsafe { - nfct_nlmsg_parse(nlh, ct); - } - - if let Some(conntrack) = parse_conntrack(ct) { - let cts: &mut Vec = unsafe { &mut *(data_ptr as *mut Vec) }; - cts.push(conntrack); - } - - unsafe { - nfct_destroy(ct); - } - - MNL_CB_OK -} - const CONNTRACK_QUERY_MSG_TYPE: u16 = ((libc::NFNL_SUBSYS_CTNETLINK << 8) | IPCTNL_MSG_CT_GET) as u16; const CONNTRACK_QUERY_FLAGS: u16 = @@ -169,7 +151,20 @@ impl Socket { seq, proto, ); - self.send_and_receive(hdr, 0, Some(query_cts_cb), cts as *mut Vec as _) + self.send_and_receive(hdr, 0, |nlh| { + let ct = unsafe { nfct_new() }; + unsafe { + nfct_nlmsg_parse(nlh, ct); + } + + if let Some(conntrack) = parse_conntrack(ct) { + cts.push(conntrack); + } + + unsafe { + nfct_destroy(ct); + } + }) } fn insert_conntrack(&mut self, ct: Conntrack) -> Result<()> { @@ -195,7 +190,7 @@ impl Socket { nfct_destroy(cth); } - self.send_and_receive(hdr, 0, None, std::ptr::null_mut())?; + self.send_and_receive(hdr, 0, |_| {})?; Ok(()) } @@ -208,7 +203,12 @@ impl Socket { Ok(()) } - fn query_expects_impl(&mut self, exps: &mut Vec, seq: u32, proto: u8) -> Result<()> { + fn query_expects_impl( + &mut self, + exps: &mut Vec, + seq: u32, + proto: u8, + ) -> Result<()> { let mut buf = [0u8; MNL_SOCKET_DUMP_SIZE as _]; let hdr = build_msg_header( buf.as_mut_ptr() as _, @@ -217,7 +217,75 @@ impl Socket { seq, proto, ); - self.send_and_receive(hdr, 0, Some(query_exp_cb), exps as *mut Vec as _) + self.send_and_receive(hdr, 0, |nlh| { + let exp = unsafe { nfexp_new() }; + unsafe { + nfexp_nlmsg_parse(nlh, exp); + } + + let mut attributes = Vec::new(); + for (attr, ty) in EXPECT_ALL_ATTRIBUTES { + if unsafe { nfexp_attr_is_set(exp, *attr) } == 0 { + continue; + } + match ty { + ExpectAttrType::CT => { + let ct = unsafe { nfexp_get_attr(exp, *attr) }; + if let Some(ct) = parse_conntrack(ct as _) { + attributes.push(ExpectAttr { + key: *attr, + value: ExpectAttrValue::CT(ct), + }); + } + } + ExpectAttrType::U8 => { + let val = unsafe { nfexp_get_attr_u8(exp, *attr) }; + attributes.push(ExpectAttr { + key: *attr, + value: ExpectAttrValue::U8(val), + }); + } + ExpectAttrType::U16 => { + let val = unsafe { nfexp_get_attr_u16(exp, *attr) }; + attributes.push(ExpectAttr { + key: *attr, + value: ExpectAttrValue::U16(val), + }); + } + ExpectAttrType::U32 => { + let val = unsafe { nfexp_get_attr_u32(exp, *attr) }; + attributes.push(ExpectAttr { + key: *attr, + value: ExpectAttrValue::U32(val), + }); + } + ExpectAttrType::String(Some(len)) => { + let ptr = unsafe { nfexp_get_attr(exp, *attr) }; + let cstr = unsafe { std::ffi::CStr::from_ptr(ptr as _) }; + let s = cstr.to_bytes(); + let s = unsafe { + CString::from_vec_unchecked(s[0..s.len().min((*len) as _)].to_vec()) + }; + attributes.push(ExpectAttr { + key: *attr, + value: ExpectAttrValue::String(s), + }); + } + ExpectAttrType::String(None) => { + let ptr = unsafe { nfexp_get_attr(exp, *attr) }; + let cstr = unsafe { std::ffi::CStr::from_ptr(ptr as _) }; + let s = cstr.to_bytes(); + let s = unsafe { CString::from_vec_unchecked(s.to_vec()) }; + attributes.push(ExpectAttr { + key: *attr, + value: ExpectAttrValue::String(s), + }); + } + } + } + + exps.push(Expect { attributes }); + }) } fn insert_expect(&mut self, exp: Expect) -> Result<()> { @@ -277,17 +345,16 @@ impl Socket { } } - self.send_and_receive(hdr, 0, None, std::ptr::null_mut())?; + self.send_and_receive(hdr, 0, |_| {})?; Ok(()) } - fn send_and_receive( + fn send_and_receive( &mut self, msg: *const libc::nlmsghdr, seq: u32, - cb: Option, - data: *mut libc::c_void, + mut cb: CB, ) -> Result<()> { let res = unsafe { mnl_socket_sendto(self.socket.as_ptr(), msg as _, (*msg).nlmsg_len as _) }; @@ -312,7 +379,16 @@ impl Socket { bail!("Failed to read message: {}", err); } - let res = unsafe { mnl_cb_run(buffer.as_ptr() as _, res as _, seq, portid, cb, data) }; + let res = unsafe { + mnl_cb_run( + buffer.as_ptr() as _, + res as _, + seq, + portid, + Some(callback), + &mut &mut cb as *mut &mut CB as _, + ) + }; if res == -1 { let err = std::io::Error::last_os_error(); bail!("Failed to run callback: {}", err); @@ -333,6 +409,12 @@ impl Drop for Socket { } } +extern "C" fn callback(nlh: *const libc::nlmsghdr, data_ptr: *mut libc::c_void) -> libc::c_int { + let cb = unsafe { *(data_ptr as *mut &dyn Fn(*const libc::nlmsghdr)) }; + cb(nlh); + MNL_CB_OK +} + fn build_msg_header( buf: *mut libc::c_void, ty: u16, @@ -594,78 +676,6 @@ const ALL_ATTRIBUTES: &[(CTAttr, AttrType)] = &[ (CTAttr::SYNPROXY_TSOFF, AttrType::U32), /* u32 bits */ ]; -extern "C" fn query_exp_cb(nlh: *const libc::nlmsghdr, data_ptr: *mut libc::c_void) -> libc::c_int { - let exp = unsafe { nfexp_new() }; - unsafe { - nfexp_nlmsg_parse(nlh, exp); - } - - let mut attributes = Vec::new(); - for (attr, ty) in EXPECT_ALL_ATTRIBUTES { - if unsafe { nfexp_attr_is_set(exp, *attr) } == 0 { - continue; - } - match ty { - ExpectAttrType::CT => { - let ct = unsafe { nfexp_get_attr(exp, *attr) }; - if let Some(ct) = parse_conntrack(ct as _) { - attributes.push(ExpectAttr { - key: *attr, - value: ExpectAttrValue::CT(ct), - }); - } - } - ExpectAttrType::U8 => { - let val = unsafe { nfexp_get_attr_u8(exp, *attr) }; - attributes.push(ExpectAttr { - key: *attr, - value: ExpectAttrValue::U8(val), - }); - } - ExpectAttrType::U16 => { - let val = unsafe { nfexp_get_attr_u16(exp, *attr) }; - attributes.push(ExpectAttr { - key: *attr, - value: ExpectAttrValue::U16(val), - }); - } - ExpectAttrType::U32 => { - let val = unsafe { nfexp_get_attr_u32(exp, *attr) }; - attributes.push(ExpectAttr { - key: *attr, - value: ExpectAttrValue::U32(val), - }); - } - ExpectAttrType::String(Some(len)) => { - let ptr = unsafe { nfexp_get_attr(exp, *attr) }; - let cstr = unsafe { std::ffi::CStr::from_ptr(ptr as _) }; - let s = cstr.to_bytes(); - let s = - unsafe { CString::from_vec_unchecked(s[0..s.len().min((*len) as _)].to_vec()) }; - attributes.push(ExpectAttr { - key: *attr, - value: ExpectAttrValue::String(s), - }); - } - ExpectAttrType::String(None) => { - let ptr = unsafe { nfexp_get_attr(exp, *attr) }; - let cstr = unsafe { std::ffi::CStr::from_ptr(ptr as _) }; - let s = cstr.to_bytes(); - let s = unsafe { CString::from_vec_unchecked(s.to_vec()) }; - attributes.push(ExpectAttr { - key: *attr, - value: ExpectAttrValue::String(s), - }); - } - } - } - - let exps: &mut Vec = unsafe { &mut *(data_ptr as *mut Vec) }; - exps.push(Expect { attributes }); - - MNL_CB_OK -} - #[derive(Debug, Serialize, Deserialize)] struct Expect { attributes: Vec, -- 2.20.1