-
Notifications
You must be signed in to change notification settings - Fork 1.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
bindgen: use bindgen to provide Rust bindings to C - v8 #12466
base: master
Are you sure you want to change the base?
Conversation
Follow Rust convention of using a "sys" crate for bindings to C functions. The bindings don't exist yet, but will be generated by bindgen and put into this crate.
Bindgen works by processing a header file which includes all other header files it should generate bindings for. For this I've created bindgen.h which just includes app-layer-protos.h for now as an example. These bindings are then generated and saved in the "suricata-sys" crate and become availale as "suricata_sys::sys".
Have bindgen generate bindings for app-layer-protos.h, then use the generated definitions of AppProto/AppProtoEnum instead if defining them ourselves. This header was chosen as its used by Rust, and its a simple header with no circular dependencies.
#[repr(u32)] | ||
#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] | ||
pub enum AppProtoEnum { | ||
ALPROTO_UNKNOWN = 0, | ||
ALPROTO_FAILED = 1, | ||
ALPROTO_HTTP1 = 2, | ||
ALPROTO_FTP = 3, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could also do:
pub const AppProtoEnum_ALPROTO_UNKNOWN: AppProtoEnum = 0;
pub const AppProtoEnum_ALPROTO_FAILED: AppProtoEnum = 1;
pub const AppProtoEnum_ALPROTO_HTTP1: AppProtoEnum = 2;
pub const AppProtoEnum_ALPROTO_FTP: AppProtoEnum = 3;
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it right to have a rust AppProtoEnum
? when we want dynamic AppProto cf #12420 and rejected https://redmine.openinfosecfoundation.org/issues/3524 ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure? That PR still uses the AppProto
datatype in SNMP. Make sense to bindgen that from C to Rust for use.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Indeed I see AppProtoEnum as AppProto
#12466 (comment)
Some comments around it may help like
- AppProtoEnum is for statically defined protocols
- AppProto is for all protocols : static and dynamic
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This file is generated, so I guess that doc would go where these are defined in C.
Codecov ReportAll modified and coverable lines are covered by tests ✅
Additional details and impacted files@@ Coverage Diff @@
## master #12466 +/- ##
==========================================
- Coverage 80.63% 80.52% -0.12%
==========================================
Files 920 923 +3
Lines 258739 259176 +437
==========================================
+ Hits 208643 208705 +62
- Misses 50096 50471 +375
Flags with carried forward coverage won't be shown. Click here to find out more. |
Information: QA ran without warnings. Pipeline 24340 |
} | ||
pub type AppProto = u16; | ||
extern "C" { | ||
#[doc = " \\brief Maps the ALPROTO_*, to its string equivalent.\n\n \\param alproto App layer protocol id.\n\n \\retval String equivalent for the alproto."] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: We do not need to export the comment I guess
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can be disabled. But still useful to have to Rustdoc IMO.
@@ -79,14 +79,49 @@ clean-local: | |||
distclean-local: | |||
rm -rf vendor dist | |||
|
|||
check-bindgen-bindings: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There should be a CI test with bindgen
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oops, I didn't pull over this test from the previous PR: https://github.com/OISF/suricata/pull/12461/files#diff-73e17259d77e5fbef83b2bdbbe4dc40a912f807472287f7f45b77e0cbf78792d
It just rebuilds the bindings to make sure they are up to date.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, this is the CI test I am expecting :-)
pub const ALPROTO_UNKNOWN : AppProto = 0; | ||
pub const ALPROTO_FAILED : AppProto = 1; | ||
pub const ALPROTO_UNKNOWN : AppProto = AppProtoEnum::ALPROTO_UNKNOWN as AppProto; | ||
pub const ALPROTO_FAILED : AppProto = AppProtoEnum::ALPROTO_FAILED as AppProto; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh AppProtoEnum. as AppProto
...
This looks nice overall. What is the remaining work to do ?
|
Its ready as is IMO. But then it would probably make sense to try to replace any of our hand written |
Unfortunately Ubuntu 24.04 and the latest RHEL/Fedora/EPEL stuff ship with bindgen 0.69.5 which can't re-export our Or, just upgrade to the latest bindgen, 0.71.1. It has no issues consuming |
Regenerates the `sys.rs` and looks for any difference. Check will fail if there is a difference.
We don't keep bindgen's autogenerated do not edit line as it contains the bindgen version which could break the CI check for out of date bindings. So add our own do not edit line.
|
Good to tackle smaller bits, but I wanted to see the next bits : |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
CI check was missing ;-)
@@ -2269,6 +2269,9 @@ fi | |||
fi | |||
fi | |||
|
|||
AC_PATH_PROG([BINDGEN], [bindgen], [no]) | |||
AM_CONDITIONAL([HAVE_BINDGEN], [test "x$BINDGEN" != "xno"]) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we check bindgen version ?
It makes sense, as its a C data structure, not a Rust one. But that means maybe it should be defined in C, and bindgen'd over to Rust. I don't think we can put it in |
Of course it could be done, and conceptually makes sense. Just might need lots of exclude/includes in cbindgen.toml as I don't see a way to just exclude a whole file |
Ok, it might not make sense: From https://doc.rust-lang.org/cargo/reference/build-scripts.html#-sys-packages | The library crate should provide declarations for types and functions in libfoo, but not higher-level abstractions. So that means by convention, a nice wrapper around the C API belongs somewhere else: | It is common to have a companion package without the -sys suffix that provides a safe, high-level abstractions on top of the sys package. For example, the git2 crate provides a high-level interface to the libgit2-sys crate. These typically apply to a pure C library being exposed, not a hybrid library like ours. This is mostly convention. It might make sense for us to mix safe wrappers in the same crate. |
So, I guess we should have a good view on how we want to divide in crates considering the use cases, including the plugin one ;-) |
Yeah, I think the sys can continue before that is decided. I didn't do this work for the plugin use case, but to avoid us writing our own bindings to C functions - it would be a big win just to get rid of those I think. |
WARNING:
Pipeline 24354 |
A simpler, more focused version of #12461.
app-layer-protos.h
and update Rust code to use the generated bindings.AppProto
could have been more more minimal by re-exporting fromcore
, but I don't like the idea of add re-exports.