freebsd(13.2): add netlink/netlink.h support - #5326
Conversation
This comment has been minimized.
This comment has been minimized.
653f197 to
0b6bb29
Compare
This comment has been minimized.
This comment has been minimized.
|
The API looks fine from a quick skim, but since there is no hurry, I think it may be worth trying to add support to ctest first so the tricky test setup isn't needed. (It's useful otherwise too.) Sketched some of that up at #5344 |
|
Noted. Since you already pinged some contributor on that issue, I'll wait and |
|
Could you try adding a separate |
|
Either author or blocked, depending on whether that works. @rustbot author |
|
Reminder, once the PR becomes ready for a review, use |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
a6a6a8d to
266acdf
Compare
This comment has been minimized.
This comment has been minimized.
|
It seems having separate invocations gets the job done just fine. Still, that Those seem to me like they're going to need extending (though it's notably less |
This comment has been minimized.
This comment has been minimized.
@tgross35 They do. Just cleaned up commit history as all tests seem to pass now. |
2b52cf7 to
30133e0
Compare
| let mut netlink_cfg = cfg.clone(); | ||
| headers!(netlink_cfg, "netlink/netlink.h",); | ||
| netlink_cfg | ||
| .skip_struct(|ty| !matches!(ty.ident(), "sockaddr_nl")) | ||
| .skip_const(|c| !is_netlink_const(c)) | ||
| .skip_union(|_| true) | ||
| .skip_alias(|_| true) | ||
| .skip_static(|_| true) | ||
| .skip_fn(|_| true) | ||
| .skip_c_enum(|_| true); | ||
| ctest::generate_test(&mut netlink_cfg, "../src/lib.rs", "netlink_ctest_output.rs").unwrap(); | ||
|
|
||
| // We must restore the above sure-skips because `TestGenerator` shares skips | ||
| // between cloned instances (here `cfg` and `netlink_cfg`.) | ||
| cfg.skip_struct(|_| false) | ||
| .skip_const(|_| false) | ||
| .skip_union(|_| false) | ||
| .skip_alias(|_| false) | ||
| .skip_static(|_| false) | ||
| .skip_fn(|_| false) | ||
| .skip_c_enum(|_| false); |
There was a problem hiding this comment.
Sharing skips isn't intentional, why does this happen?
There was a problem hiding this comment.
A prior review comment 1 mentioned a recent patch that allows sharing skips
between instances of TestGenerator. I assumed you wanted me to use the now
shallow copy semantics of that type to avoid calling anew ctest_cfg() for
netlink_cfg.
This then needs resetting to the "defaults," because otherwise some skipping
functions that we do call with netlink_cfg but not with cfg end up affecting
cfg.
Footnotes
There was a problem hiding this comment.
Sort of, but there's no shallow copy. I guess the Rc<dyn Fn()> might look that way but it's just letting closures be used from multiple places like function pointers - it's not like cloning to a TestGenerator then adding skips to one means that the other TestGenerator gets those same skips.
(The pattern for something like that would be field: Rc<RefCell<Box<dyn Fn()>>> or field: Rc<RefCell<Vec<Box<dyn Fn()>>>.)
So you can delete the .skip_union(|_| false) ...
There was a problem hiding this comment.
Done, but I've still got questions.
How is there not? TestGenerator automatically derives Clone and that would
make the inner Vec<Skip> use its Clone implementation, which itself depends
on the Clone impl of Skip. Skip is just an alias to a Rc<...>, so it
would call into the Clone impl for Rc<T: ?Sized>, which will yield a shallow
copy of T.
Granted, you'd still need some form of interior mutability to change those
skips, but I don't think skips are made to be "modified" once "registered."
What am I missing?
There was a problem hiding this comment.
IME the term "shallow copy" typically means (1) there exists a real or theoretical corresponding deep copy, and (2) the difference between a shallow and deep copy is observable. With this code:
let cfg1 = TestGenerator::new();
let cfg2 = cfg1.clone();
cfg1.skip_struct(|ty| ty.ident() == "foo");
// ...I'd definitely consider it a shallow copy if both cfg1 and cfg2 skip foo as a result (would be pretty surprising API). I thought that's what you were expecting at first based on the comments and is why I mentioned the RefCell patterns, but perhaps this wasn't correct?
That shouldn't be what happens, cfg1 and cfg2 are decoupled. Existing skips do stick around when cloning, but it's more like cloning a Vec to get the same base items then being able to add on independently.
There is a "shallow copy" with the Rc<dyn Fn()> and it wouldn't be technically incorrect to refer to it as such, but I'd find it an unintuitive use of the term because you need to go out of your way and use interior mutability to observe it. It's not too far off from duplicating a fn() or &u32—technically shallow and observable, but the distinction isn't especially meaningful.
This is mostly just opinion, though, I'm sure others may look at it differently.
30133e0 to
f9649f6
Compare
This comment has been minimized.
This comment has been minimized.
f9649f6 to
1654258
Compare
This comment has been minimized.
This comment has been minimized.
1654258 to
4d8855f
Compare
This comment has been minimized.
This comment has been minimized.
745bf15 to
be6cc74
Compare
|
@rustbot ready |
There was a problem hiding this comment.
Cc @asomers, could you take a look when you get the chance?
| let mut netlink_cfg = cfg.clone(); | ||
| headers!(netlink_cfg, "netlink/netlink.h",); | ||
| netlink_cfg | ||
| .skip_struct(|ty| !matches!(ty.ident(), "sockaddr_nl")) | ||
| .skip_const(|c| !is_netlink_const(c)) | ||
| .skip_union(|_| true) | ||
| .skip_alias(|_| true) | ||
| .skip_static(|_| true) | ||
| .skip_fn(|_| true) | ||
| .skip_c_enum(|_| true); | ||
| ctest::generate_test(&mut netlink_cfg, "../src/lib.rs", "netlink_ctest_output.rs").unwrap(); | ||
|
|
||
| // We must restore the above sure-skips because `TestGenerator` shares skips | ||
| // between cloned instances (here `cfg` and `netlink_cfg`.) | ||
| cfg.skip_struct(|_| false) | ||
| .skip_const(|_| false) | ||
| .skip_union(|_| false) | ||
| .skip_alias(|_| false) | ||
| .skip_static(|_| false) | ||
| .skip_fn(|_| false) | ||
| .skip_c_enum(|_| false); |
There was a problem hiding this comment.
Sort of, but there's no shallow copy. I guess the Rc<dyn Fn()> might look that way but it's just letting closures be used from multiple places like function pointers - it's not like cloning to a TestGenerator then adding skips to one means that the other TestGenerator gets those same skips.
(The pattern for something like that would be field: Rc<RefCell<Box<dyn Fn()>>> or field: Rc<RefCell<Vec<Box<dyn Fn()>>>.)
So you can delete the .skip_union(|_| false) ...
be6cc74 to
09bbab3
Compare
|
This PR was rebased onto a different main commit. Here's a range-diff highlighting what actually changed. Rebasing is a normal part of keeping PRs up to date, so no action is needed—this note is just to help reviewers. |
This is an early subset of the Netlink interface, but it proves sufficient for monitoring changes in IP addresses. Coverage can be extended later as needed. See [^1] and [^2]. [^1]: <https://github.com/freebsd/freebsd-src/blob/df9d6403caa6426e92f5e100602f4d2be474bbae/sys/netlink/netlink.h> [^2]: <https://github.com/freebsd/freebsd-src/blob/df9d6403caa6426e92f5e100602f4d2be474bbae/sys/netlink/netlink_generic.h> A small workaround has been necessary in the SemVer tests to ensure we get the right paths to the public submodules for the `netlink/netlink.h` and `netlink/netling_generic.h` interfaces. Those symbols now are prepended a `netlink` super module path. Signed-off-by: Yann Dirson <yann.dirson@vates.fr> Co-authored-by: Yann Dirson <yann.dirson@vates.fr>
Add specific test for `netlink/netlink.h` bindings. This is necessary to avoid conflicts with the bindings for `net/if_mib.h`. libc-test now builds two different `TestGenerator` instances. One of the instances builds tests for the same set of bindings as before this patchset, while the other builds tests only for the `netlink/netlink.h` bindings.
09bbab3 to
d22b942
Compare
|
@rustbot ready |
| #[inline] | ||
| fn is_netlink_const(it: &ctest::Const) -> bool { |
There was a problem hiding this comment.
Drop #[inline], no need to really worried about that kind of performance optimizations in tests and this isn't a bottleneck.
|
|
||
| pub(crate) mod net; | ||
| pub(crate) mod netinet6; | ||
| pub mod netlink; |
There was a problem hiding this comment.
This can now be pub(crate) right?
|
|
||
| pub use freebsd::netlink::netlink::*; | ||
| pub use freebsd::netlink::netlink_generic::*; | ||
| } |
There was a problem hiding this comment.
Maybe just rename src/new/freebsd/netlink/netlink.rs to netlink_.rs or something, so we can keep the glob export? Think this might be done elsewhere as well.
Just add a comment by the mod netlink_ explaining why it has that name.
| .skip_union(|_| true) | ||
| .skip_alias(|_| true) | ||
| .skip_static(|_| true) | ||
| .skip_fn(|_| true) | ||
| .skip_c_enum(|_| true); |
There was a problem hiding this comment.
These shouldn't be needed anymore right?
| let mut netlink_cfg = cfg.clone(); | ||
| headers!(netlink_cfg, "netlink/netlink.h",); | ||
| netlink_cfg | ||
| .skip_struct(|ty| !matches!(ty.ident(), "sockaddr_nl")) | ||
| .skip_const(|c| !is_netlink_const(c)) | ||
| .skip_union(|_| true) | ||
| .skip_alias(|_| true) | ||
| .skip_static(|_| true) | ||
| .skip_fn(|_| true) | ||
| .skip_c_enum(|_| true); | ||
| ctest::generate_test(&mut netlink_cfg, "../src/lib.rs", "netlink_ctest_output.rs").unwrap(); | ||
|
|
||
| // We must restore the above sure-skips because `TestGenerator` shares skips | ||
| // between cloned instances (here `cfg` and `netlink_cfg`.) | ||
| cfg.skip_struct(|_| false) | ||
| .skip_const(|_| false) | ||
| .skip_union(|_| false) | ||
| .skip_alias(|_| false) | ||
| .skip_static(|_| false) | ||
| .skip_fn(|_| false) | ||
| .skip_c_enum(|_| false); |
There was a problem hiding this comment.
IME the term "shallow copy" typically means (1) there exists a real or theoretical corresponding deep copy, and (2) the difference between a shallow and deep copy is observable. With this code:
let cfg1 = TestGenerator::new();
let cfg2 = cfg1.clone();
cfg1.skip_struct(|ty| ty.ident() == "foo");
// ...I'd definitely consider it a shallow copy if both cfg1 and cfg2 skip foo as a result (would be pretty surprising API). I thought that's what you were expecting at first based on the comments and is why I mentioned the RefCell patterns, but perhaps this wasn't correct?
That shouldn't be what happens, cfg1 and cfg2 are decoupled. Existing skips do stick around when cloning, but it's more like cloning a Vec to get the same base items then being able to add on independently.
There is a "shallow copy" with the Rc<dyn Fn()> and it wouldn't be technically incorrect to refer to it as such, but I'd find it an unintuitive use of the term because you need to go out of your way and use interior mutability to observe it. It's not too far off from duplicating a fn() or &u32—technically shallow and observable, but the distinction isn't especially meaningful.
This is mostly just opinion, though, I'm sure others may look at it differently.
Description
This PR updates #3201 with merge conflicts resolved and follows the new plan at
1.
The patch adds support for
netlink.hinterfaces in OpenBSD, where there's anitem resolution conflict if we expose the Rust bindings alongside those of
if_mib.h. This set of APIs is "scoped" in C because they live on separateheaders. In rust-lang/libc, we reexport all items at the root crate level, which
makes item resolution fail.
Note this depends on #5325. It won't pass tests but it will build. This is
because the test templates will gather all items in a single file, so item
resolution fails. We can't really skip these items altogether from the tests, so
it may just be necessary to extend
ctestto allow skipping module-specificRust items.
Checklist
libc-test/semverhave been updated*LASTor*MAXhave the standarddoc comment
cargo test -p libc-test --target mytarget); especiallyrelevant for platforms that may not be checked in CI
@rustbot label +stable-nominated
Footnotes
https://github.com/rust-lang/libc/pull/3201#issuecomment-4736374182 ↩