1use crate::address::{AddressError, AddressHeader, AddressMessage, AddressMessageBuffer};
4use crate::link::{LinkMessage, LinkMessageBuffer};
5use crate::neighbour::{NeighbourError, NeighbourMessage, NeighbourMessageBuffer};
6use crate::neighbour_discovery_user_option::{
7 NeighbourDiscoveryUserOptionError, NeighbourDiscoveryUserOptionMessage,
8 NeighbourDiscoveryUserOptionMessageBuffer,
9};
10use crate::neighbour_table::{
11 NeighbourTableError, NeighbourTableMessage, NeighbourTableMessageBuffer,
12};
13use crate::nsid::{NsidError, NsidMessage, NsidMessageBuffer};
14use crate::prefix::{PrefixError, PrefixMessage, PrefixMessageBuffer};
15use crate::route::{RouteError, RouteHeader, RouteMessage, RouteMessageBuffer};
16use crate::rule::{RuleError, RuleMessage, RuleMessageBuffer};
17use crate::tc::{TcError, TcMessage, TcMessageBuffer};
18use netlink_packet_core::{
19 NetlinkDeserializable, NetlinkHeader, NetlinkPayload, NetlinkSerializable,
20};
21use netlink_packet_utils::nla::NlaParseMode;
22use netlink_packet_utils::{DecodeError, Emitable, 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
130#[derive(Default)]
132pub enum RouteNetlinkMessageParseMode {
133 #[default]
136 Strict,
137 Relaxed,
140}
141
142impl From<RouteNetlinkMessageParseMode> for NlaParseMode {
143 fn from(mode: RouteNetlinkMessageParseMode) -> Self {
144 match mode {
145 RouteNetlinkMessageParseMode::Strict => NlaParseMode::Strict,
146 RouteNetlinkMessageParseMode::Relaxed => NlaParseMode::Relaxed,
147 }
148 }
149}
150
151struct RouteNetlinkMessageParseConfig {
152 message_type: u16,
153 parse_mode: RouteNetlinkMessageParseMode,
154}
155
156impl<'a, T: AsRef<[u8]> + ?Sized>
157 ParseableParametrized<RouteNetlinkMessageBuffer<&'a T>, RouteNetlinkMessageParseConfig>
158 for RouteNetlinkMessage
159{
160 type Error = RouteNetlinkMessageParseError;
161
162 fn parse_with_param(
163 buf: &RouteNetlinkMessageBuffer<&'a T>,
164 RouteNetlinkMessageParseConfig { message_type, parse_mode }: RouteNetlinkMessageParseConfig,
165 ) -> Result<Self, Self::Error> {
166 let message = match message_type {
167 RTM_NEWLINK | RTM_GETLINK | RTM_DELLINK | RTM_SETLINK => {
169 let msg = match LinkMessageBuffer::new(&buf.inner()) {
170 Ok(buf) => LinkMessage::parse_with_param(&buf, parse_mode)
171 .map_err(RouteNetlinkMessageParseError::InvalidLinkMessage)?,
172 Err(e) => {
176 if buf.inner().len() == 4 && message_type == RTM_GETLINK {
177 let mut msg = LinkMessage::default();
178 msg.header.interface_family = buf.inner()[0].into();
179 msg
180 } else {
181 return Err(RouteNetlinkMessageParseError::InvalidLinkMessage(e));
182 }
183 }
184 };
185 match message_type {
186 RTM_NEWLINK => RouteNetlinkMessage::NewLink(msg),
187 RTM_GETLINK => RouteNetlinkMessage::GetLink(msg),
188 RTM_DELLINK => RouteNetlinkMessage::DelLink(msg),
189 RTM_SETLINK => RouteNetlinkMessage::SetLink(msg),
190 _ => unreachable!(),
191 }
192 }
193
194 RTM_NEWADDR | RTM_GETADDR | RTM_DELADDR => {
196 let msg = match AddressMessageBuffer::new(&buf.inner()) {
197 Ok(buffer) => AddressMessage::parse_with_param(&buffer, parse_mode)?,
198 Err(e) => {
202 if buf.inner().len() == 4 && message_type == RTM_GETADDR {
203 let mut msg = AddressMessage {
204 header: AddressHeader::default(),
205 attributes: vec![],
206 };
207 msg.header.family = buf.inner()[0].into();
208 msg
209 } else {
210 return Err(RouteNetlinkMessageParseError::InvalidAddrMessage(
211 AddressError::FailedBufferInit(e),
212 ));
213 }
214 }
215 };
216 match message_type {
217 RTM_NEWADDR => RouteNetlinkMessage::NewAddress(msg),
218 RTM_GETADDR => RouteNetlinkMessage::GetAddress(msg),
219 RTM_DELADDR => RouteNetlinkMessage::DelAddress(msg),
220 _ => unreachable!(),
221 }
222 }
223
224 RTM_NEWNEIGH | RTM_GETNEIGH | RTM_DELNEIGH => {
226 let buf_inner = buf.inner();
227 let buffer = NeighbourMessageBuffer::new(&buf_inner)
228 .map_err(RouteNetlinkMessageParseError::ParseBuffer)?;
229 let msg = NeighbourMessage::parse_with_param(&buffer, parse_mode)?;
230 match message_type {
231 RTM_GETNEIGH => RouteNetlinkMessage::GetNeighbour(msg),
232 RTM_NEWNEIGH => RouteNetlinkMessage::NewNeighbour(msg),
233 RTM_DELNEIGH => RouteNetlinkMessage::DelNeighbour(msg),
234 _ => unreachable!(),
235 }
236 }
237
238 RTM_NEWNEIGHTBL | RTM_GETNEIGHTBL | RTM_SETNEIGHTBL => {
240 let buf_inner = buf.inner();
241 let buffer = NeighbourTableMessageBuffer::new(&buf_inner)
242 .map_err(RouteNetlinkMessageParseError::ParseBuffer)?;
243 let msg = NeighbourTableMessage::parse_with_param(&buffer, parse_mode)
244 .map_err(RouteNetlinkMessageParseError::InvalidNeighbourTableMessage)?;
245 match message_type {
246 RTM_GETNEIGHTBL => RouteNetlinkMessage::GetNeighbourTable(msg),
247 RTM_NEWNEIGHTBL => RouteNetlinkMessage::NewNeighbourTable(msg),
248 RTM_SETNEIGHTBL => RouteNetlinkMessage::SetNeighbourTable(msg),
249 _ => unreachable!(),
250 }
251 }
252
253 RTM_NEWNDUSEROPT => {
254 let msg = NeighbourDiscoveryUserOptionMessage::parse_with_param(
255 &NeighbourDiscoveryUserOptionMessageBuffer::new(&buf.inner())
256 .map_err(NeighbourDiscoveryUserOptionError::ParseBuffer)?,
257 parse_mode,
258 )?;
259 RouteNetlinkMessage::NewNeighbourDiscoveryUserOption(msg)
260 }
261
262 RTM_NEWROUTE | RTM_GETROUTE | RTM_DELROUTE => {
264 let msg = match RouteMessageBuffer::new(&buf.inner()) {
265 Ok(buffer) => RouteMessage::parse_with_param(&buffer, parse_mode)?,
266 Err(e) => {
270 if (buf.inner().len() == 4 || buf.inner().len() == 1)
279 && message_type == RTM_GETROUTE
280 {
281 let mut msg =
282 RouteMessage { header: RouteHeader::default(), attributes: vec![] };
283 msg.header.address_family = buf.inner()[0].into();
284 msg
285 } else {
286 return Err(RouteNetlinkMessageParseError::ParseBuffer(e));
287 }
288 }
289 };
290 match message_type {
291 RTM_NEWROUTE => RouteNetlinkMessage::NewRoute(msg),
292 RTM_GETROUTE => RouteNetlinkMessage::GetRoute(msg),
293 RTM_DELROUTE => RouteNetlinkMessage::DelRoute(msg),
294 _ => unreachable!(),
295 }
296 }
297
298 RTM_NEWPREFIX => {
300 let buf_inner = buf.inner();
301 let buffer = PrefixMessageBuffer::new(&buf_inner)
302 .map_err(RouteNetlinkMessageParseError::ParseBuffer)?;
303 RouteNetlinkMessage::NewPrefix(PrefixMessage::parse_with_param(
304 &buffer, parse_mode,
305 )?)
306 }
307 RTM_NEWRULE | RTM_GETRULE | RTM_DELRULE => {
308 let buf_inner = buf.inner();
309 let buffer = RuleMessageBuffer::new(&buf_inner)
310 .map_err(RouteNetlinkMessageParseError::ParseBuffer)?;
311 let msg = RuleMessage::parse_with_param(&buffer, parse_mode)?;
312 match message_type {
313 RTM_NEWRULE => RouteNetlinkMessage::NewRule(msg),
314 RTM_DELRULE => RouteNetlinkMessage::DelRule(msg),
315 RTM_GETRULE => RouteNetlinkMessage::GetRule(msg),
316 _ => unreachable!(),
317 }
318 }
319 RTM_NEWQDISC | RTM_DELQDISC | RTM_GETQDISC | RTM_NEWTCLASS | RTM_DELTCLASS
321 | RTM_GETTCLASS | RTM_NEWTFILTER | RTM_DELTFILTER | RTM_GETTFILTER | RTM_NEWCHAIN
322 | RTM_DELCHAIN | RTM_GETCHAIN => {
323 let buf_inner = buf.inner();
324 let buffer = TcMessageBuffer::new(&buf_inner)
325 .map_err(RouteNetlinkMessageParseError::ParseBuffer)?;
326 let msg = TcMessage::parse_with_param(&buffer, parse_mode)?;
327 match message_type {
328 RTM_NEWQDISC => RouteNetlinkMessage::NewQueueDiscipline(msg),
329 RTM_DELQDISC => RouteNetlinkMessage::DelQueueDiscipline(msg),
330 RTM_GETQDISC => RouteNetlinkMessage::GetQueueDiscipline(msg),
331 RTM_NEWTCLASS => RouteNetlinkMessage::NewTrafficClass(msg),
332 RTM_DELTCLASS => RouteNetlinkMessage::DelTrafficClass(msg),
333 RTM_GETTCLASS => RouteNetlinkMessage::GetTrafficClass(msg),
334 RTM_NEWTFILTER => RouteNetlinkMessage::NewTrafficFilter(msg),
335 RTM_DELTFILTER => RouteNetlinkMessage::DelTrafficFilter(msg),
336 RTM_GETTFILTER => RouteNetlinkMessage::GetTrafficFilter(msg),
337 RTM_NEWCHAIN => RouteNetlinkMessage::NewTrafficChain(msg),
338 RTM_DELCHAIN => RouteNetlinkMessage::DelTrafficChain(msg),
339 RTM_GETCHAIN => RouteNetlinkMessage::GetTrafficChain(msg),
340 _ => unreachable!(),
341 }
342 }
343
344 RTM_NEWNSID | RTM_GETNSID | RTM_DELNSID => {
346 let buf_inner = buf.inner();
347 let buffer = NsidMessageBuffer::new(&buf_inner)
348 .map_err(RouteNetlinkMessageParseError::ParseBuffer)?;
349 let msg = NsidMessage::parse_with_param(&buffer, parse_mode)?;
350 match message_type {
351 RTM_NEWNSID => RouteNetlinkMessage::NewNsId(msg),
352 RTM_DELNSID => RouteNetlinkMessage::DelNsId(msg),
353 RTM_GETNSID => RouteNetlinkMessage::GetNsId(msg),
354 _ => unreachable!(),
355 }
356 }
357
358 _ => return Err(RouteNetlinkMessageParseError::UnknownMessageType(message_type)),
359 };
360 Ok(message)
361 }
362}
363
364#[derive(Debug, PartialEq, Eq, Clone)]
365pub enum RouteNetlinkMessage {
366 NewLink(LinkMessage),
367 DelLink(LinkMessage),
368 GetLink(LinkMessage),
369 SetLink(LinkMessage),
370 NewLinkProp(LinkMessage),
371 DelLinkProp(LinkMessage),
372 NewAddress(AddressMessage),
373 DelAddress(AddressMessage),
374 GetAddress(AddressMessage),
375 NewNeighbour(NeighbourMessage),
376 GetNeighbour(NeighbourMessage),
377 DelNeighbour(NeighbourMessage),
378 NewNeighbourTable(NeighbourTableMessage),
379 GetNeighbourTable(NeighbourTableMessage),
380 SetNeighbourTable(NeighbourTableMessage),
381 NewNeighbourDiscoveryUserOption(NeighbourDiscoveryUserOptionMessage),
382 NewRoute(RouteMessage),
383 DelRoute(RouteMessage),
384 GetRoute(RouteMessage),
385 NewPrefix(PrefixMessage),
386 NewQueueDiscipline(TcMessage),
387 DelQueueDiscipline(TcMessage),
388 GetQueueDiscipline(TcMessage),
389 NewTrafficClass(TcMessage),
390 DelTrafficClass(TcMessage),
391 GetTrafficClass(TcMessage),
392 NewTrafficFilter(TcMessage),
393 DelTrafficFilter(TcMessage),
394 GetTrafficFilter(TcMessage),
395 NewTrafficChain(TcMessage),
396 DelTrafficChain(TcMessage),
397 GetTrafficChain(TcMessage),
398 NewNsId(NsidMessage),
399 DelNsId(NsidMessage),
400 GetNsId(NsidMessage),
401 NewRule(RuleMessage),
402 DelRule(RuleMessage),
403 GetRule(RuleMessage),
404}
405
406impl RouteNetlinkMessage {
407 pub fn is_new_link(&self) -> bool {
408 matches!(self, RouteNetlinkMessage::NewLink(_))
409 }
410
411 pub fn is_del_link(&self) -> bool {
412 matches!(self, RouteNetlinkMessage::DelLink(_))
413 }
414
415 pub fn is_get_link(&self) -> bool {
416 matches!(self, RouteNetlinkMessage::GetLink(_))
417 }
418
419 pub fn is_set_link(&self) -> bool {
420 matches!(self, RouteNetlinkMessage::SetLink(_))
421 }
422
423 pub fn is_new_address(&self) -> bool {
424 matches!(self, RouteNetlinkMessage::NewAddress(_))
425 }
426
427 pub fn is_del_address(&self) -> bool {
428 matches!(self, RouteNetlinkMessage::DelAddress(_))
429 }
430
431 pub fn is_get_address(&self) -> bool {
432 matches!(self, RouteNetlinkMessage::GetAddress(_))
433 }
434
435 pub fn is_get_neighbour(&self) -> bool {
436 matches!(self, RouteNetlinkMessage::GetNeighbour(_))
437 }
438
439 pub fn is_new_route(&self) -> bool {
440 matches!(self, RouteNetlinkMessage::NewRoute(_))
441 }
442
443 pub fn is_new_neighbour(&self) -> bool {
444 matches!(self, RouteNetlinkMessage::NewNeighbour(_))
445 }
446
447 pub fn is_get_route(&self) -> bool {
448 matches!(self, RouteNetlinkMessage::GetRoute(_))
449 }
450
451 pub fn is_del_neighbour(&self) -> bool {
452 matches!(self, RouteNetlinkMessage::DelNeighbour(_))
453 }
454
455 pub fn is_new_neighbour_table(&self) -> bool {
456 matches!(self, RouteNetlinkMessage::NewNeighbourTable(_))
457 }
458
459 pub fn is_get_neighbour_table(&self) -> bool {
460 matches!(self, RouteNetlinkMessage::GetNeighbourTable(_))
461 }
462
463 pub fn is_set_neighbour_table(&self) -> bool {
464 matches!(self, RouteNetlinkMessage::SetNeighbourTable(_))
465 }
466
467 pub fn is_del_route(&self) -> bool {
468 matches!(self, RouteNetlinkMessage::DelRoute(_))
469 }
470
471 pub fn is_new_qdisc(&self) -> bool {
472 matches!(self, RouteNetlinkMessage::NewQueueDiscipline(_))
473 }
474
475 pub fn is_del_qdisc(&self) -> bool {
476 matches!(self, RouteNetlinkMessage::DelQueueDiscipline(_))
477 }
478
479 pub fn is_get_qdisc(&self) -> bool {
480 matches!(self, RouteNetlinkMessage::GetQueueDiscipline(_))
481 }
482
483 pub fn is_new_class(&self) -> bool {
484 matches!(self, RouteNetlinkMessage::NewTrafficClass(_))
485 }
486
487 pub fn is_del_class(&self) -> bool {
488 matches!(self, RouteNetlinkMessage::DelTrafficClass(_))
489 }
490
491 pub fn is_get_class(&self) -> bool {
492 matches!(self, RouteNetlinkMessage::GetTrafficClass(_))
493 }
494
495 pub fn is_new_filter(&self) -> bool {
496 matches!(self, RouteNetlinkMessage::NewTrafficFilter(_))
497 }
498
499 pub fn is_del_filter(&self) -> bool {
500 matches!(self, RouteNetlinkMessage::DelTrafficFilter(_))
501 }
502
503 pub fn is_get_filter(&self) -> bool {
504 matches!(self, RouteNetlinkMessage::GetTrafficFilter(_))
505 }
506
507 pub fn is_new_chain(&self) -> bool {
508 matches!(self, RouteNetlinkMessage::NewTrafficChain(_))
509 }
510
511 pub fn is_del_chain(&self) -> bool {
512 matches!(self, RouteNetlinkMessage::DelTrafficChain(_))
513 }
514
515 pub fn is_get_chain(&self) -> bool {
516 matches!(self, RouteNetlinkMessage::GetTrafficChain(_))
517 }
518
519 pub fn is_new_nsid(&self) -> bool {
520 matches!(self, RouteNetlinkMessage::NewNsId(_))
521 }
522
523 pub fn is_get_nsid(&self) -> bool {
524 matches!(self, RouteNetlinkMessage::GetNsId(_))
525 }
526
527 pub fn is_del_nsid(&self) -> bool {
528 matches!(self, RouteNetlinkMessage::DelNsId(_))
529 }
530
531 pub fn is_get_rule(&self) -> bool {
532 matches!(self, RouteNetlinkMessage::GetRule(_))
533 }
534
535 pub fn is_new_rule(&self) -> bool {
536 matches!(self, RouteNetlinkMessage::NewRule(_))
537 }
538
539 pub fn is_del_rule(&self) -> bool {
540 matches!(self, RouteNetlinkMessage::DelRule(_))
541 }
542
543 pub fn message_type(&self) -> u16 {
544 use self::RouteNetlinkMessage::*;
545
546 match self {
547 NewLink(_) => RTM_NEWLINK,
548 DelLink(_) => RTM_DELLINK,
549 GetLink(_) => RTM_GETLINK,
550 SetLink(_) => RTM_SETLINK,
551 NewLinkProp(_) => RTM_NEWLINKPROP,
552 DelLinkProp(_) => RTM_DELLINKPROP,
553 NewAddress(_) => RTM_NEWADDR,
554 DelAddress(_) => RTM_DELADDR,
555 GetAddress(_) => RTM_GETADDR,
556 GetNeighbour(_) => RTM_GETNEIGH,
557 NewNeighbour(_) => RTM_NEWNEIGH,
558 DelNeighbour(_) => RTM_DELNEIGH,
559 GetNeighbourTable(_) => RTM_GETNEIGHTBL,
560 NewNeighbourTable(_) => RTM_NEWNEIGHTBL,
561 SetNeighbourTable(_) => RTM_SETNEIGHTBL,
562 NewNeighbourDiscoveryUserOption(_) => RTM_NEWNDUSEROPT,
563 NewRoute(_) => RTM_NEWROUTE,
564 DelRoute(_) => RTM_DELROUTE,
565 GetRoute(_) => RTM_GETROUTE,
566 NewPrefix(_) => RTM_NEWPREFIX,
567 NewQueueDiscipline(_) => RTM_NEWQDISC,
568 DelQueueDiscipline(_) => RTM_DELQDISC,
569 GetQueueDiscipline(_) => RTM_GETQDISC,
570 NewTrafficClass(_) => RTM_NEWTCLASS,
571 DelTrafficClass(_) => RTM_DELTCLASS,
572 GetTrafficClass(_) => RTM_GETTCLASS,
573 NewTrafficFilter(_) => RTM_NEWTFILTER,
574 DelTrafficFilter(_) => RTM_DELTFILTER,
575 GetTrafficFilter(_) => RTM_GETTFILTER,
576 NewTrafficChain(_) => RTM_NEWCHAIN,
577 DelTrafficChain(_) => RTM_DELCHAIN,
578 GetTrafficChain(_) => RTM_GETCHAIN,
579 GetNsId(_) => RTM_GETNSID,
580 NewNsId(_) => RTM_NEWNSID,
581 DelNsId(_) => RTM_DELNSID,
582 GetRule(_) => RTM_GETRULE,
583 NewRule(_) => RTM_NEWRULE,
584 DelRule(_) => RTM_DELRULE,
585 }
586 }
587}
588
589impl Emitable for RouteNetlinkMessage {
590 #[rustfmt::skip]
591 fn buffer_len(&self) -> usize {
592 use self::RouteNetlinkMessage::*;
593 match self {
594 | NewLink(msg)
595 | DelLink(msg)
596 | GetLink(msg)
597 | SetLink(msg)
598 | NewLinkProp(msg)
599 | DelLinkProp(msg)
600 => msg.buffer_len(),
601
602 | NewAddress(msg)
603 | DelAddress(msg)
604 | GetAddress(msg)
605 => msg.buffer_len(),
606
607 | NewNeighbour(msg)
608 | GetNeighbour(msg)
609 | DelNeighbour(msg)
610 => msg.buffer_len(),
611
612 | NewNeighbourTable(msg)
613 | GetNeighbourTable(msg)
614 | SetNeighbourTable(msg)
615 => msg.buffer_len(),
616
617 | NewNeighbourDiscoveryUserOption(msg) => msg.buffer_len(),
618
619 | NewRoute(msg)
620 | DelRoute(msg)
621 | GetRoute(msg)
622 => msg.buffer_len(),
623
624 NewPrefix(msg) => msg.buffer_len(),
625
626 | NewQueueDiscipline(msg)
627 | DelQueueDiscipline(msg)
628 | GetQueueDiscipline(msg)
629 | NewTrafficClass(msg)
630 | DelTrafficClass(msg)
631 | GetTrafficClass(msg)
632 | NewTrafficFilter(msg)
633 | DelTrafficFilter(msg)
634 | GetTrafficFilter(msg)
635 | NewTrafficChain(msg)
636 | DelTrafficChain(msg)
637 | GetTrafficChain(msg)
638 => msg.buffer_len(),
639
640 | NewNsId(msg)
641 | DelNsId(msg)
642 | GetNsId(msg)
643 => msg.buffer_len(),
644
645 | NewRule(msg)
646 | DelRule(msg)
647 | GetRule(msg)
648 => msg.buffer_len()
649 }
650 }
651
652 #[rustfmt::skip]
653 fn emit(&self, buffer: &mut [u8]) {
654 use self::RouteNetlinkMessage::*;
655 match self {
656 | NewLink(msg)
657 | DelLink(msg)
658 | GetLink(msg)
659 | SetLink(msg)
660 | NewLinkProp(msg)
661 | DelLinkProp(msg)
662 => msg.emit(buffer),
663
664 | NewAddress(msg)
665 | DelAddress(msg)
666 | GetAddress(msg)
667 => msg.emit(buffer),
668
669 | GetNeighbour(msg)
670 | NewNeighbour(msg)
671 | DelNeighbour(msg)
672 => msg.emit(buffer),
673
674 | GetNeighbourTable(msg)
675 | NewNeighbourTable(msg)
676 | SetNeighbourTable(msg)
677 => msg.emit(buffer),
678
679 | NewNeighbourDiscoveryUserOption(msg) => msg.emit(buffer),
680
681 | NewRoute(msg)
682 | DelRoute(msg)
683 | GetRoute(msg)
684 => msg.emit(buffer),
685
686 | NewPrefix(msg) => msg.emit(buffer),
687
688 | NewQueueDiscipline(msg)
689 | DelQueueDiscipline(msg)
690 | GetQueueDiscipline(msg)
691 | NewTrafficClass(msg)
692 | DelTrafficClass(msg)
693 | GetTrafficClass(msg)
694 | NewTrafficFilter(msg)
695 | DelTrafficFilter(msg)
696 | GetTrafficFilter(msg)
697 | NewTrafficChain(msg)
698 | DelTrafficChain(msg)
699 | GetTrafficChain(msg)
700 => msg.emit(buffer),
701
702 | NewNsId(msg)
703 | DelNsId(msg)
704 | GetNsId(msg)
705 => msg.emit(buffer),
706
707 | NewRule(msg)
708 | DelRule(msg)
709 | GetRule(msg)
710 => msg.emit(buffer)
711 }
712 }
713}
714
715impl NetlinkSerializable for RouteNetlinkMessage {
716 fn message_type(&self) -> u16 {
717 self.message_type()
718 }
719
720 fn buffer_len(&self) -> usize {
721 <Self as Emitable>::buffer_len(self)
722 }
723
724 fn serialize(&self, buffer: &mut [u8]) {
725 self.emit(buffer)
726 }
727}
728
729impl NetlinkDeserializable for RouteNetlinkMessage {
730 type DeserializeOptions = RouteNetlinkMessageParseMode;
731 type Error = RouteNetlinkMessageParseError;
732
733 fn deserialize(
734 header: &NetlinkHeader,
735 payload: &[u8],
736 options: RouteNetlinkMessageParseMode,
737 ) -> Result<Self, Self::Error> {
738 let buf = RouteNetlinkMessageBuffer::new(payload);
739 match RouteNetlinkMessage::parse_with_param(
740 &buf,
741 RouteNetlinkMessageParseConfig {
742 message_type: header.message_type,
743 parse_mode: options,
744 },
745 ) {
746 Err(e) => Err(e),
747 Ok(message) => Ok(message),
748 }
749 }
750}
751
752impl From<RouteNetlinkMessage> for NetlinkPayload<RouteNetlinkMessage> {
753 fn from(message: RouteNetlinkMessage) -> Self {
754 NetlinkPayload::InnerMessage(message)
755 }
756}