netlink_packet_route/tc/filters/
matchall.rs1use netlink_packet_core::ErrorContext;
4use netlink_packet_core::{
8 emit_u32, parse_u32, DecodeError, DefaultNla, Emitable, Nla, NlaBuffer,
9 NlasIterator, Parseable,
10};
11
12use crate::tc::{TcAction, TcHandle};
13
14const TCA_MATCHALL_CLASSID: u16 = 1;
15const TCA_MATCHALL_ACT: u16 = 2;
16const TCA_MATCHALL_FLAGS: u16 = 3;
17const TCA_MATCHALL_PCNT: u16 = 4;
18
19#[derive(Debug, PartialEq, Eq, Clone)]
20#[non_exhaustive]
21pub struct TcFilterMatchAll {}
22impl TcFilterMatchAll {
23 pub const KIND: &'static str = "matchall";
24}
25
26#[derive(Debug, PartialEq, Eq, Clone)]
27#[non_exhaustive]
28pub enum TcFilterMatchAllOption {
29 ClassId(TcHandle),
30 Action(Vec<TcAction>),
31 Pnct(Vec<u8>),
32 Flags(u32),
33 Other(DefaultNla),
34}
35
36impl Nla for TcFilterMatchAllOption {
37 fn value_len(&self) -> usize {
38 match self {
39 Self::Pnct(b) => b.len(),
40 Self::ClassId(_) => 4,
41 Self::Flags(_) => 4,
42 Self::Action(acts) => acts.as_slice().buffer_len(),
43 Self::Other(attr) => attr.value_len(),
44 }
45 }
46
47 fn emit_value(&self, buffer: &mut [u8]) {
48 match self {
49 Self::Pnct(b) => buffer.copy_from_slice(b.as_slice()),
50 Self::ClassId(i) => emit_u32(buffer, (*i).into()).unwrap(),
51 Self::Flags(i) => emit_u32(buffer, *i).unwrap(),
52 Self::Action(acts) => acts.as_slice().emit(buffer),
53 Self::Other(attr) => attr.emit_value(buffer),
54 }
55 }
56
57 fn kind(&self) -> u16 {
58 match self {
59 Self::ClassId(_) => TCA_MATCHALL_CLASSID,
60 Self::Action(_) => TCA_MATCHALL_ACT,
61 Self::Pnct(_) => TCA_MATCHALL_PCNT,
62 Self::Flags(_) => TCA_MATCHALL_FLAGS,
63 Self::Other(attr) => attr.kind(),
64 }
65 }
66}
67
68impl<'a, T: AsRef<[u8]> + ?Sized> Parseable<NlaBuffer<&'a T>>
69 for TcFilterMatchAllOption
70{
71 fn parse(buf: &NlaBuffer<&'a T>) -> Result<Self, DecodeError> {
72 let payload = buf.value();
73 Ok(match buf.kind() {
74 TCA_MATCHALL_CLASSID => Self::ClassId(
75 parse_u32(payload)
76 .context("failed to parse TCA_MATCHALL_UNSPEC")?
77 .into(),
78 ),
79 TCA_MATCHALL_ACT => {
80 let mut acts = vec![];
81 for act in NlasIterator::new(payload) {
82 let act = act.context("invalid TCA_MATCHALL_ACT")?;
83 acts.push(
84 TcAction::parse(&act)
85 .context("failed to parse TCA_MATCHALL_ACT")?,
86 );
87 }
88 Self::Action(acts)
89 }
90 TCA_MATCHALL_PCNT => Self::Pnct(payload.to_vec()),
91 TCA_MATCHALL_FLAGS => Self::Flags(
92 parse_u32(payload)
93 .context("failed to parse TCA_MATCHALL_FLAGS")?,
94 ),
95 _ => Self::Other(
96 DefaultNla::parse(buf).context("failed to parse u32 nla")?,
97 ),
98 })
99 }
100}