nftables/
schema.rs

1use schemars::JsonSchema;
2use std::{borrow::Cow, collections::HashSet};
3
4use crate::visitor::deserialize_optional_flags;
5use crate::{
6    expr::Expression, stmt::Statement, types::*, visitor::single_string_to_option_vec,
7    DEFAULT_CHAIN, DEFAULT_FAMILY, DEFAULT_TABLE,
8};
9
10use serde::{Deserialize, Serialize};
11
12use strum_macros::EnumString;
13
14#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize, JsonSchema)]
15/// In general, any JSON input or output is enclosed in an object with a single property named **nftables**.
16///
17/// See [libnftables-json global structure](Global Structure).
18///
19/// (Global Structure): <https://manpages.debian.org/testing/libnftables1/libnftables-json.5.en.html#GLOBAL_STRUCTURE>
20pub struct Nftables<'a> {
21    /// An array containing [commands](NfCmd) (for input) or [ruleset elements](NfListObject) (for output).
22    #[serde(rename = "nftables")]
23    pub objects: Cow<'a, [NfObject<'a>]>,
24}
25
26#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize, JsonSchema)]
27#[serde(untagged)]
28/// A [ruleset element](NfListObject) or [command](NfCmd) in an [nftables document](Nftables).
29pub enum NfObject<'a> {
30    /// A command.
31    CmdObject(NfCmd<'a>),
32    /// A ruleset element.
33    ListObject(NfListObject<'a>),
34}
35
36#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize, JsonSchema)]
37#[serde(rename_all = "lowercase")]
38/// A ruleset element in an [nftables document](Nftables).
39pub enum NfListObject<'a> {
40    /// A table element.
41    Table(Table<'a>),
42    /// A chain element.
43    Chain(Chain<'a>),
44    /// A rule element.
45    Rule(Rule<'a>),
46    /// A set element.
47    Set(Box<Set<'a>>),
48    /// A map element.
49    Map(Box<Map<'a>>),
50    /// An element manipulation.
51    Element(Element<'a>),
52    /// A flow table.
53    FlowTable(FlowTable<'a>),
54    /// A counter.
55    Counter(Counter<'a>),
56    /// A quota.
57    Quota(Quota<'a>),
58    #[serde(rename = "ct helper")]
59    /// A conntrack helper (ct helper).
60    CTHelper(CTHelper<'a>),
61    /// A limit.
62    Limit(Limit<'a>),
63    #[serde(rename = "metainfo")]
64    /// The metainfo object.
65    MetainfoObject(MetainfoObject<'a>),
66    /// A conntrack timeout (ct timeout).
67    CTTimeout(CTTimeout<'a>),
68    #[serde(rename = "ct expectation")]
69    /// A conntrack expectation (ct expectation).
70    CTExpectation(CTExpectation<'a>),
71    /// A synproxy object.
72    SynProxy(SynProxy<'a>),
73}
74
75#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize, JsonSchema)]
76#[serde(rename_all = "lowercase")]
77/// A command is an object with a single property whose name identifies the command.
78///
79/// Its value is a ruleset element - basically identical to output elements,
80/// apart from certain properties which may be interpreted differently or are
81/// required when output generally omits them.
82pub enum NfCmd<'a> {
83    /// Add a new ruleset element to the kernel.
84    Add(NfListObject<'a>),
85    /// Replace a rule.
86    ///
87    /// In [RULE](Rule), the **handle** property is mandatory and identifies
88    /// the rule to be replaced.
89    Replace(Rule<'a>),
90    /// Identical to [add command](NfCmd::Add), but returns an error if the object already exists.
91    Create(NfListObject<'a>), // TODO: ADD_OBJECT is subset of NfListObject
92    /// Insert an object.
93    ///
94    /// This command is identical to [add](NfCmd::Add) for rules, but instead of
95    /// appending the rule to the chain by default, it inserts at first position.
96    /// If a handle or index property is given, the rule is inserted before the
97    /// rule identified by those properties.
98    Insert(NfListObject<'a>),
99    /// Delete an object from the ruleset.
100    ///
101    /// Only the minimal number of properties required to uniquely identify an
102    /// object is generally needed in the enclosed object.
103    /// For most ruleset elements, this is **family** and **table** plus either
104    /// **handle** or **name** (except rules since they don’t have a name).
105    Delete(NfListObject<'a>), // TODO: ADD_OBJECT is subset of NfListObject
106    /// List ruleset elements.
107    ///
108    /// The plural forms are used to list all objects of that kind,
109    /// optionally filtered by family and for some, also table.
110    List(NfListObject<'a>),
111    /// Reset state in suitable objects, i.e. zero their internal counter.
112    Reset(ResetObject<'a>),
113    /// Empty contents in given object, e.g. remove all chains from given table
114    /// or remove all elements from given set.
115    Flush(FlushObject<'a>),
116    /// Rename a [chain](Chain).
117    ///
118    /// The new name is expected in a dedicated property named **newname**.
119    Rename(Chain<'a>),
120}
121
122#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize, JsonSchema)]
123#[serde(rename_all = "lowercase")]
124/// Reset state in suitable objects, i.e. zero their internal counter.
125pub enum ResetObject<'a> {
126    /// A counter to reset.
127    Counter(Counter<'a>),
128    /// A list of counters to reset.
129    Counters(Cow<'a, [Counter<'a>]>),
130    /// A quota to reset.
131    Quota(Quota<'a>),
132    /// A list of quotas to reset.
133    Quotas(Cow<'a, [Quota<'a>]>),
134}
135
136#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize, JsonSchema)]
137#[serde(rename_all = "lowercase")]
138/// Empty contents in given object, e.g. remove all chains from given table or remove all elements from given set.
139pub enum FlushObject<'a> {
140    /// A table to flush (i.e., remove all chains from table).
141    Table(Table<'a>),
142    /// A chain to flush (i.e., remove all rules from chain).
143    Chain(Chain<'a>),
144    /// A set to flush (i.e., remove all elements from set).
145    Set(Box<Set<'a>>),
146    /// A map to flush (i.e., remove all elements from map).
147    Map(Box<Map<'a>>),
148    /// A meter to flush.
149    Meter(Meter<'a>),
150    /// Flush the live ruleset (i.e., remove all elements from live ruleset).
151    Ruleset(Option<Ruleset>),
152}
153
154// Ruleset Elements
155
156#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize, JsonSchema)]
157/// This object describes a table.
158pub struct Table<'a> {
159    /// The table’s [family](NfFamily), e.g. "ip" or "ip6".
160    pub family: NfFamily,
161    /// The table’s name.
162    pub name: Cow<'a, str>,
163    #[serde(skip_serializing_if = "Option::is_none")]
164    /// The table’s handle.
165    ///
166    /// In input, it is used only in [delete command](NfCmd::Delete) as
167    /// alternative to **name**.
168    pub handle: Option<u32>,
169}
170
171/// Default table.
172impl Default for Table<'_> {
173    fn default() -> Self {
174        Table {
175            family: DEFAULT_FAMILY,
176            name: DEFAULT_TABLE.into(),
177            handle: None,
178        }
179    }
180}
181
182#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize, JsonSchema)]
183/// This object describes a chain.
184pub struct Chain<'a> {
185    /// The table’s family.
186    pub family: NfFamily,
187    /// The table’s name.
188    pub table: Cow<'a, str>,
189    /// The chain’s name.
190    pub name: Cow<'a, str>,
191    #[serde(skip_serializing_if = "Option::is_none")]
192    /// New name of the chain when supplied to the [rename command](NfCmd::Rename).
193    pub newname: Option<Cow<'a, str>>,
194    #[serde(skip_serializing_if = "Option::is_none")]
195    /// The chain’s handle.
196    /// In input, it is used only in [delete command](NfCmd::Delete) as alternative to **name**.
197    pub handle: Option<u32>,
198    #[serde(skip_serializing_if = "Option::is_none", rename = "type")]
199    /// The chain’s type.
200    /// Required for [base chains](Base chains).
201    ///
202    /// (Base chains): <https://wiki.nftables.org/wiki-nftables/index.php/Configuring_chains#Adding_base_chains>
203    pub _type: Option<NfChainType>, // type
204    #[serde(skip_serializing_if = "Option::is_none")]
205    /// The chain’s hook.
206    /// Required for [base chains](Base chains).
207    ///
208    /// (Base chains): <https://wiki.nftables.org/wiki-nftables/index.php/Configuring_chains#Adding_base_chains>
209    pub hook: Option<NfHook>,
210    #[serde(skip_serializing_if = "Option::is_none")]
211    /// The chain’s priority.
212    /// Required for [base chains](Base chains).
213    ///
214    /// (Base chains): <https://wiki.nftables.org/wiki-nftables/index.php/Configuring_chains#Adding_base_chains>
215    pub prio: Option<i32>,
216    #[serde(skip_serializing_if = "Option::is_none")]
217    /// The chain’s bound interface (if in the netdev family).
218    /// Required for [base chains](Base chains).
219    ///
220    /// (Base chains): <https://wiki.nftables.org/wiki-nftables/index.php/Configuring_chains#Adding_base_chains>
221    pub dev: Option<Cow<'a, str>>,
222    #[serde(skip_serializing_if = "Option::is_none")]
223    /// The chain’s [policy](NfChainPolicy).
224    /// Required for [base chains](Base chains).
225    ///
226    /// (Base chains): <https://wiki.nftables.org/wiki-nftables/index.php/Configuring_chains#Adding_base_chains>
227    pub policy: Option<NfChainPolicy>,
228}
229
230/// Default Chain.
231impl Default for Chain<'_> {
232    fn default() -> Self {
233        Chain {
234            family: DEFAULT_FAMILY,
235            table: DEFAULT_TABLE.into(),
236            name: DEFAULT_CHAIN.into(),
237            newname: None,
238            handle: None,
239            _type: None,
240            hook: None,
241            prio: None,
242            dev: None,
243            policy: None,
244        }
245    }
246}
247
248#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize, JsonSchema)]
249/// This object describes a rule.
250///
251/// Basic building blocks of rules are statements.
252/// Each rule consists of at least one.
253pub struct Rule<'a> {
254    /// The table’s family.
255    pub family: NfFamily,
256    /// The table’s name.
257    pub table: Cow<'a, str>,
258    /// The chain’s name.
259    pub chain: Cow<'a, str>,
260    /// An array of statements this rule consists of.
261    ///
262    /// In input, it is used in [add](NfCmd::Add)/[insert](NfCmd::Insert)/[replace](NfCmd::Replace) commands only.
263    pub expr: Cow<'a, [Statement<'a>]>,
264    #[serde(skip_serializing_if = "Option::is_none")]
265    /// The rule’s handle.
266    ///
267    /// In [delete](NfCmd::Delete)/[replace](NfCmd::Replace) commands, it serves as an identifier of the rule to delete/replace.
268    /// In [add](NfCmd::Add)/[insert](NfCmd::Insert) commands, it serves as an identifier of an existing rule to append/prepend the rule to.
269    pub handle: Option<u32>,
270    #[serde(skip_serializing_if = "Option::is_none")]
271    /// The rule’s position for [add](NfCmd::Add)/[insert](NfCmd::Insert) commands.
272    ///
273    /// It is used as an alternative to **handle** then.
274    pub index: Option<u32>,
275    #[serde(skip_serializing_if = "Option::is_none")]
276    /// Optional rule comment.
277    pub comment: Option<Cow<'a, str>>,
278}
279
280/// Default rule with no expressions.
281impl Default for Rule<'_> {
282    fn default() -> Self {
283        Rule {
284            family: DEFAULT_FAMILY,
285            table: DEFAULT_TABLE.into(),
286            chain: DEFAULT_CHAIN.into(),
287            expr: [][..].into(),
288            handle: None,
289            index: None,
290            comment: None,
291        }
292    }
293}
294
295#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize, JsonSchema)]
296/// Named set that holds expression elements.
297pub struct Set<'a> {
298    /// The table’s family.
299    pub family: NfFamily,
300    /// The table’s name.
301    pub table: Cow<'a, str>,
302    /// The set’s name.
303    pub name: Cow<'a, str>,
304    #[serde(skip_serializing_if = "Option::is_none")]
305    /// The set’s handle. For input, it is used by the [delete command](NfCmd::Delete) only.
306    pub handle: Option<u32>,
307    #[serde(rename = "type")]
308    /// The set’s datatype.
309    ///
310    /// The set type might be a string, such as `"ipv4_addr"` or an array consisting of strings (for concatenated types).
311    pub set_type: SetTypeValue<'a>,
312    #[serde(skip_serializing_if = "Option::is_none")]
313    /// The set’s policy.
314    pub policy: Option<SetPolicy>,
315    #[serde(
316        skip_serializing_if = "Option::is_none",
317        deserialize_with = "deserialize_optional_flags",
318        default
319    )]
320    /// The set’s flags.
321    pub flags: Option<HashSet<SetFlag>>,
322    #[serde(skip_serializing_if = "Option::is_none")]
323    /// Initial set element(s).
324    ///
325    /// A single set element might be given as string, integer or boolean value for simple cases. If additional properties are required, a formal elem object may be used.
326    /// Multiple elements may be given in an array.
327    pub elem: Option<Cow<'a, [Expression<'a>]>>,
328    #[serde(skip_serializing_if = "Option::is_none")]
329    /// Element timeout in seconds.
330    pub timeout: Option<u32>,
331    #[serde(rename = "gc-interval", skip_serializing_if = "Option::is_none")]
332    /// Garbage collector interval in seconds.
333    pub gc_interval: Option<u32>,
334    #[serde(skip_serializing_if = "Option::is_none")]
335    /// Maximum number of elements supported.
336    pub size: Option<u32>,
337    #[serde(skip_serializing_if = "Option::is_none")]
338    /// Optional set comment.
339    ///
340    /// Set comment attribute requires at least nftables 0.9.7 and kernel 5.10
341    pub comment: Option<Cow<'a, str>>,
342}
343
344/// Default set `"myset"` with type `ipv4_addr`.
345impl Default for Set<'_> {
346    fn default() -> Self {
347        Set {
348            family: DEFAULT_FAMILY,
349            table: DEFAULT_TABLE.into(),
350            name: "myset".into(),
351            handle: None,
352            set_type: SetTypeValue::Single(SetType::Ipv4Addr),
353            policy: None,
354            flags: None,
355            elem: None,
356            timeout: None,
357            gc_interval: None,
358            size: None,
359            comment: None,
360        }
361    }
362}
363
364#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize, JsonSchema)]
365/// Named map that holds expression elements.
366/// Maps are a special form of sets in that they translate a unique key to a value.
367pub struct Map<'a> {
368    /// The table’s family.
369    pub family: NfFamily,
370    /// The table’s name.
371    pub table: Cow<'a, str>,
372    /// The map’s name.
373    pub name: Cow<'a, str>,
374    #[serde(skip_serializing_if = "Option::is_none")]
375    /// The map’s handle. For input, it is used by the [delete command](NfCmd::Delete) only.
376    pub handle: Option<u32>,
377    #[serde(rename = "type")]
378    /// The map set’s datatype.
379    ///
380    /// The set type might be a string, such as `"ipv4_addr"`` or an array
381    /// consisting of strings (for concatenated types).
382    pub set_type: SetTypeValue<'a>,
383    /// Type of values this set maps to (i.e. this set is a map).
384    pub map: SetTypeValue<'a>,
385    #[serde(skip_serializing_if = "Option::is_none")]
386    /// The map’s policy.
387    pub policy: Option<SetPolicy>,
388    #[serde(
389        skip_serializing_if = "Option::is_none",
390        deserialize_with = "deserialize_optional_flags",
391        default
392    )]
393    /// The map’s flags.
394    pub flags: Option<HashSet<SetFlag>>,
395    #[serde(skip_serializing_if = "Option::is_none")]
396    /// Initial map set element(s).
397    ///
398    /// A single set element might be given as string, integer or boolean value for simple cases. If additional properties are required, a formal elem object may be used.
399    /// Multiple elements may be given in an array.
400    pub elem: Option<Cow<'a, [Expression<'a>]>>,
401    #[serde(skip_serializing_if = "Option::is_none")]
402    /// Element timeout in seconds.
403    pub timeout: Option<u32>,
404    #[serde(rename = "gc-interval", skip_serializing_if = "Option::is_none")]
405    /// Garbage collector interval in seconds.
406    pub gc_interval: Option<u32>,
407    #[serde(skip_serializing_if = "Option::is_none")]
408    /// Maximum number of elements supported.
409    pub size: Option<u32>,
410    #[serde(skip_serializing_if = "Option::is_none")]
411    /// Optional map comment.
412    ///
413    /// The map/set comment attribute requires at least nftables 0.9.7 and kernel 5.10
414    pub comment: Option<Cow<'a, str>>,
415}
416
417/// Default map "mymap" that maps ipv4addrs.
418impl Default for Map<'_> {
419    fn default() -> Self {
420        Map {
421            family: DEFAULT_FAMILY,
422            table: DEFAULT_TABLE.into(),
423            name: "mymap".into(),
424            handle: None,
425            set_type: SetTypeValue::Single(SetType::Ipv4Addr),
426            map: SetTypeValue::Single(SetType::Ipv4Addr),
427            policy: None,
428            flags: None,
429            elem: None,
430            timeout: None,
431            gc_interval: None,
432            size: None,
433            comment: None,
434        }
435    }
436}
437
438#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize, JsonSchema)]
439#[serde(untagged)]
440/// Wrapper for single or concatenated set types.
441/// The set type might be a string, such as `"ipv4_addr"` or an array consisting of strings (for concatenated types).
442pub enum SetTypeValue<'a> {
443    /// Single set type.
444    Single(SetType),
445    /// Concatenated set types.
446    Concatenated(Cow<'a, [SetType]>),
447}
448
449#[derive(
450    Clone, Copy, Debug, Eq, PartialEq, Hash, Serialize, Deserialize, EnumString, JsonSchema,
451)]
452#[serde(rename_all = "lowercase")]
453/// Describes a set’s datatype.
454pub enum SetType {
455    #[serde(rename = "ipv4_addr")]
456    #[strum(serialize = "ipv4_addr")]
457    /// IPv4 address.
458    Ipv4Addr,
459    #[serde(rename = "ipv6_addr")]
460    #[strum(serialize = "ipv6_addr")]
461    /// IPv6 address.
462    Ipv6Addr,
463    #[serde(rename = "ether_addr")]
464    #[strum(serialize = "ether_addr")]
465    /// Ethernet address.
466    EtherAddr,
467    #[serde(rename = "inet_proto")]
468    #[strum(serialize = "inet_proto")]
469    /// Internet protocol type.
470    InetProto,
471    #[serde(rename = "inet_service")]
472    #[strum(serialize = "inet_service")]
473    /// Internet service.
474    InetService,
475    #[serde(rename = "mark")]
476    #[strum(serialize = "mark")]
477    /// Mark type.
478    Mark,
479    #[serde(rename = "ifname")]
480    #[strum(serialize = "ifname")]
481    /// Network interface name (eth0, eth1..).
482    Ifname,
483}
484
485#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash, Serialize, Deserialize, JsonSchema)]
486#[serde(rename_all = "lowercase")]
487/// Describes a set’s policy.
488pub enum SetPolicy {
489    /// Performance policy (default).
490    Performance,
491    /// Memory policy.
492    Memory,
493}
494
495#[derive(
496    Clone, Copy, Debug, Eq, PartialEq, Serialize, Deserialize, EnumString, Hash, JsonSchema,
497)]
498#[serde(rename_all = "lowercase")]
499#[strum(serialize_all = "lowercase")]
500/// Describes a [set](Set)’s flags.
501pub enum SetFlag {
502    /// Set content may not change while bound.
503    Constant,
504    /// Set contains intervals.
505    Interval,
506    /// Elements can be added with a timeout.
507    Timeout,
508    // TODO: undocumented upstream
509    /// *Undocumented flag.*
510    Dynamic,
511}
512
513#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash, Serialize, Deserialize, JsonSchema)]
514#[serde(rename_all = "lowercase")]
515/// Describes an operator on set.
516pub enum SetOp {
517    /// Operator for adding elements.
518    Add,
519    /// Operator for updating elements.
520    Update,
521}
522
523#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize, JsonSchema)]
524/// Manipulate element(s) in a named set.
525pub struct Element<'a> {
526    /// The table’s family.
527    pub family: NfFamily,
528    /// The table’s name.
529    pub table: Cow<'a, str>,
530    /// The set’s name.
531    pub name: Cow<'a, str>,
532    /// A single set element might be given as string, integer or boolean value for simple cases.
533    /// If additional properties are required, a formal `elem` object may be used.
534    /// Multiple elements may be given in an array.
535    pub elem: Cow<'a, [Expression<'a>]>,
536}
537
538/// Default manipulation element for [set](Set) "myset".
539impl Default for Element<'_> {
540    fn default() -> Self {
541        Element {
542            family: DEFAULT_FAMILY,
543            table: DEFAULT_TABLE.into(),
544            name: "myset".into(),
545            elem: [][..].into(),
546        }
547    }
548}
549
550#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize, JsonSchema)]
551/// [Flowtables] allow you to accelerate packet forwarding in software (and in hardware if your NIC supports it)
552/// by using a conntrack-based network stack bypass.
553///
554/// [Flowtables]: https://wiki.nftables.org/wiki-nftables/index.php/Flowtables
555pub struct FlowTable<'a> {
556    /// The [table](Table)’s family.
557    pub family: NfFamily,
558    /// The [table](Table)’s name.
559    pub table: Cow<'a, str>,
560    /// The flow table’s name.
561    pub name: Cow<'a, str>,
562    #[serde(skip_serializing_if = "Option::is_none")]
563    /// The flow table’s handle. In input, it is used by the [delete command](NfCmd::Delete) only.
564    pub handle: Option<u32>,
565    /// The flow table’s [hook](NfHook).
566    pub hook: Option<NfHook>,
567    /// The flow table's *priority* can be a signed integer or *filter* which stands for 0.
568    /// Addition and subtraction can be used to set relative priority, e.g., filter + 5 is equal to 5.
569    pub prio: Option<u32>,
570    #[serde(
571        default,
572        skip_serializing_if = "Option::is_none",
573        deserialize_with = "single_string_to_option_vec"
574    )]
575    /// The *devices* are specified as iifname(s) of the input interface(s) of the traffic that should be offloaded.
576    ///
577    /// Devices are required for both traffic directions.
578    /// Cow slice of device names, e.g. `vec!["wg0".into(), "wg1".into()].into()`.
579    pub dev: Option<Cow<'a, [Cow<'a, str>]>>,
580}
581
582/// Default [flowtable](FlowTable) named "myflowtable".
583impl Default for FlowTable<'_> {
584    fn default() -> Self {
585        FlowTable {
586            family: DEFAULT_FAMILY,
587            table: DEFAULT_TABLE.into(),
588            name: "myflowtable".into(),
589            handle: None,
590            hook: None,
591            prio: None,
592            dev: None,
593        }
594    }
595}
596
597#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize, JsonSchema)]
598/// This object represents a named [counter].
599///
600/// A counter counts both the total number of packets and the total bytes it has seen since it was last reset.
601/// With nftables you need to explicitly specify a counter for each rule you want to count.
602///
603/// [counter]: https://wiki.nftables.org/wiki-nftables/index.php/Counters
604pub struct Counter<'a> {
605    /// The [table](Table)’s family.
606    pub family: NfFamily,
607    /// The [table](Table)’s name.
608    pub table: Cow<'a, str>,
609    /// The counter’s name.
610    pub name: Cow<'a, str>,
611    #[serde(skip_serializing_if = "Option::is_none")]
612    /// The counter’s handle. In input, it is used by the [delete command](NfCmd::Delete) only.
613    pub handle: Option<u32>,
614    #[serde(skip_serializing_if = "Option::is_none")]
615    /// Packet counter value.
616    pub packets: Option<u32>,
617    /// Byte counter value.
618    pub bytes: Option<u32>,
619}
620
621/// Default [counter](Counter) named "mycounter".
622impl Default for Counter<'_> {
623    fn default() -> Self {
624        Counter {
625            family: DEFAULT_FAMILY,
626            table: DEFAULT_TABLE.into(),
627            name: "mycounter".into(),
628            handle: None,
629            packets: None,
630            bytes: None,
631        }
632    }
633}
634
635#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize, JsonSchema)]
636/// This object represents a named [quota](Quota).
637///
638/// A quota:
639/// * defines a threshold number of bytes;
640/// * sets an initial byte count (defaults to 0 bytes if not specified);
641/// * counts the total number of bytes, starting from the initial count; and
642/// * matches either:
643///     * only until the byte count exceeds the threshold, or
644///     * only after the byte count is over the threshold.
645///
646/// (Quota): <https://wiki.nftables.org/wiki-nftables/index.php/Quotas>
647pub struct Quota<'a> {
648    /// The [table](Table)’s family.
649    pub family: NfFamily,
650    /// The [table](Table)’s name.
651    pub table: Cow<'a, str>,
652    /// The quota’s name.
653    pub name: Cow<'a, str>,
654    #[serde(skip_serializing_if = "Option::is_none")]
655    /// The quota’s handle. In input, it is used by the [delete command](NfCmd::Delete) only.
656    pub handle: Option<u32>,
657    #[serde(skip_serializing_if = "Option::is_none")]
658    /// Quota threshold.
659    pub bytes: Option<u32>,
660    #[serde(skip_serializing_if = "Option::is_none")]
661    /// Quota used so far.
662    pub used: Option<u32>,
663    #[serde(skip_serializing_if = "Option::is_none")]
664    /// If `true`, match if the quota has been exceeded (i.e., "invert" the quota).
665    pub inv: Option<bool>,
666}
667
668/// Default [quota](Quota) named "myquota".
669impl Default for Quota<'_> {
670    fn default() -> Self {
671        Quota {
672            family: DEFAULT_FAMILY,
673            table: DEFAULT_TABLE.into(),
674            name: "myquota".into(),
675            handle: None,
676            bytes: None,
677            used: None,
678            inv: None,
679        }
680    }
681}
682
683#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize, JsonSchema)]
684#[serde(rename = "ct helper")]
685/// Enable the specified [conntrack helper][Conntrack helpers] for this packet.
686///
687/// [Conntrack helpers]: <https://wiki.nftables.org/wiki-nftables/index.php/Conntrack_helpers>
688pub struct CTHelper<'a> {
689    /// The [table](Table)’s family.
690    pub family: NfFamily,
691    /// The [table](Table)’s name.
692    pub table: Cow<'a, str>,
693    /// The ct helper’s name.
694    pub name: Cow<'a, str>,
695    #[serde(skip_serializing_if = "Option::is_none")]
696    /// The ct helper’s handle. In input, it is used by the [delete command](NfCmd::Delete) only.
697    pub handle: Option<u32>,
698    #[serde(rename = "type")]
699    /// The ct helper type name, e.g. "ftp" or "tftp".
700    pub _type: Cow<'a, str>,
701    #[serde(skip_serializing_if = "Option::is_none")]
702    /// The ct helper’s layer 4 protocol.
703    pub protocol: Option<Cow<'a, str>>,
704    #[serde(skip_serializing_if = "Option::is_none")]
705    /// The ct helper’s layer 3 protocol, e.g. "ip" or "ip6".
706    pub l3proto: Option<Cow<'a, str>>,
707}
708
709/// Default ftp [ct helper](CTHelper) named "mycthelper".
710impl Default for CTHelper<'_> {
711    fn default() -> Self {
712        CTHelper {
713            family: DEFAULT_FAMILY,
714            table: DEFAULT_TABLE.into(),
715            name: "mycthelper".into(),
716            handle: None,
717            _type: "ftp".into(),
718            protocol: None,
719            l3proto: None,
720        }
721    }
722}
723
724#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize, JsonSchema)]
725/// This object represents a named [limit](Limit).
726///
727/// A limit uses a [token bucket](Token bucket) filter to match packets:
728/// * only until its rate is exceeded; or
729/// * only after its rate is exceeded, if defined as an over limit.
730///
731/// (Limit): <https://wiki.nftables.org/wiki-nftables/index.php/Limits>
732/// (Token bucket): <https://en.wikipedia.org/wiki/Token_bucket>
733pub struct Limit<'a> {
734    /// The [table](Table)’s family.
735    pub family: NfFamily,
736    /// The [table](Table)’s name.
737    pub table: Cow<'a, str>,
738    /// The limit’s name.
739    pub name: Cow<'a, str>,
740    #[serde(skip_serializing_if = "Option::is_none")]
741    /// The limit’s handle. In input, it is used by the [delete command](NfCmd::Delete) only.
742    pub handle: Option<u32>,
743    #[serde(skip_serializing_if = "Option::is_none")]
744    /// The limit’s rate value.
745    pub rate: Option<u32>,
746    #[serde(skip_serializing_if = "Option::is_none")]
747    /// Time unit to apply the limit to, e.g. "week", "day", "hour", etc.
748    ///
749    /// If omitted, defaults to "second".
750    pub per: Option<NfTimeUnit>,
751    #[serde(skip_serializing_if = "Option::is_none")]
752    /// The limit’s burst value. If omitted, defaults to 0.
753    pub burst: Option<u32>,
754    #[serde(skip_serializing_if = "Option::is_none")]
755    /// [Unit](LimitUnit) of rate and burst values. If omitted, defaults to "packets".
756    pub unit: Option<LimitUnit>,
757    /// If `true`, match if limit was exceeded. If omitted, defaults to `false`.
758    pub inv: Option<bool>,
759}
760
761/// Default [limit](Limit) named "mylimit".
762impl Default for Limit<'_> {
763    fn default() -> Self {
764        Limit {
765            family: DEFAULT_FAMILY,
766            table: DEFAULT_TABLE.into(),
767            name: "mylimit".into(),
768            handle: None,
769            rate: None,
770            per: None,
771            burst: None,
772            unit: None,
773            inv: None,
774        }
775    }
776}
777
778#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash, Serialize, Deserialize, JsonSchema)]
779#[serde(rename_all = "lowercase")]
780/// A unit used in [limits](Limit).
781pub enum LimitUnit {
782    /// Limit by number of packets.
783    Packets,
784    /// Limit by number of bytes.
785    Bytes,
786}
787
788#[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize, JsonSchema)]
789pub struct Meter<'a> {
790    pub name: Cow<'a, str>,
791    pub key: Expression<'a>,
792    pub stmt: Box<Statement<'a>>,
793}
794
795#[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize, JsonSchema)]
796/// Represents the live ruleset (to be [flushed](NfCmd::Flush)).
797pub struct Ruleset {}
798
799/// Default ruleset.
800impl Default for Ruleset {
801    fn default() -> Self {
802        Ruleset {}
803    }
804}
805
806#[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize, JsonSchema)]
807/// Library information in output.
808///
809/// In output, the first object in an nftables array is a special one containing library information.
810pub struct MetainfoObject<'a> {
811    #[serde(skip_serializing_if = "Option::is_none")]
812    /// The value of version property is equal to the package version as printed by `nft -v`.
813    pub version: Option<Cow<'a, str>>,
814    /// The value of release_name property is equal to the release name as printed by `nft -v`.
815    #[serde(skip_serializing_if = "Option::is_none")]
816    pub release_name: Option<Cow<'a, str>>,
817    #[serde(skip_serializing_if = "Option::is_none")]
818    /// The JSON Schema version.
819    ///
820    /// If supplied in (libnftables) library input, the parser will verify the
821    /// `json_schema_version` value to not exceed the internally hardcoded one
822    /// (to make sure the given schema is fully understood).
823    /// In future, a lower number than the internal one may activate
824    /// compatibility mode to parse outdated and incompatible JSON input.
825    pub json_schema_version: Option<u32>,
826}
827
828/// Default (empty) [metainfo object](MetainfoObject).
829impl Default for MetainfoObject<'_> {
830    fn default() -> Self {
831        MetainfoObject {
832            version: None,
833            release_name: None,
834            json_schema_version: None,
835        }
836    }
837}
838
839#[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize, JsonSchema)]
840/// This object represents a named [conntrack timeout][Ct timeout] policy.
841///
842/// You can use a ct timeout object to specify a connection tracking timeout policy for a particular flow.
843///
844/// [Ct timeout]: <https://wiki.nftables.org/wiki-nftables/index.php/Ct_timeout>
845pub struct CTTimeout<'a> {
846    /// The table’s family.
847    pub family: NfFamily,
848    /// The table’s name.
849    pub table: Cow<'a, str>,
850    /// The ct timeout object’s name.
851    pub name: Cow<'a, str>,
852    #[serde(skip_serializing_if = "Option::is_none")]
853    /// The ct timeout object’s handle. In input, it is used by the [delete command](NfCmd::Delete) only.
854    pub handle: Option<u32>,
855    #[serde(skip_serializing_if = "Option::is_none")]
856    /// The ct timeout object’s [layer 4 protocol](CTHProto).
857    pub protocol: Option<CTHProto>,
858    #[serde(skip_serializing_if = "Option::is_none")]
859    /// The connection state name, e.g. "established", "syn_sent", "close" or "close_wait", for which the timeout value has to be updated.
860    pub state: Option<Cow<'a, str>>,
861    #[serde(skip_serializing_if = "Option::is_none")]
862    /// The updated timeout value for the specified connection state.
863    pub value: Option<u32>,
864    #[serde(skip_serializing_if = "Option::is_none")]
865    /// The ct timeout object’s layer 3 protocol, e.g. "ip" or "ip6".
866    pub l3proto: Option<Cow<'a, str>>,
867}
868
869/// Default [ct timeout](CTTimeout) named "mycttimeout"
870impl Default for CTTimeout<'_> {
871    fn default() -> Self {
872        CTTimeout {
873            family: DEFAULT_FAMILY,
874            table: DEFAULT_TABLE.into(),
875            name: "mycttimeout".into(),
876            handle: None,
877            protocol: None,
878            state: None,
879            value: None,
880            l3proto: None,
881        }
882    }
883}
884
885#[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize, JsonSchema)]
886/// This object represents a named [conntrack expectation][Ct expectation].
887///
888/// [Ct expectation]: <https://wiki.nftables.org/wiki-nftables/index.php/Ct_expectation>
889pub struct CTExpectation<'a> {
890    /// The table’s family.
891    pub family: NfFamily,
892    /// The table’s name.
893    pub table: Cow<'a, str>,
894    /// The ct expectation object’s name.
895    pub name: Cow<'a, str>,
896    #[serde(skip_serializing_if = "Option::is_none")]
897    /// The ct expectation object’s handle. In input, it is used by delete command only.
898    pub handle: Option<u32>,
899    #[serde(skip_serializing_if = "Option::is_none")]
900    /// The ct expectation object’s layer 3 protocol, e.g. "ip" or "ip6".
901    pub l3proto: Option<Cow<'a, str>>,
902    #[serde(skip_serializing_if = "Option::is_none")]
903    /// The ct expectation object’s layer 4 protocol.
904    pub protocol: Option<CTHProto>,
905    #[serde(skip_serializing_if = "Option::is_none")]
906    /// The destination port of the expected connection.
907    pub dport: Option<u32>,
908    #[serde(skip_serializing_if = "Option::is_none")]
909    /// The time in millisecond that this expectation will live.
910    pub timeout: Option<u32>,
911    #[serde(skip_serializing_if = "Option::is_none")]
912    /// The maximum count of expectations to be living in the same time.
913    pub size: Option<u32>,
914}
915
916/// [SynProxy] intercepts new TCP connections and handles the initial 3-way handshake using
917/// syncookies instead of conntrack to establish the connection.
918///
919/// Named SynProxy requires **nftables 0.9.3 or newer**.
920///
921/// [SynProxy]: https://wiki.nftables.org/wiki-nftables/index.php/Synproxy
922#[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize, JsonSchema)]
923pub struct SynProxy<'a> {
924    /// The table’s family.
925    pub family: NfFamily,
926    /// The table’s name.
927    pub table: Cow<'a, str>,
928    /// The synproxy's name.
929    pub name: Cow<'a, str>,
930    #[serde(skip_serializing_if = "Option::is_none")]
931    /// The synproxy's handle. For input, it is used by the [delete command](NfCmd::Delete) only.
932    pub handle: Option<u32>,
933    #[serde(skip_serializing_if = "Option::is_none")]
934    /// The maximum segment size (must match your backend server).
935    pub mss: Option<u16>,
936    #[serde(skip_serializing_if = "Option::is_none")]
937    /// The window scale (must match your backend server).
938    pub wscale: Option<u8>,
939    #[serde(
940        skip_serializing_if = "Option::is_none",
941        deserialize_with = "deserialize_optional_flags",
942        default
943    )]
944    /// The synproxy's [flags](crate::types::SynProxyFlag).
945    pub flags: Option<HashSet<SynProxyFlag>>,
946}