Skip to main content

netlink_packet_route/link/link_info/
veth.rs

1// SPDX-License-Identifier: MIT
2
3use anyhow::Context;
4use netlink_packet_utils::DecodeError;
5use netlink_packet_utils::nla::{DefaultNla, Nla, NlaBuffer};
6use netlink_packet_utils::traits::{Emitable, Parseable, ParseableParametrized};
7
8use crate::RouteNetlinkMessageParseMode;
9
10use super::super::{LinkMessage, LinkMessageBuffer};
11
12const VETH_INFO_PEER: u16 = 1;
13
14#[derive(Debug, PartialEq, Eq, Clone)]
15#[non_exhaustive]
16// This data is not for querying/dumping as in kernel 6.5.8,
17// because the `struct rtnl_link_ops veth_link_ops` does not have `fill_info`.
18// Only for create veth
19pub enum InfoVeth {
20    Peer(LinkMessage),
21    Other(DefaultNla),
22}
23
24impl Nla for InfoVeth {
25    fn value_len(&self) -> usize {
26        use self::InfoVeth::*;
27        match *self {
28            Peer(ref message) => message.buffer_len(),
29            Other(ref attr) => attr.value_len(),
30        }
31    }
32
33    fn emit_value(&self, buffer: &mut [u8]) {
34        use self::InfoVeth::*;
35        match *self {
36            Peer(ref message) => message.emit(buffer),
37            Other(ref attr) => attr.emit_value(buffer),
38        }
39    }
40
41    fn kind(&self) -> u16 {
42        use self::InfoVeth::*;
43        match *self {
44            Peer(_) => VETH_INFO_PEER,
45            Other(ref attr) => attr.kind(),
46        }
47    }
48}
49
50impl<'a, T: AsRef<[u8]> + ?Sized> Parseable<NlaBuffer<&'a T>> for InfoVeth {
51    type Error = DecodeError;
52    fn parse(buf: &NlaBuffer<&'a T>) -> Result<Self, DecodeError> {
53        use self::InfoVeth::*;
54        let payload = buf.value();
55        Ok(match buf.kind() {
56            VETH_INFO_PEER => {
57                let err = "failed to parse veth link info";
58                let buffer = LinkMessageBuffer::new(&payload).context(err)?;
59                Peer(
60                    LinkMessage::parse_with_param(&buffer, RouteNetlinkMessageParseMode::Relaxed)
61                        .context(err)?,
62                )
63            }
64            kind => Other(DefaultNla::parse(buf).context(format!("unknown NLA type {kind}"))?),
65        })
66    }
67}