Skip to main content

netlink_bindings/
traits.rs

1#[derive(Debug, Clone, Copy, PartialEq, Eq)]
2pub enum Protocol {
3    /// Legacy Netlink protocol, aka netlink-raw
4    Raw {
5        /// Value supplied to socket(2)
6        protonum: u16,
7        /// Value of `type` field in the message header
8        request_type: u16,
9    },
10    /// Generic Netlink protocol, aka genetlink or genl
11    ///
12    /// Note that the message also carries a command type in the required Nfgenmsg header.
13    Generic(&'static [u8]),
14}
15
16/// A trait describing how to handle a particular request.
17/// It designed to be used by a netlink socket implementation.
18pub trait NetlinkRequest {
19    /// Netlink protocol to use
20    fn protocol(&self) -> Protocol;
21
22    /// Additional `flags` specified in the message header
23    fn flags(&self) -> u16;
24
25    /// Encoded payload of the message (without message header)
26    fn payload(&self) -> &[u8];
27
28    // type RequestType<'buf>;
29    // fn decode_request(buf: &[u8]) -> Self::RequestType<'_>;
30
31    type ReplyType<'buf>;
32    fn decode_reply(buf: &[u8]) -> Self::ReplyType<'_>;
33
34    /// Lookup an attribute and it's parents in the request payload by offset
35    fn lookup(
36        buf: &[u8],
37        offset: usize,
38        missing_type: Option<u16>,
39    ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
40        let _ = buf;
41        let _ = offset;
42        let _ = missing_type;
43        (Vec::new(), None)
44    }
45}
46
47/// Function signature of [`NetlinkRequest::lookup`]
48pub type LookupFn =
49    fn(&[u8], usize, Option<u16>) -> (Vec<(&'static str, usize)>, Option<&'static str>);
50
51/// A chain of requests encoded into the single buffer (experimental)
52pub trait NetlinkChained {
53    fn protonum(&self) -> u16;
54
55    /// Encoded payload of the messages (including message headers)
56    fn payload(&self) -> &[u8];
57
58    /// Number of messages in the chain
59    fn chain_len(&self) -> usize;
60
61    fn get_index(&self, seq: u32) -> Option<usize>;
62
63    fn name(&self, index: usize) -> &'static str;
64
65    fn lookup(&self, index: usize) -> LookupFn {
66        let _ = index;
67        |_, _, _| Default::default()
68    }
69
70    /// Packet supports ack on success with NLM_F_ACK (assumed true by default).
71    /// To date, this's only used to workaround a bug in nftables prior to linux 6.10.
72    ///
73    /// Caller sequentially peeks indexes 0..chain_len() until it encounters None.
74    #[doc(hidden)]
75    fn supports_ack(&self, index: usize) -> Option<bool> {
76        let _ = index;
77        None
78    }
79}
80
81/// A trait for `Push*` structs to access the internal buffer.
82///
83/// You can use it to inspect, modify, or append attributes,
84/// e.g. by copying from another attribute set.
85///
86/// Use this trait with caution as there's no further type checks!
87pub trait Pusher {
88    fn as_vec(&self) -> &Vec<u8>;
89    fn as_vec_mut(&mut self) -> &mut Vec<u8>;
90
91    // TODO: drop in v0.4
92    #[deprecated = "Use .as_vec() instead (rec -> vec)"]
93    fn as_rec(&self) -> &Vec<u8> {
94        self.as_vec()
95    }
96    #[deprecated = "Use .as_vec_mut() instead (rec -> vec)"]
97    fn as_rec_mut(&mut self) -> &mut Vec<u8> {
98        self.as_vec_mut()
99    }
100}
101
102impl Pusher for Vec<u8> {
103    fn as_vec(&self) -> &Vec<u8> {
104        self
105    }
106    fn as_vec_mut(&mut self) -> &mut Vec<u8> {
107        self
108    }
109}
110
111impl Pusher for &mut Vec<u8> {
112    fn as_vec(&self) -> &Vec<u8> {
113        self
114    }
115    fn as_vec_mut(&mut self) -> &mut Vec<u8> {
116        self
117    }
118}