netlink_packet_route/rtnl/
message.rs1use 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}