netlink_packet_route/rtnl/
message.rs

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