netlink_packet_route/rtnl/tc/nlas/
options.rs

1// SPDX-License-Identifier: MIT
2use anyhow::Context;
3
4use crate::{
5    nlas::{self, DefaultNla, NlaBuffer},
6    tc::{ingress, u32},
7    traits::{Parseable, ParseableParametrized},
8    DecodeError,
9};
10
11#[derive(Debug, PartialEq, Eq, Clone)]
12pub enum TcOpt {
13    // Qdisc specific options
14    Ingress,
15    // Filter specific options
16    U32(u32::Nla),
17    // Other options
18    Other(DefaultNla),
19}
20
21impl nlas::Nla for TcOpt {
22    fn value_len(&self) -> usize {
23        match self {
24            Self::Ingress => 0,
25            Self::U32(u) => u.value_len(),
26            Self::Other(o) => o.value_len(),
27        }
28    }
29
30    fn emit_value(&self, buffer: &mut [u8]) {
31        match self {
32            Self::Ingress => unreachable!(),
33            Self::U32(u) => u.emit_value(buffer),
34            Self::Other(o) => o.emit_value(buffer),
35        }
36    }
37
38    fn kind(&self) -> u16 {
39        match self {
40            Self::Ingress => unreachable!(),
41            Self::U32(u) => u.kind(),
42            Self::Other(o) => o.kind(),
43        }
44    }
45}
46
47impl<'a, T, S> ParseableParametrized<NlaBuffer<&'a T>, S> for TcOpt
48where
49    T: AsRef<[u8]> + ?Sized,
50    S: AsRef<str>,
51{
52    fn parse_with_param(buf: &NlaBuffer<&'a T>, kind: S) -> Result<Self, DecodeError> {
53        Ok(match kind.as_ref() {
54            ingress::KIND => TcOpt::Ingress,
55            u32::KIND => Self::U32(u32::Nla::parse(buf).context("failed to parse u32 nlas")?),
56            _ => Self::Other(DefaultNla::parse(buf)?),
57        })
58    }
59}