Skip to content
This repository has been archived by the owner on Oct 26, 2022. It is now read-only.

Commit

Permalink
netlink-packet-route/src/rtnl/link: Implement PropList nla
Browse files Browse the repository at this point in the history
  • Loading branch information
inemajo authored and cathay4t committed Aug 13, 2021
1 parent 26a8e2a commit b4b3c46
Show file tree
Hide file tree
Showing 2 changed files with 78 additions and 6 deletions.
24 changes: 18 additions & 6 deletions netlink-packet-route/src/rtnl/link/nlas/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ pub use self::af_spec_inet::*;
mod link_infos;
pub use self::link_infos::*;

mod prop_list;
pub use self::prop_list::*;

mod map;
pub use self::map::*;

Expand All @@ -32,7 +35,7 @@ use byteorder::{ByteOrder, NativeEndian};

use crate::{
constants::*,
nlas::{self, DefaultNla, NlaBuffer, NlasIterator},
nlas::{self, DefaultNla, NlaBuffer, NlasIterator, NLA_F_NESTED},
parsers::{parse_i32, parse_string, parse_u32, parse_u8},
traits::{Emitable, Parseable, ParseableParametrized},
DecodeError,
Expand Down Expand Up @@ -68,7 +71,7 @@ pub enum Nla {
/// [1]: https://lwn.net/ml/netdev/20190719110029.29466-1-jiri@resnulli.us/
/// [2]: https://lwn.net/ml/netdev/20190930094820.11281-1-jiri@resnulli.us/
/// [defining message]: https://lwn.net/ml/netdev/20190913145012.GB2276@nanopsycho.orion/
PropList(Vec<u8>),
PropList(Vec<Prop>),
/// `protodown` is a mechanism that allows protocols to hold an interface down.
/// This field is used to specify the reason why it is held down.
/// For additional context see the related linux kernel threads<sup>[1][1],[2][2]</sup>.
Expand Down Expand Up @@ -174,7 +177,6 @@ impl nlas::Nla for Nla {
| AfSpecUnknown(ref bytes)
| AfSpecBridge(ref bytes)
| Map(ref bytes)
| PropList(ref bytes)
| ProtoDownReason(ref bytes)
=> bytes.len(),

Expand Down Expand Up @@ -217,6 +219,7 @@ impl nlas::Nla for Nla {
Stats(_) => LINK_STATS_LEN,
Stats64(_) => LINK_STATS64_LEN,
Info(ref nlas) => nlas.as_slice().buffer_len(),
PropList(ref nlas) => nlas.as_slice().buffer_len(),
AfSpecInet(ref nlas) => nlas.as_slice().buffer_len(),
// AfSpecBridge(ref nlas) => nlas.as_slice().buffer_len(),
Other(ref attr) => attr.value_len(),
Expand Down Expand Up @@ -257,7 +260,6 @@ impl nlas::Nla for Nla {
| Stats(ref bytes)
| Stats64(ref bytes)
| Map(ref bytes)
| PropList(ref bytes)
| ProtoDownReason(ref bytes)
=> buffer.copy_from_slice(bytes.as_slice()),

Expand Down Expand Up @@ -303,6 +305,7 @@ impl nlas::Nla for Nla {

OperState(state) => buffer[0] = state.into(),
Info(ref nlas) => nlas.as_slice().emit(buffer),
PropList(ref nlas) => nlas.as_slice().emit(buffer),
AfSpecInet(ref nlas) => nlas.as_slice().emit(buffer),
// AfSpecBridge(ref nlas) => nlas.as_slice().emit(buffer),
// default nlas
Expand Down Expand Up @@ -334,7 +337,7 @@ impl nlas::Nla for Nla {
CarrierUpCount(_) => IFLA_CARRIER_UP_COUNT,
CarrierDownCount(_) => IFLA_CARRIER_DOWN_COUNT,
NewIfIndex(_) => IFLA_NEW_IFINDEX,
PropList(_) => IFLA_PROP_LIST,
PropList(_) => IFLA_PROP_LIST | NLA_F_NESTED,
ProtoDownReason(_) => IFLA_PROTO_DOWN_REASON,
// Mac address
Address(_) => IFLA_ADDRESS,
Expand Down Expand Up @@ -409,7 +412,16 @@ impl<'a, T: AsRef<[u8]> + ?Sized> ParseableParametrized<NlaBuffer<&'a T>, u16> f
IFLA_CARRIER_UP_COUNT => CarrierUpCount(payload.to_vec()),
IFLA_CARRIER_DOWN_COUNT => CarrierDownCount(payload.to_vec()),
IFLA_NEW_IFINDEX => NewIfIndex(payload.to_vec()),
IFLA_PROP_LIST => PropList(payload.to_vec()),
IFLA_PROP_LIST => {
let error_msg = "invalid IFLA_PROP_LIST value";
let mut nlas = vec![];
for nla in NlasIterator::new(payload) {
let nla = &nla.context(error_msg)?;
let parsed = Prop::parse(nla).context(error_msg)?;
nlas.push(parsed);
}
PropList(nlas)
}
IFLA_PROTO_DOWN_REASON => ProtoDownReason(payload.to_vec()),
// HW address (we parse them as Vec for now, because for IP over GRE, the HW address is
// an IP instead of a MAC for example
Expand Down
60 changes: 60 additions & 0 deletions netlink-packet-route/src/rtnl/link/nlas/prop_list.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
use crate::{
constants::*,
nlas::{DefaultNla, Nla, NlaBuffer},
parsers::parse_string,
traits::Parseable,
DecodeError,
};

use anyhow::Context;

#[derive(Debug, PartialEq, Eq, Clone)]
pub enum Prop {
AltIfName(String),
Other(DefaultNla),
}

impl Nla for Prop {
#[rustfmt::skip]
fn value_len(&self) -> usize {
use self::Prop::*;
match self {
AltIfName(ref string) => string.as_bytes().len() + 1,
Other(nla) => nla.value_len()
}
}

#[rustfmt::skip]
fn emit_value(&self, buffer: &mut [u8]) {
use self::Prop::*;
match self {
AltIfName(ref string) => {
buffer[..string.len()].copy_from_slice(string.as_bytes());
buffer[string.len()] = 0;
},
Other(nla) => nla.emit_value(buffer)
}
}

fn kind(&self) -> u16 {
use self::Prop::*;
match self {
AltIfName(_) => IFLA_ALT_IFNAME,
Other(nla) => nla.kind(),
}
}
}

impl<'a, T: AsRef<[u8]> + ?Sized> Parseable<NlaBuffer<&'a T>> for Prop {
fn parse(buf: &NlaBuffer<&'a T>) -> Result<Self, DecodeError> {
let payload = buf.value();
Ok(match buf.kind() {
IFLA_ALT_IFNAME => {
Prop::AltIfName(parse_string(payload).context("invalid IFLA_ALT_IFNAME value")?)
}
kind => {
Prop::Other(DefaultNla::parse(buf).context(format!("Unknown NLA type {}", kind))?)
}
})
}
}

0 comments on commit b4b3c46

Please sign in to comment.