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}