netlink_packet_route/nsid/
attribute.rs

1// SPDX-License-Identifier: MIT
2
3use netlink_packet_core::{
4    emit_i32, emit_u32, parse_i32, parse_u32, DecodeError, DefaultNla,
5    ErrorContext, Nla, NlaBuffer, Parseable,
6};
7
8const NETNSA_NSID: u16 = 1;
9const NETNSA_PID: u16 = 2;
10const NETNSA_FD: u16 = 3;
11const NETNSA_TARGET_NSID: u16 = 4;
12const NETNSA_CURRENT_NSID: u16 = 5;
13
14#[derive(Debug, PartialEq, Eq, Clone)]
15#[non_exhaustive]
16pub enum NsidAttribute {
17    /// -1 means not assigned
18    Id(i32),
19    Pid(u32),
20    Fd(u32),
21    TargetNsid(i32),
22    CurrentNsid(i32),
23    Other(DefaultNla),
24}
25
26impl Nla for NsidAttribute {
27    fn value_len(&self) -> usize {
28        match self {
29            Self::Id(_)
30            | Self::Pid(_)
31            | Self::Fd(_)
32            | Self::TargetNsid(_)
33            | Self::CurrentNsid(_) => 4,
34            Self::Other(attr) => attr.value_len(),
35        }
36    }
37
38    fn emit_value(&self, buffer: &mut [u8]) {
39        match self {
40            Self::Fd(v) | Self::Pid(v) => emit_u32(buffer, *v).unwrap(),
41            Self::Id(v) | Self::TargetNsid(v) | Self::CurrentNsid(v) => {
42                emit_i32(buffer, *v).unwrap()
43            }
44            Self::Other(attr) => attr.emit_value(buffer),
45        }
46    }
47
48    fn kind(&self) -> u16 {
49        match self {
50            Self::Id(_) => NETNSA_NSID,
51            Self::Pid(_) => NETNSA_PID,
52            Self::Fd(_) => NETNSA_FD,
53            Self::TargetNsid(_) => NETNSA_TARGET_NSID,
54            Self::CurrentNsid(_) => NETNSA_CURRENT_NSID,
55            Self::Other(attr) => attr.kind(),
56        }
57    }
58}
59
60impl<'a, T: AsRef<[u8]> + ?Sized> Parseable<NlaBuffer<&'a T>>
61    for NsidAttribute
62{
63    fn parse(buf: &NlaBuffer<&'a T>) -> Result<Self, DecodeError> {
64        let payload = buf.value();
65        Ok(match buf.kind() {
66            NETNSA_NSID => {
67                Self::Id(parse_i32(payload).context("invalid NETNSA_NSID")?)
68            }
69            NETNSA_PID => {
70                Self::Pid(parse_u32(payload).context("invalid NETNSA_PID")?)
71            }
72            NETNSA_FD => {
73                Self::Fd(parse_u32(payload).context("invalid NETNSA_FD")?)
74            }
75            NETNSA_TARGET_NSID => Self::TargetNsid(
76                parse_i32(payload).context("invalid NETNSA_TARGET_NSID")?,
77            ),
78            NETNSA_CURRENT_NSID => Self::CurrentNsid(
79                parse_i32(payload).context("invalid NETNSA_CURRENT_NSID")?,
80            ),
81            kind => Self::Other(
82                DefaultNla::parse(buf)
83                    .context(format!("unknown NLA type {kind}"))?,
84            ),
85        })
86    }
87}