nftables_json/
object.rs

1// Copyright (c) nftables-json Developers
2// SPDX-License-Identifier: MIT OR Apache-2.0
3
4//! Provides types related to parsing output from `nft --json`
5
6use crate::expression::*;
7use crate::statement::*;
8
9#[serde_with::apply(Option => #[serde(default, skip_serializing_if = "Option::is_none")])]
10#[derive(Debug, Default, Clone, serde::Serialize, serde::Deserialize)]
11#[serde(deny_unknown_fields)]
12pub struct Metainfo {
13    pub version: Option<String>,
14    pub release_name: Option<String>,
15    pub json_schema_version: isize,
16}
17
18#[serde_with::apply(Option => #[serde(default, skip_serializing_if = "Option::is_none")])]
19#[derive(Debug, Default, Clone, serde::Serialize, serde::Deserialize)]
20#[serde(deny_unknown_fields)]
21pub struct Table {
22    pub family: String,
23    pub name: String,
24    pub handle: Option<isize>,
25    pub flags: Option<Vec<String>>,
26}
27
28#[serde_with::apply(Option => #[serde(default, skip_serializing_if = "Option::is_none")])]
29#[derive(Debug, Default, Clone, serde::Serialize, serde::Deserialize)]
30#[serde(deny_unknown_fields)]
31pub struct Chain {
32    pub family: String,
33    pub table: String,
34    pub name: String,
35    pub handle: Option<isize>,
36    pub dev: Option<String>,
37    pub policy: Option<String>,
38    #[serde(rename = "type")]
39    pub r#type: Option<String>,
40    pub hook: Option<String>,
41    pub prio: Option<isize>,
42}
43
44#[serde_with::apply(Option => #[serde(default, skip_serializing_if = "Option::is_none")])]
45#[derive(Debug, Default, Clone, serde::Serialize, serde::Deserialize)]
46#[serde(deny_unknown_fields)]
47pub struct Rule {
48    pub family: String,
49    pub table: String,
50    pub chain: String,
51    pub handle: Option<isize>,
52    pub index: Option<isize>,
53    pub comment: Option<String>,
54    pub expr: Option<Vec<Statement>>,
55}
56
57#[serde_with::apply(Option => #[serde(default, skip_serializing_if = "Option::is_none")])]
58#[derive(Debug, Default, Clone, serde::Serialize, serde::Deserialize)]
59#[serde(deny_unknown_fields)]
60pub struct Set {
61    pub family: String,
62    pub table: String,
63    pub name: String,
64    pub handle: Option<isize>,
65    pub comment: Option<String>,
66    #[serde(rename = "type")]
67    pub r#type: Option<String>,
68    pub policy: Option<String>,
69    pub flags: Option<Vec<String>>,
70    pub size: Option<isize>,
71    pub timeout: Option<isize>,
72    #[serde(rename = "gc-interval")]
73    pub gc_interval: Option<isize>,
74    #[serde(with = "serde_with::As::<Option<serde_with::OneOrMany<serde_with::Same>>>")]
75    pub elem: Option<Vec<Expression>>,
76    pub stmt: Option<Vec<Statement>>,
77}
78
79#[serde_with::apply(Option => #[serde(default, skip_serializing_if = "Option::is_none")])]
80#[derive(Debug, Default, Clone, serde::Serialize, serde::Deserialize)]
81#[serde(deny_unknown_fields)]
82pub struct Map {
83    pub family: String,
84    pub table: String,
85    pub name: String,
86    pub handle: Option<isize>,
87    pub comment: Option<String>,
88    pub map: Option<String>,
89    #[serde(rename = "type")]
90    pub r#type: Option<String>,
91    pub policy: Option<String>,
92    pub flags: Option<Vec<String>>,
93    pub size: Option<isize>,
94    pub timeout: Option<isize>,
95    #[serde(rename = "gc-interval")]
96    pub gc_interval: Option<isize>,
97    #[serde(with = "serde_with::As::<Option<serde_with::OneOrMany<serde_with::Same>>>")]
98    pub elem: Option<Vec<Expression>>,
99    pub stmt: Option<Vec<Statement>>,
100}
101
102#[serde_with::apply(Option => #[serde(default, skip_serializing_if = "Option::is_none")])]
103#[derive(Debug, Default, Clone, serde::Serialize, serde::Deserialize)]
104#[serde(deny_unknown_fields)]
105pub struct Element {
106    pub family: String,
107    pub table: String,
108    pub name: String,
109    #[serde(with = "serde_with::As::<Option<serde_with::OneOrMany<serde_with::Same>>>")]
110    pub elem: Option<Vec<Expression>>,
111}
112
113#[serde_with::apply(Option => #[serde(default, skip_serializing_if = "Option::is_none")])]
114#[derive(Debug, Default, Clone, serde::Serialize, serde::Deserialize)]
115#[serde(deny_unknown_fields)]
116pub struct Flowtable {
117    pub family: String,
118    pub table: String,
119    pub name: String,
120    pub handle: Option<isize>,
121    pub comment: Option<String>,
122    pub hook: Option<String>,
123    pub prio: Option<isize>,
124    #[serde(with = "serde_with::As::<Option<serde_with::OneOrMany<serde_with::Same>>>")]
125    pub dev: Option<Vec<String>>,
126}
127
128#[serde_with::apply(Option => #[serde(default, skip_serializing_if = "Option::is_none")])]
129#[derive(Debug, Default, Clone, serde::Serialize, serde::Deserialize)]
130#[serde(deny_unknown_fields)]
131pub struct Counter {
132    pub family: String,
133    pub table: String,
134    pub name: String,
135    pub handle: Option<isize>,
136    pub comment: Option<String>,
137    pub packets: Option<isize>,
138    pub bytes: Option<isize>,
139}
140
141#[serde_with::apply(Option => #[serde(default, skip_serializing_if = "Option::is_none")])]
142#[derive(Debug, Default, Clone, serde::Serialize, serde::Deserialize)]
143#[serde(deny_unknown_fields)]
144pub struct Quota {
145    pub family: String,
146    pub table: String,
147    pub name: String,
148    pub handle: Option<isize>,
149    pub comment: Option<String>,
150    pub bytes: Option<isize>,
151    pub used: Option<isize>,
152    pub inv: Option<bool>,
153}
154
155#[serde_with::apply(Option => #[serde(default, skip_serializing_if = "Option::is_none")])]
156#[derive(Debug, Default, Clone, serde::Serialize, serde::Deserialize)]
157#[serde(deny_unknown_fields)]
158pub struct CtHelper {
159    pub family: String,
160    pub table: String,
161    pub name: String,
162    pub handle: Option<isize>,
163    pub comment: Option<String>,
164    #[serde(rename = "type")]
165    pub r#type: Option<String>,
166    pub protocol: Option<String>,
167    pub l3proto: Option<String>,
168}
169
170#[serde_with::apply(Option => #[serde(default, skip_serializing_if = "Option::is_none")])]
171#[derive(Debug, Default, Clone, serde::Serialize, serde::Deserialize)]
172#[serde(deny_unknown_fields)]
173pub struct CtTimeout {
174    pub family: String,
175    pub table: String,
176    pub name: String,
177    pub handle: Option<isize>,
178    pub comment: Option<String>,
179    pub protocol: Option<String>,
180    pub l3proto: Option<String>,
181    pub policy: Option<std::collections::HashMap<String, isize>>,
182}
183
184#[serde_with::apply(Option => #[serde(default, skip_serializing_if = "Option::is_none")])]
185#[derive(Debug, Default, Clone, serde::Serialize, serde::Deserialize)]
186#[serde(deny_unknown_fields)]
187pub struct CtExpectation {
188    pub family: String,
189    pub table: String,
190    pub name: String,
191    pub handle: Option<isize>,
192    pub comment: Option<String>,
193    pub protocol: Option<String>,
194    pub l3proto: Option<String>,
195    pub dport: Option<String>,
196    pub timeout: Option<isize>,
197    pub size: Option<String>,
198}
199
200#[serde_with::apply(Option => #[serde(default, skip_serializing_if = "Option::is_none")])]
201#[derive(Debug, Default, Clone, serde::Serialize, serde::Deserialize)]
202#[serde(deny_unknown_fields)]
203pub struct Limit {
204    pub family: String,
205    pub table: String,
206    pub name: String,
207    pub handle: Option<isize>,
208    pub comment: Option<String>,
209    pub rate: Option<isize>,
210    pub rate_unit: Option<String>,
211    pub per: Option<String>,
212    pub burst: Option<isize>,
213    pub burst_unit: Option<String>,
214    pub inv: Option<bool>,
215}
216
217#[serde_with::apply(Option => #[serde(default, skip_serializing_if = "Option::is_none")])]
218#[derive(Debug, Default, Clone, serde::Serialize, serde::Deserialize)]
219#[serde(deny_unknown_fields)]
220pub struct Secmark {
221    pub family: String,
222    pub table: String,
223    pub name: String,
224    pub handle: Option<isize>,
225    pub comment: Option<String>,
226    pub context: Option<String>,
227}
228
229#[serde_with::apply(Option => #[serde(default, skip_serializing_if = "Option::is_none")])]
230#[derive(Debug, Default, Clone, serde::Serialize, serde::Deserialize)]
231#[serde(deny_unknown_fields)]
232pub struct Synproxy {
233    pub family: String,
234    pub table: String,
235    pub name: String,
236    pub handle: Option<isize>,
237    pub comment: Option<String>,
238    pub mss: Option<isize>,
239    pub wscale: Option<isize>,
240    #[serde(with = "serde_with::As::<Option<serde_with::OneOrMany<serde_with::Same>>>")]
241    pub flags: Option<Vec<String>>,
242}
243
244/// Represents a component of an nftables ruleset
245#[serde_with::apply(Option => #[serde(default, skip_serializing_if = "Option::is_none")])]
246#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
247#[serde(deny_unknown_fields, rename_all = "kebab-case")]
248#[non_exhaustive]
249pub enum Object {
250    Metainfo(Metainfo),
251    Table(Table),
252    Chain(Chain),
253    Rule(Rule),
254    Set(Set),
255    #[serde(alias = "meter")]
256    Map(Map),
257    Element(Element),
258    Flowtable(Flowtable),
259    Counter(Counter),
260    Quota(Quota),
261    #[serde(rename = "ct helper")]
262    CtHelper(CtHelper),
263    #[serde(rename = "ct timeout")]
264    CtTimeout(CtTimeout),
265    #[serde(rename = "ct expectation")]
266    CtExpectation(CtExpectation),
267    Limit(Limit),
268    Secmark(Secmark),
269    Synproxy(Synproxy),
270}
271
272/// Represents the components of an nftables ruleset
273#[serde_with::apply(Option => #[serde(default, skip_serializing_if = "Option::is_none")])]
274#[derive(Debug, Default, Clone, serde::Serialize, serde::Deserialize)]
275#[serde(deny_unknown_fields)]
276pub struct Objects {
277    #[serde(rename = "nftables")]
278    objects: Vec<Object>,
279}
280
281impl Objects {
282    pub fn new() -> Self {
283        Self::default()
284    }
285
286    pub fn from_value(value: serde_json::Value) -> serde_json::Result<Self> {
287        serde_json::from_value(value)
288    }
289
290    pub fn from_str(string: &str) -> serde_json::Result<Self> {
291        serde_json::from_str(string)
292    }
293
294    pub fn from_slice(slice: &[u8]) -> serde_json::Result<Self> {
295        serde_json::from_slice(slice)
296    }
297
298    pub fn from_reader<R: std::io::Read>(reader: R) -> serde_json::Result<Self> {
299        serde_json::from_reader(reader)
300    }
301
302    pub fn to_value(&self) -> serde_json::Result<serde_json::Value> {
303        serde_json::to_value(self)
304    }
305
306    pub fn to_string(&self) -> serde_json::Result<String> {
307        serde_json::to_string(self)
308    }
309}
310
311impl From<&[Object]> for Objects {
312    fn from(value: &[Object]) -> Self {
313        Self { objects: Vec::from(value) }
314    }
315}
316
317impl From<&mut [Object]> for Objects {
318    fn from(value: &mut [Object]) -> Self {
319        Self { objects: Vec::from(value) }
320    }
321}
322
323impl From<Box<[Object]>> for Objects {
324    fn from(value: Box<[Object]>) -> Self {
325        Self { objects: Vec::from(value) }
326    }
327}
328
329impl From<Vec<Object>> for Objects {
330    fn from(value: Vec<Object>) -> Self {
331        Self { objects: Vec::from(value) }
332    }
333}
334
335impl FromIterator<Object> for Objects {
336    fn from_iter<T: IntoIterator<Item = Object>>(iter: T) -> Self {
337        Self { objects: Vec::from_iter(iter) }
338    }
339}
340
341impl Extend<Object> for Objects {
342    fn extend<T: IntoIterator<Item = Object>>(&mut self, iter: T) {
343        self.objects.extend(iter.into_iter());
344    }
345}
346
347impl<'a> Extend<&'a Object> for Objects {
348    fn extend<T: IntoIterator<Item = &'a Object>>(&mut self, iter: T) {
349        self.objects.extend(iter.into_iter().map(|item| item.clone()));
350    }
351}
352
353impl std::ops::Deref for Objects {
354    type Target = [Object];
355
356    fn deref(&self) -> &Self::Target {
357        &self.objects
358    }
359}
360
361impl std::ops::DerefMut for Objects {
362    fn deref_mut(&mut self) -> &mut Self::Target {
363        &mut self.objects
364    }
365}
366
367impl std::fmt::Display for Objects {
368    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
369        f.write_str(&self.to_string().map_err(|_| std::fmt::Error::default())?)
370    }
371}