1use crate::constants::*;
4use netlink_packet_core::{
5 emit_i64, emit_u32, emit_u64, parse_i64, parse_u32, parse_u64, DecodeError,
6 Emitable, ErrorContext, Nla, NlaBuffer, NlasIterator, Parseable,
7};
8use std::{convert::TryFrom, mem::size_of_val};
9
10#[derive(Clone, Debug, PartialEq, Eq)]
13pub struct PolicyAttr {
14 pub index: u16,
15 pub attr_policy: AttributePolicyAttr,
16}
17
18impl Nla for PolicyAttr {
19 fn value_len(&self) -> usize {
20 self.attr_policy.buffer_len()
21 }
22
23 fn kind(&self) -> u16 {
24 self.index
25 }
26
27 fn emit_value(&self, buffer: &mut [u8]) {
28 self.attr_policy.emit(buffer);
29 }
30
31 fn is_nested(&self) -> bool {
32 true
33 }
34}
35
36impl<'a, T: AsRef<[u8]> + ?Sized> Parseable<NlaBuffer<&'a T>> for PolicyAttr {
37 fn parse(buf: &NlaBuffer<&'a T>) -> Result<Self, DecodeError> {
38 let payload = buf.value();
39
40 Ok(Self {
41 index: buf.kind(),
42 attr_policy: AttributePolicyAttr::parse(&NlaBuffer::new(payload))
43 .context("failed to parse PolicyAttr")?,
44 })
45 }
46}
47
48#[derive(Clone, Debug, PartialEq, Eq)]
51pub struct AttributePolicyAttr {
52 pub index: u16,
53 pub policies: Vec<NlPolicyTypeAttrs>,
54}
55
56impl Nla for AttributePolicyAttr {
57 fn value_len(&self) -> usize {
58 self.policies.as_slice().buffer_len()
59 }
60
61 fn kind(&self) -> u16 {
62 self.index
63 }
64
65 fn emit_value(&self, buffer: &mut [u8]) {
66 self.policies.as_slice().emit(buffer);
67 }
68
69 fn is_nested(&self) -> bool {
70 true
71 }
72}
73
74impl<'a, T: AsRef<[u8]> + ?Sized> Parseable<NlaBuffer<&'a T>>
75 for AttributePolicyAttr
76{
77 fn parse(buf: &NlaBuffer<&'a T>) -> Result<Self, DecodeError> {
78 let payload = buf.value();
79 let policies = NlasIterator::new(payload)
80 .map(|nla| nla.and_then(|nla| NlPolicyTypeAttrs::parse(&nla)))
81 .collect::<Result<Vec<_>, _>>()
82 .context("failed to parse AttributePolicyAttr")?;
83
84 Ok(Self {
85 index: buf.kind(),
86 policies,
87 })
88 }
89}
90
91#[derive(Clone, Debug, PartialEq, Eq)]
94pub enum NlPolicyTypeAttrs {
95 Type(NlaType),
96 MinValueSigned(i64),
97 MaxValueSigned(i64),
98 MaxValueUnsigned(u64),
99 MinValueUnsigned(u64),
100 MinLength(u32),
101 MaxLength(u32),
102 PolicyIdx(u32),
103 PolicyMaxType(u32),
104 Bitfield32Mask(u32),
105 Mask(u64),
106}
107
108impl Nla for NlPolicyTypeAttrs {
109 fn value_len(&self) -> usize {
110 use NlPolicyTypeAttrs::*;
111 match self {
112 Type(v) => size_of_val(v),
113 MinValueSigned(v) => size_of_val(v),
114 MaxValueSigned(v) => size_of_val(v),
115 MaxValueUnsigned(v) => size_of_val(v),
116 MinValueUnsigned(v) => size_of_val(v),
117 MinLength(v) => size_of_val(v),
118 MaxLength(v) => size_of_val(v),
119 PolicyIdx(v) => size_of_val(v),
120 PolicyMaxType(v) => size_of_val(v),
121 Bitfield32Mask(v) => size_of_val(v),
122 Mask(v) => size_of_val(v),
123 }
124 }
125
126 fn kind(&self) -> u16 {
127 use NlPolicyTypeAttrs::*;
128 match self {
129 Type(_) => NL_POLICY_TYPE_ATTR_TYPE,
130 MinValueSigned(_) => NL_POLICY_TYPE_ATTR_MIN_VALUE_S,
131 MaxValueSigned(_) => NL_POLICY_TYPE_ATTR_MAX_VALUE_S,
132 MaxValueUnsigned(_) => NL_POLICY_TYPE_ATTR_MIN_VALUE_U,
133 MinValueUnsigned(_) => NL_POLICY_TYPE_ATTR_MAX_VALUE_U,
134 MinLength(_) => NL_POLICY_TYPE_ATTR_MIN_LENGTH,
135 MaxLength(_) => NL_POLICY_TYPE_ATTR_MAX_LENGTH,
136 PolicyIdx(_) => NL_POLICY_TYPE_ATTR_POLICY_IDX,
137 PolicyMaxType(_) => NL_POLICY_TYPE_ATTR_POLICY_MAXTYPE,
138 Bitfield32Mask(_) => NL_POLICY_TYPE_ATTR_BITFIELD32_MASK,
139 Mask(_) => NL_POLICY_TYPE_ATTR_MASK,
140 }
141 }
142
143 fn emit_value(&self, buffer: &mut [u8]) {
144 use NlPolicyTypeAttrs::*;
145 match self {
146 Type(v) => emit_u32(buffer, u32::from(*v)).unwrap(),
147 MinValueSigned(v) => emit_i64(buffer, *v).unwrap(),
148 MaxValueSigned(v) => emit_i64(buffer, *v).unwrap(),
149 MaxValueUnsigned(v) => emit_u64(buffer, *v).unwrap(),
150 MinValueUnsigned(v) => emit_u64(buffer, *v).unwrap(),
151 MinLength(v) => emit_u32(buffer, *v).unwrap(),
152 MaxLength(v) => emit_u32(buffer, *v).unwrap(),
153 PolicyIdx(v) => emit_u32(buffer, *v).unwrap(),
154 PolicyMaxType(v) => emit_u32(buffer, *v).unwrap(),
155 Bitfield32Mask(v) => emit_u32(buffer, *v).unwrap(),
156 Mask(v) => emit_u64(buffer, *v).unwrap(),
157 }
158 }
159}
160
161impl<'a, T: AsRef<[u8]> + ?Sized> Parseable<NlaBuffer<&'a T>>
162 for NlPolicyTypeAttrs
163{
164 fn parse(buf: &NlaBuffer<&'a T>) -> Result<Self, DecodeError> {
165 let payload = buf.value();
166 Ok(match buf.kind() {
167 NL_POLICY_TYPE_ATTR_TYPE => {
168 let value = parse_u32(payload)
169 .context("invalid NL_POLICY_TYPE_ATTR_TYPE value")?;
170 Self::Type(NlaType::try_from(value)?)
171 }
172 NL_POLICY_TYPE_ATTR_MIN_VALUE_S => Self::MinValueSigned(
173 parse_i64(payload)
174 .context("invalid NL_POLICY_TYPE_ATTR_MIN_VALUE_S value")?,
175 ),
176 NL_POLICY_TYPE_ATTR_MAX_VALUE_S => Self::MaxValueSigned(
177 parse_i64(payload)
178 .context("invalid NL_POLICY_TYPE_ATTR_MAX_VALUE_S value")?,
179 ),
180 NL_POLICY_TYPE_ATTR_MIN_VALUE_U => Self::MinValueUnsigned(
181 parse_u64(payload)
182 .context("invalid NL_POLICY_TYPE_ATTR_MIN_VALUE_U value")?,
183 ),
184 NL_POLICY_TYPE_ATTR_MAX_VALUE_U => Self::MaxValueUnsigned(
185 parse_u64(payload)
186 .context("invalid NL_POLICY_TYPE_ATTR_MAX_VALUE_U value")?,
187 ),
188 NL_POLICY_TYPE_ATTR_MIN_LENGTH => Self::MinLength(
189 parse_u32(payload)
190 .context("invalid NL_POLICY_TYPE_ATTR_MIN_LENGTH value")?,
191 ),
192 NL_POLICY_TYPE_ATTR_MAX_LENGTH => Self::MaxLength(
193 parse_u32(payload)
194 .context("invalid NL_POLICY_TYPE_ATTR_MAX_LENGTH value")?,
195 ),
196 NL_POLICY_TYPE_ATTR_POLICY_IDX => Self::PolicyIdx(
197 parse_u32(payload)
198 .context("invalid NL_POLICY_TYPE_ATTR_POLICY_IDX value")?,
199 ),
200 NL_POLICY_TYPE_ATTR_POLICY_MAXTYPE => {
201 Self::PolicyMaxType(parse_u32(payload).context(
202 "invalid NL_POLICY_TYPE_ATTR_POLICY_MAXTYPE value",
203 )?)
204 }
205 NL_POLICY_TYPE_ATTR_BITFIELD32_MASK => {
206 Self::Bitfield32Mask(parse_u32(payload).context(
207 "invalid NL_POLICY_TYPE_ATTR_BITFIELD32_MASK value",
208 )?)
209 }
210 NL_POLICY_TYPE_ATTR_MASK => Self::Mask(
211 parse_u64(payload)
212 .context("invalid NL_POLICY_TYPE_ATTR_MASK value")?,
213 ),
214 kind => {
215 return Err(DecodeError::from(format!(
216 "Unknown NLA type: {kind}"
217 )))
218 }
219 })
220 }
221}
222
223#[derive(Copy, Clone, Debug, PartialEq, Eq)]
224pub enum NlaType {
225 Flag,
226 U8,
227 U16,
228 U32,
229 U64,
230 S8,
231 S16,
232 S32,
233 S64,
234 Binary,
235 String,
236 NulString,
237 Nested,
238 NestedArray,
239 Bitfield32,
240}
241
242impl From<NlaType> for u32 {
243 fn from(nlatype: NlaType) -> u32 {
244 match nlatype {
245 NlaType::Flag => NL_ATTR_TYPE_FLAG,
246 NlaType::U8 => NL_ATTR_TYPE_U8,
247 NlaType::U16 => NL_ATTR_TYPE_U16,
248 NlaType::U32 => NL_ATTR_TYPE_U32,
249 NlaType::U64 => NL_ATTR_TYPE_U64,
250 NlaType::S8 => NL_ATTR_TYPE_S8,
251 NlaType::S16 => NL_ATTR_TYPE_S16,
252 NlaType::S32 => NL_ATTR_TYPE_S32,
253 NlaType::S64 => NL_ATTR_TYPE_S64,
254 NlaType::Binary => NL_ATTR_TYPE_BINARY,
255 NlaType::String => NL_ATTR_TYPE_STRING,
256 NlaType::NulString => NL_ATTR_TYPE_NUL_STRING,
257 NlaType::Nested => NL_ATTR_TYPE_NESTED,
258 NlaType::NestedArray => NL_ATTR_TYPE_NESTED_ARRAY,
259 NlaType::Bitfield32 => NL_ATTR_TYPE_BITFIELD32,
260 }
261 }
262}
263
264impl TryFrom<u32> for NlaType {
265 type Error = DecodeError;
266
267 fn try_from(value: u32) -> Result<Self, Self::Error> {
268 Ok(match value {
269 NL_ATTR_TYPE_FLAG => NlaType::Flag,
270 NL_ATTR_TYPE_U8 => NlaType::U8,
271 NL_ATTR_TYPE_U16 => NlaType::U16,
272 NL_ATTR_TYPE_U32 => NlaType::U32,
273 NL_ATTR_TYPE_U64 => NlaType::U64,
274 NL_ATTR_TYPE_S8 => NlaType::S8,
275 NL_ATTR_TYPE_S16 => NlaType::S16,
276 NL_ATTR_TYPE_S32 => NlaType::S32,
277 NL_ATTR_TYPE_S64 => NlaType::S64,
278 NL_ATTR_TYPE_BINARY => NlaType::Binary,
279 NL_ATTR_TYPE_STRING => NlaType::String,
280 NL_ATTR_TYPE_NUL_STRING => NlaType::NulString,
281 NL_ATTR_TYPE_NESTED => NlaType::Nested,
282 NL_ATTR_TYPE_NESTED_ARRAY => NlaType::NestedArray,
283 NL_ATTR_TYPE_BITFIELD32 => NlaType::Bitfield32,
284 _ => {
285 return Err(DecodeError::from(format!(
286 "invalid NLA type: {value}"
287 )))
288 }
289 })
290 }
291}