netlink_packet_generic/ctrl/
mod.rsuse self::nlas::*;
use crate::constants::*;
use crate::traits::*;
use crate::GenlHeader;
use anyhow::Context;
use netlink_packet_utils::nla::NlasIterator;
use netlink_packet_utils::traits::*;
use netlink_packet_utils::DecodeError;
use std::convert::{TryFrom, TryInto};
pub mod nlas;
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum GenlCtrlCmd {
NewFamily,
DelFamily,
GetFamily,
NewOps,
DelOps,
GetOps,
NewMcastGrp,
DelMcastGrp,
GetMcastGrp,
GetPolicy,
}
impl From<GenlCtrlCmd> for u8 {
fn from(cmd: GenlCtrlCmd) -> u8 {
use GenlCtrlCmd::*;
match cmd {
NewFamily => CTRL_CMD_NEWFAMILY,
DelFamily => CTRL_CMD_DELFAMILY,
GetFamily => CTRL_CMD_GETFAMILY,
NewOps => CTRL_CMD_NEWOPS,
DelOps => CTRL_CMD_DELOPS,
GetOps => CTRL_CMD_GETOPS,
NewMcastGrp => CTRL_CMD_NEWMCAST_GRP,
DelMcastGrp => CTRL_CMD_DELMCAST_GRP,
GetMcastGrp => CTRL_CMD_GETMCAST_GRP,
GetPolicy => CTRL_CMD_GETPOLICY,
}
}
}
impl TryFrom<u8> for GenlCtrlCmd {
type Error = DecodeError;
fn try_from(value: u8) -> Result<Self, Self::Error> {
use GenlCtrlCmd::*;
Ok(match value {
CTRL_CMD_NEWFAMILY => NewFamily,
CTRL_CMD_DELFAMILY => DelFamily,
CTRL_CMD_GETFAMILY => GetFamily,
CTRL_CMD_NEWOPS => NewOps,
CTRL_CMD_DELOPS => DelOps,
CTRL_CMD_GETOPS => GetOps,
CTRL_CMD_NEWMCAST_GRP => NewMcastGrp,
CTRL_CMD_DELMCAST_GRP => DelMcastGrp,
CTRL_CMD_GETMCAST_GRP => GetMcastGrp,
CTRL_CMD_GETPOLICY => GetPolicy,
cmd => return Err(DecodeError::from(format!("Unknown control command: {cmd}"))),
})
}
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct GenlCtrl {
pub cmd: GenlCtrlCmd,
pub nlas: Vec<GenlCtrlAttrs>,
}
impl GenlFamily for GenlCtrl {
fn family_name() -> &'static str {
"nlctrl"
}
fn family_id(&self) -> u16 {
GENL_ID_CTRL
}
fn command(&self) -> u8 {
self.cmd.into()
}
fn version(&self) -> u8 {
2
}
}
impl Emitable for GenlCtrl {
fn emit(&self, buffer: &mut [u8]) {
self.nlas.as_slice().emit(buffer)
}
fn buffer_len(&self) -> usize {
self.nlas.as_slice().buffer_len()
}
}
impl ParseableParametrized<[u8], GenlHeader> for GenlCtrl {
type Error = DecodeError;
fn parse_with_param(buf: &[u8], header: GenlHeader) -> Result<Self, DecodeError> {
Ok(Self { cmd: header.cmd.try_into()?, nlas: parse_ctrlnlas(buf)? })
}
}
fn parse_ctrlnlas(buf: &[u8]) -> Result<Vec<GenlCtrlAttrs>, DecodeError> {
let nlas = NlasIterator::new(buf)
.map(|nla| {
nla.map_err(|err| DecodeError::Nla(err)).and_then(|nla| GenlCtrlAttrs::parse(&nla))
})
.collect::<Result<Vec<_>, _>>()
.context("failed to parse control message attributes")?;
Ok(nlas)
}