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