netlink_packet_route/link/link_info/
xfrm.rs

1// SPDX-License-Identifier: MIT
2
3use anyhow::Context;
4use byteorder::{ByteOrder, NativeEndian};
5use netlink_packet_utils::nla::{DefaultNla, Nla, NlaBuffer};
6use netlink_packet_utils::parsers::parse_u32;
7use netlink_packet_utils::traits::Parseable;
8use netlink_packet_utils::DecodeError;
9
10const IFLA_XFRM_LINK: u16 = 1;
11const IFLA_XFRM_IF_ID: u16 = 2;
12
13#[derive(Debug, PartialEq, Eq, Clone)]
14#[non_exhaustive]
15pub enum InfoXfrm {
16    Link(u32),
17    IfId(u32),
18    Other(DefaultNla),
19}
20
21impl Nla for InfoXfrm {
22    fn value_len(&self) -> usize {
23        use self::InfoXfrm::*;
24        match self {
25            Link(_) => 4,
26            IfId(_) => 4,
27            Other(nla) => nla.value_len(),
28        }
29    }
30
31    fn emit_value(&self, buffer: &mut [u8]) {
32        use self::InfoXfrm::*;
33        match self {
34            Link(value) => NativeEndian::write_u32(buffer, *value),
35            IfId(value) => NativeEndian::write_u32(buffer, *value),
36            Other(nla) => nla.emit_value(buffer),
37        }
38    }
39
40    fn kind(&self) -> u16 {
41        use self::InfoXfrm::*;
42        match self {
43            Link(_) => IFLA_XFRM_LINK,
44            IfId(_) => IFLA_XFRM_IF_ID,
45            Other(nla) => nla.kind(),
46        }
47    }
48}
49
50impl<'a, T: AsRef<[u8]> + ?Sized> Parseable<NlaBuffer<&'a T>> for InfoXfrm {
51    type Error = DecodeError;
52    fn parse(buf: &NlaBuffer<&'a T>) -> Result<Self, DecodeError> {
53        use self::InfoXfrm::*;
54        let payload = buf.value();
55        Ok(match buf.kind() {
56            IFLA_XFRM_LINK => Link(parse_u32(payload).context("invalid IFLA_XFRM_LINK value")?),
57            IFLA_XFRM_IF_ID => IfId(parse_u32(payload).context("invalid IFLA_XFRM_IF_ID value")?),
58            kind => Other(
59                DefaultNla::parse(buf)
60                    .context(format!("unknown NLA type {kind} for IFLA_INFO_DATA(xfrm)"))?,
61            ),
62        })
63    }
64}