[pve-devel] [PATCH conntrack-tool v2 5/5] replace C callback with closures
Mira Limbeck
m.limbeck at proxmox.com
Wed Feb 3 15:25:35 CET 2021
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 at 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
More information about the pve-devel
mailing list