1use crate::AddressFamily;
4use crate::address::{AddressError, AddressHeader, AddressMessage, AddressMessageBuffer};
5use crate::link::{LinkAttribute, LinkExtentMask, LinkHeader, LinkMessage, LinkMessageBuffer};
6use crate::neighbour::{NeighbourError, NeighbourMessage, NeighbourMessageBuffer};
7use crate::neighbour_discovery_user_option::{
8 NeighbourDiscoveryUserOptionError, NeighbourDiscoveryUserOptionMessage,
9 NeighbourDiscoveryUserOptionMessageBuffer,
10};
11use crate::neighbour_table::{
12 NeighbourTableError, NeighbourTableMessage, NeighbourTableMessageBuffer,
13};
14use crate::nsid::{NsidError, NsidMessage, NsidMessageBuffer};
15use crate::prefix::{PrefixError, PrefixMessage, PrefixMessageBuffer};
16use crate::route::{RouteError, RouteHeader, RouteMessage, RouteMessageBuffer};
17use crate::rule::{RuleError, RuleMessage, RuleMessageBuffer};
18use crate::tc::{TcError, TcMessage, TcMessageBuffer};
19use netlink_packet_core::{
20 NetlinkDeserializable, NetlinkHeader, NetlinkPayload, NetlinkSerializable,
21};
22use netlink_packet_utils::{DecodeError, Emitable, Parseable, ParseableParametrized};
23use thiserror::Error;
24
25const RTM_NEWLINK: u16 = 16;
26const RTM_DELLINK: u16 = 17;
27const RTM_GETLINK: u16 = 18;
28const RTM_SETLINK: u16 = 19;
29const RTM_NEWADDR: u16 = 20;
30const RTM_DELADDR: u16 = 21;
31const RTM_GETADDR: u16 = 22;
32const RTM_NEWROUTE: u16 = 24;
33const RTM_DELROUTE: u16 = 25;
34const RTM_GETROUTE: u16 = 26;
35const RTM_NEWNEIGH: u16 = 28;
36const RTM_DELNEIGH: u16 = 29;
37const RTM_GETNEIGH: u16 = 30;
38const RTM_NEWRULE: u16 = 32;
39const RTM_DELRULE: u16 = 33;
40const RTM_GETRULE: u16 = 34;
41const RTM_NEWQDISC: u16 = 36;
42const RTM_DELQDISC: u16 = 37;
43const RTM_GETQDISC: u16 = 38;
44const RTM_NEWTCLASS: u16 = 40;
45const RTM_DELTCLASS: u16 = 41;
46const RTM_GETTCLASS: u16 = 42;
47const RTM_NEWTFILTER: u16 = 44;
48const RTM_DELTFILTER: u16 = 45;
49const RTM_GETTFILTER: u16 = 46;
50const RTM_NEWPREFIX: u16 = 52;
54const RTM_NEWNEIGHTBL: u16 = 64;
57const RTM_GETNEIGHTBL: u16 = 66;
58const RTM_SETNEIGHTBL: u16 = 67;
59const RTM_NEWNDUSEROPT: u16 = 68;
60const RTM_NEWNSID: u16 = 88;
72const RTM_DELNSID: u16 = 89;
73const RTM_GETNSID: u16 = 90;
74const RTM_NEWCHAIN: u16 = 100;
78const RTM_DELCHAIN: u16 = 101;
79const RTM_GETCHAIN: u16 = 102;
80const RTM_NEWLINKPROP: u16 = 108;
81const RTM_DELLINKPROP: u16 = 109;
82
83buffer!(RouteNetlinkMessageBuffer);
84
85#[derive(Debug, Error)]
86pub enum RouteNetlinkMessageParseError {
87 #[error("Invalid link message")]
88 InvalidLinkMessage(#[source] DecodeError),
89
90 #[error(transparent)]
91 InvalidRouteMessage(#[from] RouteError),
92
93 #[error(transparent)]
94 InvalidAddrMessage(#[from] AddressError),
95
96 #[error(transparent)]
97 InvalidPrefixMessage(#[from] PrefixError),
98
99 #[error(transparent)]
100 InvalidFibRuleMessage(#[from] RuleError),
101
102 #[error(transparent)]
103 InvalidTcMessage(#[from] TcError),
104
105 #[error(transparent)]
106 InvalidNsidMessage(#[from] NsidError),
107
108 #[error(transparent)]
109 InvalidNeighbourMessage(#[from] NeighbourError),
110
111 #[error(transparent)]
112 InvalidNeighbourTableMessage(#[from] NeighbourTableError),
113
114 #[error(transparent)]
115 InvalidNeighbourDiscoveryUserOptionMessage(#[from] NeighbourDiscoveryUserOptionError),
116
117 #[error("Unknown message type: {0}")]
118 UnknownMessageType(u16),
119
120 #[error("Parse buffer: {0}")]
121 ParseBuffer(#[source] DecodeError),
122}
123
124impl From<RouteNetlinkMessageParseError> for DecodeError {
125 fn from(e: RouteNetlinkMessageParseError) -> Self {
126 DecodeError::Other(e.into())
127 }
128}
129
130fn looks_like_bad_iproute2_dump_req<'a, T: AsRef<[u8]> + ?Sized>(
150 buf: &RouteNetlinkMessageBuffer<&'a T>,
151) -> Option<AddressFamily> {
152 let buf_inner = buf.inner();
153 let buffer = LinkMessageBuffer::new(&buf_inner).ok()?;
154 let as_link_msg = LinkMessage::parse(&buffer).ok()?;
155
156 let bad_req_format = LinkMessage {
161 header: LinkHeader {
162 interface_family: as_link_msg.header.interface_family,
163 ..Default::default()
164 },
165 attributes: vec![LinkAttribute::ExtMask(vec![LinkExtentMask::Vf])],
166 ..Default::default()
167 };
168 (as_link_msg == bad_req_format).then_some(as_link_msg.header.interface_family)
169}
170
171impl<'a, T: AsRef<[u8]> + ?Sized> ParseableParametrized<RouteNetlinkMessageBuffer<&'a T>, u16>
172 for RouteNetlinkMessage
173{
174 type Error = RouteNetlinkMessageParseError;
175
176 fn parse_with_param(
177 buf: &RouteNetlinkMessageBuffer<&'a T>,
178 message_type: u16,
179 ) -> Result<Self, Self::Error> {
180 let message = match message_type {
181 RTM_NEWLINK | RTM_GETLINK | RTM_DELLINK | RTM_SETLINK => {
183 let msg = match LinkMessageBuffer::new(&buf.inner()) {
184 Ok(buf) => LinkMessage::parse(&buf)
185 .map_err(RouteNetlinkMessageParseError::InvalidLinkMessage)?,
186 Err(e) => {
190 if buf.inner().len() == 4 && message_type == RTM_GETLINK {
191 let mut msg = LinkMessage::default();
192 msg.header.interface_family = buf.inner()[0].into();
193 msg
194 } else {
195 return Err(RouteNetlinkMessageParseError::InvalidLinkMessage(e));
196 }
197 }
198 };
199 match message_type {
200 RTM_NEWLINK => RouteNetlinkMessage::NewLink(msg),
201 RTM_GETLINK => RouteNetlinkMessage::GetLink(msg),
202 RTM_DELLINK => RouteNetlinkMessage::DelLink(msg),
203 RTM_SETLINK => RouteNetlinkMessage::SetLink(msg),
204 _ => unreachable!(),
205 }
206 }
207
208 RTM_NEWADDR | RTM_GETADDR | RTM_DELADDR => {
210 let msg = match AddressMessageBuffer::new(&buf.inner()) {
211 Ok(buffer) => AddressMessage::parse(&buffer).or_else(|e| {
212 if message_type == RTM_GETADDR
213 && let Some(af) = looks_like_bad_iproute2_dump_req(buf)
214 {
215 let mut message = AddressMessage::default();
216 message.header.family = af.into();
217 return Ok(message);
218 }
219 Err(e)
220 })?,
221 Err(e) => {
225 if buf.inner().len() == 4 && message_type == RTM_GETADDR {
226 let mut msg = AddressMessage {
227 header: AddressHeader::default(),
228 attributes: vec![],
229 };
230 msg.header.family = buf.inner()[0].into();
231 msg
232 } else {
233 return Err(RouteNetlinkMessageParseError::InvalidAddrMessage(
234 AddressError::FailedBufferInit(e),
235 ));
236 }
237 }
238 };
239 match message_type {
240 RTM_NEWADDR => RouteNetlinkMessage::NewAddress(msg),
241 RTM_GETADDR => RouteNetlinkMessage::GetAddress(msg),
242 RTM_DELADDR => RouteNetlinkMessage::DelAddress(msg),
243 _ => unreachable!(),
244 }
245 }
246
247 RTM_NEWNEIGH | RTM_GETNEIGH | RTM_DELNEIGH => {
249 let buf_inner = buf.inner();
250 let buffer = NeighbourMessageBuffer::new(&buf_inner)
251 .map_err(RouteNetlinkMessageParseError::ParseBuffer)?;
252 let msg = NeighbourMessage::parse(&buffer)?;
253 match message_type {
254 RTM_GETNEIGH => RouteNetlinkMessage::GetNeighbour(msg),
255 RTM_NEWNEIGH => RouteNetlinkMessage::NewNeighbour(msg),
256 RTM_DELNEIGH => RouteNetlinkMessage::DelNeighbour(msg),
257 _ => unreachable!(),
258 }
259 }
260
261 RTM_NEWNEIGHTBL | RTM_GETNEIGHTBL | RTM_SETNEIGHTBL => {
263 let buf_inner = buf.inner();
264 let buffer = NeighbourTableMessageBuffer::new(&buf_inner)
265 .map_err(RouteNetlinkMessageParseError::ParseBuffer)?;
266 let msg = NeighbourTableMessage::parse(&buffer)
267 .map_err(RouteNetlinkMessageParseError::InvalidNeighbourTableMessage)?;
268 match message_type {
269 RTM_GETNEIGHTBL => RouteNetlinkMessage::GetNeighbourTable(msg),
270 RTM_NEWNEIGHTBL => RouteNetlinkMessage::NewNeighbourTable(msg),
271 RTM_SETNEIGHTBL => RouteNetlinkMessage::SetNeighbourTable(msg),
272 _ => unreachable!(),
273 }
274 }
275
276 RTM_NEWNDUSEROPT => {
277 let msg = NeighbourDiscoveryUserOptionMessage::parse(
278 &NeighbourDiscoveryUserOptionMessageBuffer::new(&buf.inner())
279 .map_err(NeighbourDiscoveryUserOptionError::ParseBuffer)?,
280 )?;
281 RouteNetlinkMessage::NewNeighbourDiscoveryUserOption(msg)
282 }
283
284 RTM_NEWROUTE | RTM_GETROUTE | RTM_DELROUTE => {
286 let msg = match RouteMessageBuffer::new(&buf.inner()) {
287 Ok(buffer) => RouteMessage::parse(&buffer).or_else(|e| {
288 if message_type == RTM_GETROUTE
289 && let Some(af) = looks_like_bad_iproute2_dump_req(buf)
290 {
291 let mut message = RouteMessage::default();
292 message.header.address_family = af;
293 return Ok(message);
294 }
295 Err(e)
296 })?,
297 Err(e) => {
301 if (buf.inner().len() == 4 || buf.inner().len() == 1)
310 && message_type == RTM_GETROUTE
311 {
312 let mut msg =
313 RouteMessage { header: RouteHeader::default(), attributes: vec![] };
314 msg.header.address_family = buf.inner()[0].into();
315 msg
316 } else {
317 return Err(RouteNetlinkMessageParseError::ParseBuffer(e));
318 }
319 }
320 };
321 match message_type {
322 RTM_NEWROUTE => RouteNetlinkMessage::NewRoute(msg),
323 RTM_GETROUTE => RouteNetlinkMessage::GetRoute(msg),
324 RTM_DELROUTE => RouteNetlinkMessage::DelRoute(msg),
325 _ => unreachable!(),
326 }
327 }
328
329 RTM_NEWPREFIX => {
331 let buf_inner = buf.inner();
332 let buffer = PrefixMessageBuffer::new(&buf_inner)
333 .map_err(RouteNetlinkMessageParseError::ParseBuffer)?;
334 RouteNetlinkMessage::NewPrefix(PrefixMessage::parse(&buffer)?)
335 }
336 RTM_NEWRULE | RTM_GETRULE | RTM_DELRULE => {
337 let buf_inner = buf.inner();
338 let buffer = RuleMessageBuffer::new(&buf_inner)
339 .map_err(RouteNetlinkMessageParseError::ParseBuffer)?;
340 let msg = RuleMessage::parse(&buffer).or_else(|e| {
341 if message_type == RTM_GETRULE
342 && let Some(af) = looks_like_bad_iproute2_dump_req(buf)
343 {
344 let mut message = RuleMessage::default();
345 message.header.family = af;
346 return Ok(message);
347 }
348 Err(e)
349 })?;
350 match message_type {
351 RTM_NEWRULE => RouteNetlinkMessage::NewRule(msg),
352 RTM_DELRULE => RouteNetlinkMessage::DelRule(msg),
353 RTM_GETRULE => RouteNetlinkMessage::GetRule(msg),
354 _ => unreachable!(),
355 }
356 }
357 RTM_NEWQDISC | RTM_DELQDISC | RTM_GETQDISC | RTM_NEWTCLASS | RTM_DELTCLASS
359 | RTM_GETTCLASS | RTM_NEWTFILTER | RTM_DELTFILTER | RTM_GETTFILTER | RTM_NEWCHAIN
360 | RTM_DELCHAIN | RTM_GETCHAIN => {
361 let buf_inner = buf.inner();
362 let buffer = TcMessageBuffer::new(&buf_inner)
363 .map_err(RouteNetlinkMessageParseError::ParseBuffer)?;
364 let msg = TcMessage::parse(&buffer)?;
365 match message_type {
366 RTM_NEWQDISC => RouteNetlinkMessage::NewQueueDiscipline(msg),
367 RTM_DELQDISC => RouteNetlinkMessage::DelQueueDiscipline(msg),
368 RTM_GETQDISC => RouteNetlinkMessage::GetQueueDiscipline(msg),
369 RTM_NEWTCLASS => RouteNetlinkMessage::NewTrafficClass(msg),
370 RTM_DELTCLASS => RouteNetlinkMessage::DelTrafficClass(msg),
371 RTM_GETTCLASS => RouteNetlinkMessage::GetTrafficClass(msg),
372 RTM_NEWTFILTER => RouteNetlinkMessage::NewTrafficFilter(msg),
373 RTM_DELTFILTER => RouteNetlinkMessage::DelTrafficFilter(msg),
374 RTM_GETTFILTER => RouteNetlinkMessage::GetTrafficFilter(msg),
375 RTM_NEWCHAIN => RouteNetlinkMessage::NewTrafficChain(msg),
376 RTM_DELCHAIN => RouteNetlinkMessage::DelTrafficChain(msg),
377 RTM_GETCHAIN => RouteNetlinkMessage::GetTrafficChain(msg),
378 _ => unreachable!(),
379 }
380 }
381
382 RTM_NEWNSID | RTM_GETNSID | RTM_DELNSID => {
384 let buf_inner = buf.inner();
385 let buffer = NsidMessageBuffer::new(&buf_inner)
386 .map_err(RouteNetlinkMessageParseError::ParseBuffer)?;
387 let msg = NsidMessage::parse(&buffer)?;
388 match message_type {
389 RTM_NEWNSID => RouteNetlinkMessage::NewNsId(msg),
390 RTM_DELNSID => RouteNetlinkMessage::DelNsId(msg),
391 RTM_GETNSID => RouteNetlinkMessage::GetNsId(msg),
392 _ => unreachable!(),
393 }
394 }
395
396 _ => return Err(RouteNetlinkMessageParseError::UnknownMessageType(message_type)),
397 };
398 Ok(message)
399 }
400}
401
402#[derive(Debug, PartialEq, Eq, Clone)]
403pub enum RouteNetlinkMessage {
404 NewLink(LinkMessage),
405 DelLink(LinkMessage),
406 GetLink(LinkMessage),
407 SetLink(LinkMessage),
408 NewLinkProp(LinkMessage),
409 DelLinkProp(LinkMessage),
410 NewAddress(AddressMessage),
411 DelAddress(AddressMessage),
412 GetAddress(AddressMessage),
413 NewNeighbour(NeighbourMessage),
414 GetNeighbour(NeighbourMessage),
415 DelNeighbour(NeighbourMessage),
416 NewNeighbourTable(NeighbourTableMessage),
417 GetNeighbourTable(NeighbourTableMessage),
418 SetNeighbourTable(NeighbourTableMessage),
419 NewNeighbourDiscoveryUserOption(NeighbourDiscoveryUserOptionMessage),
420 NewRoute(RouteMessage),
421 DelRoute(RouteMessage),
422 GetRoute(RouteMessage),
423 NewPrefix(PrefixMessage),
424 NewQueueDiscipline(TcMessage),
425 DelQueueDiscipline(TcMessage),
426 GetQueueDiscipline(TcMessage),
427 NewTrafficClass(TcMessage),
428 DelTrafficClass(TcMessage),
429 GetTrafficClass(TcMessage),
430 NewTrafficFilter(TcMessage),
431 DelTrafficFilter(TcMessage),
432 GetTrafficFilter(TcMessage),
433 NewTrafficChain(TcMessage),
434 DelTrafficChain(TcMessage),
435 GetTrafficChain(TcMessage),
436 NewNsId(NsidMessage),
437 DelNsId(NsidMessage),
438 GetNsId(NsidMessage),
439 NewRule(RuleMessage),
440 DelRule(RuleMessage),
441 GetRule(RuleMessage),
442}
443
444impl RouteNetlinkMessage {
445 pub fn is_new_link(&self) -> bool {
446 matches!(self, RouteNetlinkMessage::NewLink(_))
447 }
448
449 pub fn is_del_link(&self) -> bool {
450 matches!(self, RouteNetlinkMessage::DelLink(_))
451 }
452
453 pub fn is_get_link(&self) -> bool {
454 matches!(self, RouteNetlinkMessage::GetLink(_))
455 }
456
457 pub fn is_set_link(&self) -> bool {
458 matches!(self, RouteNetlinkMessage::SetLink(_))
459 }
460
461 pub fn is_new_address(&self) -> bool {
462 matches!(self, RouteNetlinkMessage::NewAddress(_))
463 }
464
465 pub fn is_del_address(&self) -> bool {
466 matches!(self, RouteNetlinkMessage::DelAddress(_))
467 }
468
469 pub fn is_get_address(&self) -> bool {
470 matches!(self, RouteNetlinkMessage::GetAddress(_))
471 }
472
473 pub fn is_get_neighbour(&self) -> bool {
474 matches!(self, RouteNetlinkMessage::GetNeighbour(_))
475 }
476
477 pub fn is_new_route(&self) -> bool {
478 matches!(self, RouteNetlinkMessage::NewRoute(_))
479 }
480
481 pub fn is_new_neighbour(&self) -> bool {
482 matches!(self, RouteNetlinkMessage::NewNeighbour(_))
483 }
484
485 pub fn is_get_route(&self) -> bool {
486 matches!(self, RouteNetlinkMessage::GetRoute(_))
487 }
488
489 pub fn is_del_neighbour(&self) -> bool {
490 matches!(self, RouteNetlinkMessage::DelNeighbour(_))
491 }
492
493 pub fn is_new_neighbour_table(&self) -> bool {
494 matches!(self, RouteNetlinkMessage::NewNeighbourTable(_))
495 }
496
497 pub fn is_get_neighbour_table(&self) -> bool {
498 matches!(self, RouteNetlinkMessage::GetNeighbourTable(_))
499 }
500
501 pub fn is_set_neighbour_table(&self) -> bool {
502 matches!(self, RouteNetlinkMessage::SetNeighbourTable(_))
503 }
504
505 pub fn is_del_route(&self) -> bool {
506 matches!(self, RouteNetlinkMessage::DelRoute(_))
507 }
508
509 pub fn is_new_qdisc(&self) -> bool {
510 matches!(self, RouteNetlinkMessage::NewQueueDiscipline(_))
511 }
512
513 pub fn is_del_qdisc(&self) -> bool {
514 matches!(self, RouteNetlinkMessage::DelQueueDiscipline(_))
515 }
516
517 pub fn is_get_qdisc(&self) -> bool {
518 matches!(self, RouteNetlinkMessage::GetQueueDiscipline(_))
519 }
520
521 pub fn is_new_class(&self) -> bool {
522 matches!(self, RouteNetlinkMessage::NewTrafficClass(_))
523 }
524
525 pub fn is_del_class(&self) -> bool {
526 matches!(self, RouteNetlinkMessage::DelTrafficClass(_))
527 }
528
529 pub fn is_get_class(&self) -> bool {
530 matches!(self, RouteNetlinkMessage::GetTrafficClass(_))
531 }
532
533 pub fn is_new_filter(&self) -> bool {
534 matches!(self, RouteNetlinkMessage::NewTrafficFilter(_))
535 }
536
537 pub fn is_del_filter(&self) -> bool {
538 matches!(self, RouteNetlinkMessage::DelTrafficFilter(_))
539 }
540
541 pub fn is_get_filter(&self) -> bool {
542 matches!(self, RouteNetlinkMessage::GetTrafficFilter(_))
543 }
544
545 pub fn is_new_chain(&self) -> bool {
546 matches!(self, RouteNetlinkMessage::NewTrafficChain(_))
547 }
548
549 pub fn is_del_chain(&self) -> bool {
550 matches!(self, RouteNetlinkMessage::DelTrafficChain(_))
551 }
552
553 pub fn is_get_chain(&self) -> bool {
554 matches!(self, RouteNetlinkMessage::GetTrafficChain(_))
555 }
556
557 pub fn is_new_nsid(&self) -> bool {
558 matches!(self, RouteNetlinkMessage::NewNsId(_))
559 }
560
561 pub fn is_get_nsid(&self) -> bool {
562 matches!(self, RouteNetlinkMessage::GetNsId(_))
563 }
564
565 pub fn is_del_nsid(&self) -> bool {
566 matches!(self, RouteNetlinkMessage::DelNsId(_))
567 }
568
569 pub fn is_get_rule(&self) -> bool {
570 matches!(self, RouteNetlinkMessage::GetRule(_))
571 }
572
573 pub fn is_new_rule(&self) -> bool {
574 matches!(self, RouteNetlinkMessage::NewRule(_))
575 }
576
577 pub fn is_del_rule(&self) -> bool {
578 matches!(self, RouteNetlinkMessage::DelRule(_))
579 }
580
581 pub fn message_type(&self) -> u16 {
582 use self::RouteNetlinkMessage::*;
583
584 match self {
585 NewLink(_) => RTM_NEWLINK,
586 DelLink(_) => RTM_DELLINK,
587 GetLink(_) => RTM_GETLINK,
588 SetLink(_) => RTM_SETLINK,
589 NewLinkProp(_) => RTM_NEWLINKPROP,
590 DelLinkProp(_) => RTM_DELLINKPROP,
591 NewAddress(_) => RTM_NEWADDR,
592 DelAddress(_) => RTM_DELADDR,
593 GetAddress(_) => RTM_GETADDR,
594 GetNeighbour(_) => RTM_GETNEIGH,
595 NewNeighbour(_) => RTM_NEWNEIGH,
596 DelNeighbour(_) => RTM_DELNEIGH,
597 GetNeighbourTable(_) => RTM_GETNEIGHTBL,
598 NewNeighbourTable(_) => RTM_NEWNEIGHTBL,
599 SetNeighbourTable(_) => RTM_SETNEIGHTBL,
600 NewNeighbourDiscoveryUserOption(_) => RTM_NEWNDUSEROPT,
601 NewRoute(_) => RTM_NEWROUTE,
602 DelRoute(_) => RTM_DELROUTE,
603 GetRoute(_) => RTM_GETROUTE,
604 NewPrefix(_) => RTM_NEWPREFIX,
605 NewQueueDiscipline(_) => RTM_NEWQDISC,
606 DelQueueDiscipline(_) => RTM_DELQDISC,
607 GetQueueDiscipline(_) => RTM_GETQDISC,
608 NewTrafficClass(_) => RTM_NEWTCLASS,
609 DelTrafficClass(_) => RTM_DELTCLASS,
610 GetTrafficClass(_) => RTM_GETTCLASS,
611 NewTrafficFilter(_) => RTM_NEWTFILTER,
612 DelTrafficFilter(_) => RTM_DELTFILTER,
613 GetTrafficFilter(_) => RTM_GETTFILTER,
614 NewTrafficChain(_) => RTM_NEWCHAIN,
615 DelTrafficChain(_) => RTM_DELCHAIN,
616 GetTrafficChain(_) => RTM_GETCHAIN,
617 GetNsId(_) => RTM_GETNSID,
618 NewNsId(_) => RTM_NEWNSID,
619 DelNsId(_) => RTM_DELNSID,
620 GetRule(_) => RTM_GETRULE,
621 NewRule(_) => RTM_NEWRULE,
622 DelRule(_) => RTM_DELRULE,
623 }
624 }
625}
626
627impl Emitable for RouteNetlinkMessage {
628 #[rustfmt::skip]
629 fn buffer_len(&self) -> usize {
630 use self::RouteNetlinkMessage::*;
631 match self {
632 | NewLink(msg)
633 | DelLink(msg)
634 | GetLink(msg)
635 | SetLink(msg)
636 | NewLinkProp(msg)
637 | DelLinkProp(msg)
638 => msg.buffer_len(),
639
640 | NewAddress(msg)
641 | DelAddress(msg)
642 | GetAddress(msg)
643 => msg.buffer_len(),
644
645 | NewNeighbour(msg)
646 | GetNeighbour(msg)
647 | DelNeighbour(msg)
648 => msg.buffer_len(),
649
650 | NewNeighbourTable(msg)
651 | GetNeighbourTable(msg)
652 | SetNeighbourTable(msg)
653 => msg.buffer_len(),
654
655 | NewNeighbourDiscoveryUserOption(msg) => msg.buffer_len(),
656
657 | NewRoute(msg)
658 | DelRoute(msg)
659 | GetRoute(msg)
660 => msg.buffer_len(),
661
662 NewPrefix(msg) => msg.buffer_len(),
663
664 | NewQueueDiscipline(msg)
665 | DelQueueDiscipline(msg)
666 | GetQueueDiscipline(msg)
667 | NewTrafficClass(msg)
668 | DelTrafficClass(msg)
669 | GetTrafficClass(msg)
670 | NewTrafficFilter(msg)
671 | DelTrafficFilter(msg)
672 | GetTrafficFilter(msg)
673 | NewTrafficChain(msg)
674 | DelTrafficChain(msg)
675 | GetTrafficChain(msg)
676 => msg.buffer_len(),
677
678 | NewNsId(msg)
679 | DelNsId(msg)
680 | GetNsId(msg)
681 => msg.buffer_len(),
682
683 | NewRule(msg)
684 | DelRule(msg)
685 | GetRule(msg)
686 => msg.buffer_len()
687 }
688 }
689
690 #[rustfmt::skip]
691 fn emit(&self, buffer: &mut [u8]) {
692 use self::RouteNetlinkMessage::*;
693 match self {
694 | NewLink(msg)
695 | DelLink(msg)
696 | GetLink(msg)
697 | SetLink(msg)
698 | NewLinkProp(msg)
699 | DelLinkProp(msg)
700 => msg.emit(buffer),
701
702 | NewAddress(msg)
703 | DelAddress(msg)
704 | GetAddress(msg)
705 => msg.emit(buffer),
706
707 | GetNeighbour(msg)
708 | NewNeighbour(msg)
709 | DelNeighbour(msg)
710 => msg.emit(buffer),
711
712 | GetNeighbourTable(msg)
713 | NewNeighbourTable(msg)
714 | SetNeighbourTable(msg)
715 => msg.emit(buffer),
716
717 | NewNeighbourDiscoveryUserOption(msg) => msg.emit(buffer),
718
719 | NewRoute(msg)
720 | DelRoute(msg)
721 | GetRoute(msg)
722 => msg.emit(buffer),
723
724 | NewPrefix(msg) => msg.emit(buffer),
725
726 | NewQueueDiscipline(msg)
727 | DelQueueDiscipline(msg)
728 | GetQueueDiscipline(msg)
729 | NewTrafficClass(msg)
730 | DelTrafficClass(msg)
731 | GetTrafficClass(msg)
732 | NewTrafficFilter(msg)
733 | DelTrafficFilter(msg)
734 | GetTrafficFilter(msg)
735 | NewTrafficChain(msg)
736 | DelTrafficChain(msg)
737 | GetTrafficChain(msg)
738 => msg.emit(buffer),
739
740 | NewNsId(msg)
741 | DelNsId(msg)
742 | GetNsId(msg)
743 => msg.emit(buffer),
744
745 | NewRule(msg)
746 | DelRule(msg)
747 | GetRule(msg)
748 => msg.emit(buffer)
749 }
750 }
751}
752
753impl NetlinkSerializable for RouteNetlinkMessage {
754 fn message_type(&self) -> u16 {
755 self.message_type()
756 }
757
758 fn buffer_len(&self) -> usize {
759 <Self as Emitable>::buffer_len(self)
760 }
761
762 fn serialize(&self, buffer: &mut [u8]) {
763 self.emit(buffer)
764 }
765}
766
767impl NetlinkDeserializable for RouteNetlinkMessage {
768 type Error = RouteNetlinkMessageParseError;
769
770 fn deserialize(header: &NetlinkHeader, payload: &[u8]) -> Result<Self, Self::Error> {
771 let buf = RouteNetlinkMessageBuffer::new(payload);
772 match RouteNetlinkMessage::parse_with_param(&buf, header.message_type) {
773 Err(e) => Err(e),
774 Ok(message) => Ok(message),
775 }
776 }
777}
778
779impl From<RouteNetlinkMessage> for NetlinkPayload<RouteNetlinkMessage> {
780 fn from(message: RouteNetlinkMessage) -> Self {
781 NetlinkPayload::InnerMessage(message)
782 }
783}