netlink_packet_route/rtnl/link/nlas/inet/
mod.rs

1// SPDX-License-Identifier: MIT
2
3use anyhow::Context;
4
5use crate::constants::{IFLA_INET_CONF, IFLA_INET_UNSPEC};
6
7use netlink_packet_utils::{
8    nla::{DefaultNla, Nla, NlaBuffer},
9    traits::Parseable,
10    DecodeError,
11};
12
13mod dev_conf;
14pub use self::dev_conf::*;
15
16#[derive(Clone, Eq, PartialEq, Debug)]
17#[non_exhaustive]
18pub enum Inet {
19    DevConf(Vec<u8>),
20    Unspec(Vec<u8>),
21    Other(DefaultNla),
22}
23
24impl Nla for Inet {
25    fn value_len(&self) -> usize {
26        use self::Inet::*;
27        match *self {
28            Unspec(ref bytes) => bytes.len(),
29            DevConf(_) => DEV_CONF_LEN,
30            Other(ref nla) => nla.value_len(),
31        }
32    }
33
34    fn emit_value(&self, buffer: &mut [u8]) {
35        use self::Inet::*;
36        match *self {
37            Unspec(ref bytes) => {
38                buffer[..bytes.len()].copy_from_slice(bytes.as_slice())
39            }
40            DevConf(ref dev_conf) => {
41                buffer[..dev_conf.len()].copy_from_slice(dev_conf.as_slice())
42            }
43            Other(ref nla) => nla.emit_value(buffer),
44        }
45    }
46
47    fn kind(&self) -> u16 {
48        use self::Inet::*;
49        match *self {
50            Unspec(_) => IFLA_INET_UNSPEC,
51            DevConf(_) => IFLA_INET_CONF,
52            Other(ref nla) => nla.kind(),
53        }
54    }
55}
56
57impl<'a, T: AsRef<[u8]> + ?Sized> Parseable<NlaBuffer<&'a T>> for Inet {
58    fn parse(buf: &NlaBuffer<&'a T>) -> Result<Self, DecodeError> {
59        use self::Inet::*;
60
61        let payload = buf.value();
62        Ok(match buf.kind() {
63            IFLA_INET_UNSPEC => Unspec(payload.to_vec()),
64            IFLA_INET_CONF => DevConf(payload.to_vec()),
65            kind => Other(
66                DefaultNla::parse(buf)
67                    .context(format!("unknown NLA type {kind}"))?,
68            ),
69        })
70    }
71}