neli/consts/mod.rs
1//! # High level notes
2//!
3//! The contents of this module are generated mostly by macros, which
4//! implement the appropriate traits necessary to both be
5//! serialized/deserialized and also provide an additional level of
6//! type safety when constructing netlink packets. Some of the traits
7//! generated in this module allow netlink structures to implement
8//! trait bounds assuring that only compatible constant-based enums
9//! are allowed to be passed in as parameters. The macros are
10//! exported; you can use them too! See [`impl_trait`][crate::impl_trait]
11//! and [`impl_flags`][crate::impl_flags] for more details.
12//!
13//! Note that most of these constants come from the Linux kernel
14//! headers, which can be found in `/usr/include/linux` on many
15//! distros. You can also see `man 3 netlink`, `man 7 netlink`,
16//! and `man 7 rtnetlink` for more information.
17//!
18//! # Design decisions
19//!
20//! * Macros are exported so that these conventions are extensible and
21//! usable for data types implemented by the user in the case of new
22//! netlink families (which is supported by the protocol). In this
23//! case, there is no way in which I can support every custom netlink
24//! family but my aim is to make this library as flexible as possible
25//! so that it is painless to hook your custom netlink data type into
26//! the existing library support.
27//! * Enums are used so that:
28//! * Values can be checked based on a finite number of inputs as
29//! opposed to the range of whatever integer data type C defines as
30//! the struct member type. This makes it easier to catch garbage
31//! responses and corruption when an invalid netlink message is sent
32//! to the kernel.
33//! * Only the enum or an enum implementing a marker trait in the
34//! case of type parameters can be used in the appropriate places
35//! when constructing netlink messages. This takes guess work out of
36//! which constants can be used where. Netlink documentation is not
37//! always complete and sometimes takes a bit of trial and error
38//! sending messages to the kernel to figure out if you are using
39//! the correct constants. This setup should let you know at compile
40//! time if you are doing something you should not be doing.
41//! * `UnrecognizedVariant` is included in each enum because
42//! completeness cannot be guaranteed for every constant for every
43//! protocol. This allows you to inspect the integer value returned
44//! and if you are sure that it is correct, you can use it. If it is
45//! a garbage value, this can also be useful for error reporting.
46
47#[macro_use]
48mod macros;
49
50/// Constants related to netlink connector interface
51pub mod connector;
52/// Constants related to generic netlink
53pub mod genl;
54/// Constants related to netfilter netlink integration
55pub mod netfilter;
56/// Constants related to generic netlink top level headers
57pub mod nl;
58/// Constants related to rtnetlink
59pub mod rtnl;
60/// Constants related to netlink socket operations
61pub mod socket;
62
63/// Reimplementation of alignto macro in C
64pub fn alignto(len: usize) -> usize {
65 (len + libc::NLA_ALIGNTO as usize - 1) & !(libc::NLA_ALIGNTO as usize - 1)
66}
67
68/// Max supported message length for netlink messages supported by
69/// the kernel.
70pub const MAX_NL_LENGTH: usize = 32768;
71
72#[cfg(test)]
73mod test {
74 use super::genl::*;
75
76 #[test]
77 fn test_generated_enum_into_from() {
78 let unspec: u8 = CtrlCmd::Unspec.into();
79 assert_eq!(unspec, libc::CTRL_CMD_UNSPEC as u8);
80
81 let unspec_variant = CtrlCmd::from(libc::CTRL_CMD_UNSPEC as u8);
82 assert_eq!(unspec_variant, CtrlCmd::Unspec);
83 }
84}