netlink_packet_route/rtnl/
message.rs

1// SPDX-License-Identifier: MIT
2
3use netlink_packet_utils::{
4    traits::{Emitable, ParseableParametrized},
5    DecodeError,
6};
7
8use netlink_packet_core::{
9    NetlinkDeserializable, NetlinkHeader, NetlinkPayload, NetlinkSerializable,
10};
11
12use crate::{
13    constants::*, AddressMessage, LinkMessage, NeighbourMessage,
14    NeighbourTableMessage, NsidMessage, RouteMessage, RtnlMessageBuffer,
15    RuleMessage, TcMessage,
16};
17
18#[derive(Debug, PartialEq, Eq, Clone)]
19#[non_exhaustive]
20pub enum RtnlMessage {
21    NewLink(LinkMessage),
22    DelLink(LinkMessage),
23    GetLink(LinkMessage),
24    SetLink(LinkMessage),
25    NewLinkProp(LinkMessage),
26    DelLinkProp(LinkMessage),
27    NewAddress(AddressMessage),
28    DelAddress(AddressMessage),
29    GetAddress(AddressMessage),
30    NewNeighbour(NeighbourMessage),
31    GetNeighbour(NeighbourMessage),
32    DelNeighbour(NeighbourMessage),
33    NewNeighbourTable(NeighbourTableMessage),
34    GetNeighbourTable(NeighbourTableMessage),
35    SetNeighbourTable(NeighbourTableMessage),
36    NewRoute(RouteMessage),
37    DelRoute(RouteMessage),
38    GetRoute(RouteMessage),
39    NewQueueDiscipline(TcMessage),
40    DelQueueDiscipline(TcMessage),
41    GetQueueDiscipline(TcMessage),
42    NewTrafficClass(TcMessage),
43    DelTrafficClass(TcMessage),
44    GetTrafficClass(TcMessage),
45    NewTrafficFilter(TcMessage),
46    DelTrafficFilter(TcMessage),
47    GetTrafficFilter(TcMessage),
48    NewTrafficChain(TcMessage),
49    DelTrafficChain(TcMessage),
50    GetTrafficChain(TcMessage),
51    NewNsId(NsidMessage),
52    DelNsId(NsidMessage),
53    GetNsId(NsidMessage),
54    NewRule(RuleMessage),
55    DelRule(RuleMessage),
56    GetRule(RuleMessage),
57}
58
59impl RtnlMessage {
60    pub fn is_new_link(&self) -> bool {
61        matches!(self, RtnlMessage::NewLink(_))
62    }
63
64    pub fn is_del_link(&self) -> bool {
65        matches!(self, RtnlMessage::DelLink(_))
66    }
67
68    pub fn is_get_link(&self) -> bool {
69        matches!(self, RtnlMessage::GetLink(_))
70    }
71
72    pub fn is_set_link(&self) -> bool {
73        matches!(self, RtnlMessage::SetLink(_))
74    }
75
76    pub fn is_new_address(&self) -> bool {
77        matches!(self, RtnlMessage::NewAddress(_))
78    }
79
80    pub fn is_del_address(&self) -> bool {
81        matches!(self, RtnlMessage::DelAddress(_))
82    }
83
84    pub fn is_get_address(&self) -> bool {
85        matches!(self, RtnlMessage::GetAddress(_))
86    }
87
88    pub fn is_get_neighbour(&self) -> bool {
89        matches!(self, RtnlMessage::GetNeighbour(_))
90    }
91
92    pub fn is_new_route(&self) -> bool {
93        matches!(self, RtnlMessage::NewRoute(_))
94    }
95
96    pub fn is_new_neighbour(&self) -> bool {
97        matches!(self, RtnlMessage::NewNeighbour(_))
98    }
99
100    pub fn is_get_route(&self) -> bool {
101        matches!(self, RtnlMessage::GetRoute(_))
102    }
103
104    pub fn is_del_neighbour(&self) -> bool {
105        matches!(self, RtnlMessage::DelNeighbour(_))
106    }
107
108    pub fn is_new_neighbour_table(&self) -> bool {
109        matches!(self, RtnlMessage::NewNeighbourTable(_))
110    }
111
112    pub fn is_get_neighbour_table(&self) -> bool {
113        matches!(self, RtnlMessage::GetNeighbourTable(_))
114    }
115
116    pub fn is_set_neighbour_table(&self) -> bool {
117        matches!(self, RtnlMessage::SetNeighbourTable(_))
118    }
119
120    pub fn is_del_route(&self) -> bool {
121        matches!(self, RtnlMessage::DelRoute(_))
122    }
123
124    pub fn is_new_qdisc(&self) -> bool {
125        matches!(self, RtnlMessage::NewQueueDiscipline(_))
126    }
127
128    pub fn is_del_qdisc(&self) -> bool {
129        matches!(self, RtnlMessage::DelQueueDiscipline(_))
130    }
131
132    pub fn is_get_qdisc(&self) -> bool {
133        matches!(self, RtnlMessage::GetQueueDiscipline(_))
134    }
135
136    pub fn is_new_class(&self) -> bool {
137        matches!(self, RtnlMessage::NewTrafficClass(_))
138    }
139
140    pub fn is_del_class(&self) -> bool {
141        matches!(self, RtnlMessage::DelTrafficClass(_))
142    }
143
144    pub fn is_get_class(&self) -> bool {
145        matches!(self, RtnlMessage::GetTrafficClass(_))
146    }
147
148    pub fn is_new_filter(&self) -> bool {
149        matches!(self, RtnlMessage::NewTrafficFilter(_))
150    }
151
152    pub fn is_del_filter(&self) -> bool {
153        matches!(self, RtnlMessage::DelTrafficFilter(_))
154    }
155
156    pub fn is_get_filter(&self) -> bool {
157        matches!(self, RtnlMessage::GetTrafficFilter(_))
158    }
159
160    pub fn is_new_chain(&self) -> bool {
161        matches!(self, RtnlMessage::NewTrafficChain(_))
162    }
163
164    pub fn is_del_chain(&self) -> bool {
165        matches!(self, RtnlMessage::DelTrafficChain(_))
166    }
167
168    pub fn is_get_chain(&self) -> bool {
169        matches!(self, RtnlMessage::GetTrafficChain(_))
170    }
171
172    pub fn is_new_nsid(&self) -> bool {
173        matches!(self, RtnlMessage::NewNsId(_))
174    }
175
176    pub fn is_get_nsid(&self) -> bool {
177        matches!(self, RtnlMessage::GetNsId(_))
178    }
179
180    pub fn is_del_nsid(&self) -> bool {
181        matches!(self, RtnlMessage::DelNsId(_))
182    }
183
184    pub fn is_get_rule(&self) -> bool {
185        matches!(self, RtnlMessage::GetRule(_))
186    }
187
188    pub fn is_new_rule(&self) -> bool {
189        matches!(self, RtnlMessage::NewRule(_))
190    }
191
192    pub fn is_del_rule(&self) -> bool {
193        matches!(self, RtnlMessage::DelRule(_))
194    }
195
196    pub fn message_type(&self) -> u16 {
197        use self::RtnlMessage::*;
198
199        match self {
200            NewLink(_) => RTM_NEWLINK,
201            DelLink(_) => RTM_DELLINK,
202            GetLink(_) => RTM_GETLINK,
203            SetLink(_) => RTM_SETLINK,
204            NewLinkProp(_) => RTM_NEWLINKPROP,
205            DelLinkProp(_) => RTM_DELLINKPROP,
206            NewAddress(_) => RTM_NEWADDR,
207            DelAddress(_) => RTM_DELADDR,
208            GetAddress(_) => RTM_GETADDR,
209            GetNeighbour(_) => RTM_GETNEIGH,
210            NewNeighbour(_) => RTM_NEWNEIGH,
211            DelNeighbour(_) => RTM_DELNEIGH,
212            GetNeighbourTable(_) => RTM_GETNEIGHTBL,
213            NewNeighbourTable(_) => RTM_NEWNEIGHTBL,
214            SetNeighbourTable(_) => RTM_SETNEIGHTBL,
215            NewRoute(_) => RTM_NEWROUTE,
216            DelRoute(_) => RTM_DELROUTE,
217            GetRoute(_) => RTM_GETROUTE,
218            NewQueueDiscipline(_) => RTM_NEWQDISC,
219            DelQueueDiscipline(_) => RTM_DELQDISC,
220            GetQueueDiscipline(_) => RTM_GETQDISC,
221            NewTrafficClass(_) => RTM_NEWTCLASS,
222            DelTrafficClass(_) => RTM_DELTCLASS,
223            GetTrafficClass(_) => RTM_GETTCLASS,
224            NewTrafficFilter(_) => RTM_NEWTFILTER,
225            DelTrafficFilter(_) => RTM_DELTFILTER,
226            GetTrafficFilter(_) => RTM_GETTFILTER,
227            NewTrafficChain(_) => RTM_NEWCHAIN,
228            DelTrafficChain(_) => RTM_DELCHAIN,
229            GetTrafficChain(_) => RTM_GETCHAIN,
230            GetNsId(_) => RTM_GETNSID,
231            NewNsId(_) => RTM_NEWNSID,
232            DelNsId(_) => RTM_DELNSID,
233            GetRule(_) => RTM_GETRULE,
234            NewRule(_) => RTM_NEWRULE,
235            DelRule(_) => RTM_DELRULE,
236        }
237    }
238}
239
240impl Emitable for RtnlMessage {
241    #[rustfmt::skip]
242    fn buffer_len(&self) -> usize {
243        use self::RtnlMessage::*;
244        match self {
245            | NewLink(ref msg)
246            | DelLink(ref msg)
247            | GetLink(ref msg)
248            | SetLink(ref msg)
249            | NewLinkProp(ref msg)
250            | DelLinkProp(ref msg)
251            =>  msg.buffer_len(),
252
253            | NewAddress(ref msg)
254            | DelAddress(ref msg)
255            | GetAddress(ref msg)
256            => msg.buffer_len(),
257
258            | NewNeighbour(ref msg)
259            | GetNeighbour(ref msg)
260            | DelNeighbour(ref msg)
261            => msg.buffer_len(),
262
263            | NewNeighbourTable(ref msg)
264            | GetNeighbourTable(ref msg)
265            | SetNeighbourTable(ref msg)
266            => msg.buffer_len(),
267
268            | NewRoute(ref msg)
269            | DelRoute(ref msg)
270            | GetRoute(ref msg)
271            => msg.buffer_len(),
272
273            | NewQueueDiscipline(ref msg)
274            | DelQueueDiscipline(ref msg)
275            | GetQueueDiscipline(ref msg)
276            | NewTrafficClass(ref msg)
277            | DelTrafficClass(ref msg)
278            | GetTrafficClass(ref msg)
279            | NewTrafficFilter(ref msg)
280            | DelTrafficFilter(ref msg)
281            | GetTrafficFilter(ref msg)
282            | NewTrafficChain(ref msg)
283            | DelTrafficChain(ref msg)
284            | GetTrafficChain(ref msg)
285            => msg.buffer_len(),
286
287            | NewNsId(ref msg)
288            | DelNsId(ref msg)
289            | GetNsId(ref msg)
290            => msg.buffer_len(),
291
292            | NewRule(ref msg)
293            | DelRule(ref msg)
294            | GetRule(ref msg)
295            => msg.buffer_len()
296        }
297    }
298
299    #[rustfmt::skip]
300    fn emit(&self, buffer: &mut [u8]) {
301        use self::RtnlMessage::*;
302        match self {
303            | NewLink(ref msg)
304            | DelLink(ref msg)
305            | GetLink(ref msg)
306            | SetLink(ref msg)
307            | NewLinkProp(ref msg)
308            | DelLinkProp(ref msg)
309            => msg.emit(buffer),
310
311            | NewAddress(ref msg)
312            | DelAddress(ref msg)
313            | GetAddress(ref msg)
314            => msg.emit(buffer),
315
316            | GetNeighbour(ref msg)
317            | NewNeighbour(ref msg)
318            | DelNeighbour(ref msg)
319            => msg.emit(buffer),
320
321            | GetNeighbourTable(ref msg)
322            | NewNeighbourTable(ref msg)
323            | SetNeighbourTable(ref msg)
324            => msg.emit(buffer),
325
326            | NewRoute(ref msg)
327            | DelRoute(ref msg)
328            | GetRoute(ref msg)
329            => msg.emit(buffer),
330
331            | NewQueueDiscipline(ref msg)
332            | DelQueueDiscipline(ref msg)
333            | GetQueueDiscipline(ref msg)
334            | NewTrafficClass(ref msg)
335            | DelTrafficClass(ref msg)
336            | GetTrafficClass(ref msg)
337            | NewTrafficFilter(ref msg)
338            | DelTrafficFilter(ref msg)
339            | GetTrafficFilter(ref msg)
340            | NewTrafficChain(ref msg)
341            | DelTrafficChain(ref msg)
342            | GetTrafficChain(ref msg)
343            => msg.emit(buffer),
344
345            | NewNsId(ref msg)
346            | DelNsId(ref msg)
347            | GetNsId(ref msg)
348            => msg.emit(buffer),
349
350            | NewRule(ref msg)
351            | DelRule(ref msg)
352            | GetRule(ref msg)
353            => msg.emit(buffer)
354        }
355    }
356}
357
358impl NetlinkSerializable for RtnlMessage {
359    fn message_type(&self) -> u16 {
360        self.message_type()
361    }
362
363    fn buffer_len(&self) -> usize {
364        <Self as Emitable>::buffer_len(self)
365    }
366
367    fn serialize(&self, buffer: &mut [u8]) {
368        self.emit(buffer)
369    }
370}
371
372impl NetlinkDeserializable for RtnlMessage {
373    type Error = DecodeError;
374    fn deserialize(
375        header: &NetlinkHeader,
376        payload: &[u8],
377    ) -> Result<Self, Self::Error> {
378        let buf = RtnlMessageBuffer::new(payload);
379        match RtnlMessage::parse_with_param(&buf, header.message_type) {
380            Err(e) => Err(e),
381            Ok(message) => Ok(message),
382        }
383    }
384}
385
386impl From<RtnlMessage> for NetlinkPayload<RtnlMessage> {
387    fn from(message: RtnlMessage) -> Self {
388        NetlinkPayload::InnerMessage(message)
389    }
390}