netlink_packet_route/link/
prop_list.rs

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