netlink_packet_route/rtnl/tc/nlas/action/
mirred.rs1use netlink_packet_utils::{
10 nla::{self, DefaultNla, NlaBuffer},
11 traits::{Emitable, Parseable},
12 DecodeError,
13};
14
15use crate::tc::{constants::*, TC_GEN_BUF_LEN};
16
17pub const KIND: &str = "mirred";
18pub const TC_MIRRED_BUF_LEN: usize = TC_GEN_BUF_LEN + 8;
19
20#[derive(Debug, PartialEq, Eq, Clone)]
21#[non_exhaustive]
22pub enum Nla {
23 Unspec(Vec<u8>),
24 Tm(Vec<u8>),
25 Parms(TcMirred),
26 Other(DefaultNla),
27}
28
29impl nla::Nla for Nla {
30 fn value_len(&self) -> usize {
31 use self::Nla::*;
32 match self {
33 Unspec(bytes) | Tm(bytes) => bytes.len(),
34 Parms(_) => TC_MIRRED_BUF_LEN,
35 Other(attr) => attr.value_len(),
36 }
37 }
38
39 fn emit_value(&self, buffer: &mut [u8]) {
40 use self::Nla::*;
41 match self {
42 Unspec(bytes) | Tm(bytes) => {
43 buffer.copy_from_slice(bytes.as_slice())
44 }
45 Parms(p) => p.emit(buffer),
46 Other(attr) => attr.emit_value(buffer),
47 }
48 }
49 fn kind(&self) -> u16 {
50 use self::Nla::*;
51 match self {
52 Unspec(_) => TCA_MIRRED_UNSPEC,
53 Tm(_) => TCA_MIRRED_TM,
54 Parms(_) => TCA_MIRRED_PARMS,
55 Other(nla) => nla.kind(),
56 }
57 }
58}
59
60impl<'a, T: AsRef<[u8]> + ?Sized> Parseable<NlaBuffer<&'a T>> for Nla {
61 fn parse(buf: &NlaBuffer<&'a T>) -> Result<Self, DecodeError> {
62 use self::Nla::*;
63 let payload = buf.value();
64 Ok(match buf.kind() {
65 TCA_MIRRED_UNSPEC => Unspec(payload.to_vec()),
66 TCA_MIRRED_TM => Tm(payload.to_vec()),
67 TCA_MIRRED_PARMS => {
68 Parms(TcMirred::parse(&TcMirredBuffer::new_checked(payload)?)?)
69 }
70 _ => Other(DefaultNla::parse(buf)?),
71 })
72 }
73}
74
75#[derive(Debug, PartialEq, Eq, Clone, Default)]
76#[non_exhaustive]
77pub struct TcMirred {
78 pub index: u32,
79 pub capab: u32,
80 pub action: i32,
81 pub refcnt: i32,
82 pub bindcnt: i32,
83
84 pub eaction: i32,
85 pub ifindex: u32,
86}
87
88buffer!(TcMirredBuffer(TC_MIRRED_BUF_LEN) {
89 index: (u32, 0..4),
90 capab: (u32, 4..8),
91 action: (i32, 8..12),
92 refcnt: (i32, 12..16),
93 bindcnt: (i32, 16..20),
94 eaction: (i32, TC_GEN_BUF_LEN..(TC_GEN_BUF_LEN + 4)),
95 ifindex: (u32, (TC_GEN_BUF_LEN + 4)..TC_MIRRED_BUF_LEN),
96});
97
98impl Emitable for TcMirred {
99 fn buffer_len(&self) -> usize {
100 TC_MIRRED_BUF_LEN
101 }
102
103 fn emit(&self, buffer: &mut [u8]) {
104 let mut packet = TcMirredBuffer::new(buffer);
105 packet.set_index(self.index);
106 packet.set_capab(self.capab);
107 packet.set_action(self.action);
108 packet.set_refcnt(self.refcnt);
109 packet.set_bindcnt(self.bindcnt);
110
111 packet.set_eaction(self.eaction);
112 packet.set_ifindex(self.ifindex);
113 }
114}
115
116impl<T: AsRef<[u8]>> Parseable<TcMirredBuffer<T>> for TcMirred {
117 fn parse(buf: &TcMirredBuffer<T>) -> Result<Self, DecodeError> {
118 Ok(Self {
119 index: buf.index(),
120 capab: buf.capab(),
121 action: buf.action(),
122 refcnt: buf.refcnt(),
123 bindcnt: buf.bindcnt(),
124 eaction: buf.eaction(),
125 ifindex: buf.ifindex(),
126 })
127 }
128}