netlink_packet_route/rtnl/tc/nlas/
options.rs1use anyhow::Context;
4use netlink_packet_utils::{
5 nla::{self, DefaultNla, NlaBuffer},
6 traits::{Parseable, ParseableParametrized},
7 DecodeError,
8};
9
10use crate::tc::{ingress, matchall, u32};
11
12#[derive(Debug, PartialEq, Eq, Clone)]
13#[non_exhaustive]
14pub enum TcOpt {
15 Ingress,
17 U32(u32::Nla),
19 Matchall(matchall::Nla),
21 Other(DefaultNla),
23}
24
25impl nla::Nla for TcOpt {
26 fn value_len(&self) -> usize {
27 match self {
28 Self::Ingress => 0,
29 Self::U32(u) => u.value_len(),
30 Self::Matchall(m) => m.value_len(),
31 Self::Other(o) => o.value_len(),
32 }
33 }
34
35 fn emit_value(&self, buffer: &mut [u8]) {
36 match self {
37 Self::Ingress => unreachable!(),
38 Self::U32(u) => u.emit_value(buffer),
39 Self::Matchall(m) => m.emit_value(buffer),
40 Self::Other(o) => o.emit_value(buffer),
41 }
42 }
43
44 fn kind(&self) -> u16 {
45 match self {
46 Self::Ingress => unreachable!(),
47 Self::U32(u) => u.kind(),
48 Self::Matchall(m) => m.kind(),
49 Self::Other(o) => o.kind(),
50 }
51 }
52}
53
54impl<'a, T, S> ParseableParametrized<NlaBuffer<&'a T>, S> for TcOpt
55where
56 T: AsRef<[u8]> + ?Sized,
57 S: AsRef<str>,
58{
59 fn parse_with_param(
60 buf: &NlaBuffer<&'a T>,
61 kind: S,
62 ) -> Result<Self, DecodeError> {
63 Ok(match kind.as_ref() {
64 ingress::KIND => TcOpt::Ingress,
65 u32::KIND => Self::U32(
66 u32::Nla::parse(buf).context("failed to parse u32 nlas")?,
67 ),
68 matchall::KIND => Self::Matchall(
69 matchall::Nla::parse(buf)
70 .context("failed to parse matchall nlas")?,
71 ),
72 _ => Self::Other(DefaultNla::parse(buf)?),
73 })
74 }
75}