netlink_packet_route/rtnl/tc/nlas/
options.rs

1// SPDX-License-Identifier: MIT
2
3use 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    // Qdisc specific options
16    Ingress,
17    // Filter specific options
18    U32(u32::Nla),
19    // matchall options
20    Matchall(matchall::Nla),
21    // Other options
22    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}