From: Mira Limbeck <m.limbeck@proxmox.com>
To: pve-devel@lists.proxmox.com
Subject: [pve-devel] [PATCH conntrack-tool v2 5/5] replace C callback with closures
Date: Wed, 3 Feb 2021 15:25:35 +0100 [thread overview]
Message-ID: <20210203142536.28480-5-m.limbeck@proxmox.com> (raw)
In-Reply-To: <20210203142536.28480-1-m.limbeck@proxmox.com>
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 <m.limbeck@proxmox.com>
---
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<Conntrack> = unsafe { &mut *(data_ptr as *mut Vec<Conntrack>) };
- 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<Conntrack> 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<Expect>, seq: u32, proto: u8) -> Result<()> {
+ fn query_expects_impl(
+ &mut self,
+ exps: &mut Vec<Expect>,
+ 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<Expect> 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<CB: FnMut(*const libc::nlmsghdr)>(
&mut self,
msg: *const libc::nlmsghdr,
seq: u32,
- cb: Option<mnl_cb_t>,
- 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<Expect> = unsafe { &mut *(data_ptr as *mut Vec<Expect>) };
- exps.push(Expect { attributes });
-
- MNL_CB_OK
-}
-
#[derive(Debug, Serialize, Deserialize)]
struct Expect {
attributes: Vec<ExpectAttr>,
--
2.20.1
next prev parent reply other threads:[~2021-02-03 14:25 UTC|newest]
Thread overview: 14+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-02-03 14:25 [pve-devel] [PATCH conntrack-tool v2 1/5] initial commit Mira Limbeck
2021-02-03 14:25 ` [pve-devel] [PATCH conntrack-tool v2 2/5] add packaging support Mira Limbeck
2021-02-04 7:08 ` Thomas Lamprecht
2021-02-04 9:55 ` Mira Limbeck
2021-02-03 14:25 ` [pve-devel] [PATCH conntrack-tool v2 3/5] add expectation support Mira Limbeck
2021-02-03 14:25 ` [pve-devel] [PATCH conntrack-tool v2 4/5] add additional bindings Mira Limbeck
2021-02-03 14:25 ` Mira Limbeck [this message]
2021-02-03 14:25 ` [pve-devel] [PATCH qemu-server v2] copy conntrack information on migration Mira Limbeck
2021-02-05 8:11 ` Fabian Ebner
2021-02-05 9:51 ` Mira Limbeck
2021-02-04 8:07 ` [pve-devel] [PATCH conntrack-tool v2 1/5] initial commit Thomas Lamprecht
2021-02-04 10:15 ` Mira Limbeck
2021-02-04 10:20 ` Thomas Lamprecht
2021-02-04 10:16 ` Mira Limbeck
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20210203142536.28480-5-m.limbeck@proxmox.com \
--to=m.limbeck@proxmox.com \
--cc=pve-devel@lists.proxmox.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.