nftables/expr.rs
1use schemars::JsonSchema;
2use serde::{Deserialize, Serialize};
3use std::{borrow::Cow, collections::HashSet};
4
5use crate::stmt::{Counter, JumpTarget, Statement};
6use crate::visitor::deserialize_flags;
7use strum_macros::EnumString;
8
9#[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize, JsonSchema)]
10#[serde(untagged)]
11/// Expressions are the building blocks of (most) [statements](crate::stmt::Statement).
12/// In their most basic form, they are just immediate values represented as a
13/// JSON string, integer or boolean type.
14pub enum Expression<'a> {
15 // immediates
16 /// A string expression (*immediate expression*).
17 /// For string expressions there are two special cases:
18 /// * `@STRING`: The remaining part is taken as [set](crate::schema::Set)
19 /// name to create a set reference.
20 /// * `\*`: Construct a wildcard expression.
21 String(Cow<'a, str>),
22 /// An integer expression (*immediate expression*).
23 Number(u32),
24 /// A boolean expression (*immediate expression*).
25 Boolean(bool),
26 /// List expressions are constructed by plain arrays containing of an arbitrary number of expressions.
27 List(Vec<Expression<'a>>),
28 /// A [binary operation](BinaryOperation) expression.
29 BinaryOperation(Box<BinaryOperation<'a>>),
30 /// Construct a range of values.
31 ///
32 /// The first array item denotes the lower boundary, the second one the upper boundary.
33 Range(Box<Range<'a>>),
34
35 /// Wrapper for non-immediate expressions.
36 Named(NamedExpression<'a>),
37 /// A verdict expression (used in [verdict maps](crate::stmt::VerdictMap)).
38 Verdict(Verdict<'a>),
39}
40
41#[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize, JsonSchema)]
42#[serde(rename_all = "lowercase")]
43/// Wrapper for non-immediate [Expressions](Expression).
44pub enum NamedExpression<'a> {
45 /// Concatenate several expressions.
46 Concat(Vec<Expression<'a>>),
47 /// This object constructs an anonymous set with [items](SetItem).
48 /// For mappings, an array of arrays with exactly two elements is expected.
49 Set(Vec<SetItem<'a>>),
50 /// Map a key to a value.
51 Map(Box<Map<'a>>),
52 /// Construct an IPv4 or IPv6 [prefix](Prefix) consisting of address part and prefix length.
53 Prefix(Prefix<'a>),
54
55 /// Construct a [payload](Payload) expression, i.e. a reference to a certain part of packet data.
56 Payload(Payload<'a>),
57
58 /// Create a reference to a field in an IPv6 extension header.
59 Exthdr(Exthdr<'a>),
60 #[serde(rename = "tcp option")]
61 /// Create a reference to a field of a TCP option header.
62 TcpOption(TcpOption<'a>),
63 #[serde(rename = "sctp chunk")]
64 /// Create a reference to a field of an SCTP chunk.
65 SctpChunk(SctpChunk<'a>),
66 // TODO: DCCP Option
67 /// Create a reference to packet meta data.
68 Meta(Meta),
69 /// Create a reference to packet routing data.
70 RT(RT),
71 /// Create a reference to packet conntrack data.
72 CT(CT<'a>),
73 /// Create a number generator.
74 Numgen(Numgen),
75 /// Hash packet data (Jenkins Hash).
76 JHash(JHash<'a>),
77 /// Hash packet data (Symmetric Hash).
78 SymHash(SymHash),
79
80 /// Perform kernel Forwarding Information Base lookups.
81 Fib(Fib),
82 /// Explicitly set element object, in case `timeout`, `expires`, or `comment`
83 /// are desired.
84 Elem(Elem<'a>),
85 /// Construct a reference to a packet’s socket.
86 Socket(Socket<'a>),
87 /// Perform OS fingerprinting.
88 ///
89 /// This expression is typically used in the [LHS](crate::stmt::Match::left)
90 /// of a [match](crate::stmt::Match) statement.
91 Osf(Osf<'a>),
92}
93
94#[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize, JsonSchema)]
95#[serde(rename = "map")]
96/// Map a key to a value.
97pub struct Map<'a> {
98 /// Map key.
99 pub key: Expression<'a>,
100 /// Mapping expression consisting of value/target pairs.
101 pub data: Expression<'a>,
102}
103
104/// Default map expression (`true -> false`).
105impl Default for Map<'_> {
106 fn default() -> Self {
107 Map {
108 key: Expression::Boolean(true),
109 data: Expression::Boolean(false),
110 }
111 }
112}
113
114#[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize, JsonSchema)]
115#[serde(untagged)]
116/// Item in an anonymous set.
117pub enum SetItem<'a> {
118 /// A set item containing a single expression.
119 Element(Expression<'a>),
120 /// A set item mapping two expressions.
121 Mapping(Expression<'a>, Expression<'a>),
122 /// A set item mapping an expression to a statement.
123 MappingStatement(Expression<'a>, Statement<'a>),
124}
125
126#[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize, JsonSchema)]
127#[serde(rename = "prefix")]
128/// Construct an IPv4 or IPv6 prefix consisting of address part in
129/// [addr](Prefix::addr) and prefix length in [len](Prefix::len).
130pub struct Prefix<'a> {
131 /// An IPv4 or IPv6 address.
132 pub addr: Box<Expression<'a>>,
133 /// The prefix length.
134 pub len: u32,
135}
136
137#[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize, JsonSchema)]
138#[serde(rename = "range")]
139/// Construct a range of values.
140/// The first array item denotes the lower boundary, the second one the upper
141/// boundary.
142pub struct Range<'a> {
143 /// The range boundaries.
144 ///
145 /// The first array item denotes the lower boundary, the second one the
146 /// upper boundary.
147 pub range: [Expression<'a>; 2],
148}
149
150#[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize, JsonSchema)]
151#[serde(untagged)]
152/// Construct a payload expression, i.e. a reference to a certain part of packet
153/// data.
154pub enum Payload<'a> {
155 /// Allows one to reference a field by name in a named packet header.
156 PayloadField(PayloadField<'a>),
157 /// Creates a raw payload expression to point at a random number of bits at
158 /// a certain offset from a given reference point.
159 PayloadRaw(PayloadRaw),
160}
161
162#[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize, JsonSchema)]
163/// Creates a raw payload expression to point at a random number
164/// ([len](PayloadRaw::len)) of bits at a certain offset
165/// ([offset](PayloadRaw::offset)) from a given reference point
166/// ([base](PayloadRaw::base)).
167pub struct PayloadRaw {
168 /// The (protocol layer) reference point.
169 pub base: PayloadBase,
170 /// Offset from the reference point in bits.
171 pub offset: u32,
172 /// Number of bits.
173 pub len: u32,
174}
175
176/// Default raw payload expression (0-length at link layer).
177impl Default for PayloadRaw {
178 fn default() -> Self {
179 PayloadRaw {
180 base: PayloadBase::LL,
181 offset: 0,
182 len: 0,
183 }
184 }
185}
186
187#[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize, JsonSchema)]
188/// Construct a payload expression, i.e. a reference to a certain part of packet
189/// data.
190///
191/// Allows to reference a field by name ([field](PayloadField::field)) in a
192/// named packet header ([protocol](PayloadField::protocol)).
193pub struct PayloadField<'a> {
194 /// A named packet header.
195 pub protocol: Cow<'a, str>,
196 /// The field name.
197 pub field: Cow<'a, str>,
198}
199
200/// Default payload field reference (`arp ptype`).
201impl Default for PayloadField<'_> {
202 fn default() -> Self {
203 PayloadField {
204 protocol: "arp".into(),
205 field: "ptype".into(),
206 }
207 }
208}
209
210#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash, Serialize, Deserialize, JsonSchema)]
211#[serde(rename_all = "lowercase")]
212/// Represents a protocol layer for [payload](Payload) references.
213pub enum PayloadBase {
214 /// Link layer, for example the Ethernet header.
215 LL,
216 /// Network header, for example IPv4 or IPv6.
217 NH,
218 /// Transport Header, for example TCP.
219 ///
220 /// *Added in nftables 0.9.2 and Linux kernel 5.3.*
221 TH,
222 /// Inner Header / Payload, i.e. after the L4 transport level header.
223 ///
224 /// *Added in Kernel version 6.2.*
225 IH,
226}
227
228#[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize, JsonSchema)]
229#[serde(rename = "exthdr")]
230/// Create a reference to a field ([field](Exthdr::field)) in an IPv6 extension
231/// header ([name](Exthdr::name)).
232///
233/// [offset](Exthdr::offset) is used only for `rt0` protocol.
234pub struct Exthdr<'a> {
235 /// The IPv6 extension header name.
236 pub name: Cow<'a, str>,
237 /// The field name.
238 ///
239 /// If the [field][Exthdr::field] property is not given, the expression is
240 /// to be used as a header existence check in a [match](crate::stmt::Match)
241 /// statement with a [boolean](Expression::Boolean) on the
242 /// [right](crate::stmt::Match::right) hand side.
243 pub field: Option<Cow<'a, str>>,
244 /// The offset length. Used only for `rt0` protocol.
245 pub offset: Option<u32>,
246}
247
248/// Default [Exthdr] for `frag` extension header.
249impl Default for Exthdr<'_> {
250 fn default() -> Self {
251 Exthdr {
252 name: "frag".into(),
253 field: None,
254 offset: None,
255 }
256 }
257}
258
259#[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize, JsonSchema)]
260#[serde(rename = "tcp option")]
261/// Create a reference to a field ([field](TcpOption::field)) of a TCP option
262/// header ([name](TcpOption::field)).
263pub struct TcpOption<'a> {
264 /// The TCP option header name.
265 pub name: Cow<'a, str>,
266 /// The field name.
267 ///
268 /// If the field property is not given, the expression is to be used as a
269 /// TCP option existence check in a [match](crate::stmt::Match)
270 /// statement with a [boolean](Expression::Boolean) on the
271 /// [right](crate::stmt::Match::right) hand side.
272 pub field: Option<Cow<'a, str>>,
273}
274
275/// Default TCP option for `maxseg` option.
276impl Default for TcpOption<'_> {
277 fn default() -> Self {
278 TcpOption {
279 name: "maxseg".into(),
280 field: None,
281 }
282 }
283}
284
285#[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize, JsonSchema)]
286#[serde(rename = "sctp chunk")]
287/// Create a reference to a field ([field](SctpChunk::field)) of an SCTP chunk
288/// ((name)[SctpChunk::name]).
289pub struct SctpChunk<'a> {
290 /// The SCTP chunk name.
291 pub name: Cow<'a, str>,
292 /// The field name.
293 ///
294 /// If the field property is not given, the expression is to be used as an
295 /// SCTP chunk existence check in a [match](crate::stmt::Match) statement
296 /// with a [boolean](Expression::Boolean) on the
297 /// [right](crate::stmt::Match::right) hand side.
298 pub field: Cow<'a, str>,
299}
300
301#[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize, JsonSchema)]
302#[serde(rename = "meta")]
303/// Create a reference to packet meta data.
304///
305/// See [this page](https://wiki.nftables.org/wiki-nftables/index.php/Matching_packet_metainformation)
306/// for more information.
307pub struct Meta {
308 /// The packet [meta data key](MetaKey).
309 pub key: MetaKey,
310}
311
312/// Default impl for meta key `l4proto`.
313impl Default for Meta {
314 fn default() -> Self {
315 Meta {
316 key: MetaKey::L4proto,
317 }
318 }
319}
320
321#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash, Serialize, Deserialize, JsonSchema)]
322#[serde(rename_all = "lowercase")]
323/// Represents a `meta` key for packet meta data.
324///
325/// See [this page](https://wiki.nftables.org/wiki-nftables/index.php/Matching_packet_metainformation)
326/// for more information.
327pub enum MetaKey {
328 // matching by packet info:
329 /// Packet type (unicast, broadcast, multicast, other).
330 Pkttype,
331 /// Packet length in bytes.
332 Length,
333 /// Packet protocol / EtherType protocol value.
334 Protocol,
335 /// Netfilter packet protocol family.
336 Nfproto,
337 /// Layer 4 protocol.
338 L4proto,
339
340 // matching by interface:
341 /// Input interface index.
342 Iif,
343 /// Input interface name.
344 Iifname,
345 /// Input interface type.
346 Iiftype,
347 /// Input interface kind name.
348 Iifkind,
349 /// Input interface group.
350 Iifgroup,
351 /// Output interface index.
352 Oif,
353 /// Output interface name.
354 Oifname,
355 /// Output interface type.
356 Oiftype,
357 /// Output interface kind name.
358 Oifkind,
359 /// Output interface group.
360 Oifgroup,
361 /// Input bridge interface name.
362 Ibridgename,
363 /// Output bridge interface name.
364 Obridgename,
365 /// Input bridge interface name
366 Ibriport,
367 /// Output bridge interface name
368 Obriport,
369
370 // matching by packet mark, routing class and realm:
371 /// Packet mark.
372 Mark,
373 /// TC packet priority.
374 Priority,
375 /// Routing realm.
376 Rtclassid,
377
378 // matching by socket uid/gid:
379 /// UID associated with originating socket.
380 Skuid,
381 /// GID associated with originating socket.
382 Skgid,
383
384 // matching by security selectors:
385 /// CPU number processing the packet.
386 Cpu,
387 /// Socket control group ID.
388 Cgroup,
389 /// `true` if packet was ipsec encrypted. (*obsolete*)
390 Secpath,
391
392 // matching by miscellaneous selectors:
393 /// Pseudo-random number.
394 Random,
395 /// [nftrace debugging] bit.
396 ///
397 /// [nftract debugging]: <https://wiki.nftables.org/wiki-nftables/index.php/Ruleset_debug/tracing>
398 Nftrace,
399}
400
401#[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize, JsonSchema)]
402#[serde(rename = "rt")]
403/// Create a reference to packet routing data.
404pub struct RT {
405 /// The routing data key.
406 pub key: RTKey,
407 #[serde(skip_serializing_if = "Option::is_none")]
408 /// The protocol family.
409 ///
410 /// The `family` property is optional and defaults to unspecified.
411 pub family: Option<RTFamily>,
412}
413
414/// Default impl for [RT] with key [nexthop](RTKey::NextHop).
415impl Default for RT {
416 fn default() -> Self {
417 RT {
418 key: RTKey::NextHop,
419 family: None,
420 }
421 }
422}
423
424#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash, Serialize, Deserialize, JsonSchema)]
425#[serde(rename_all = "lowercase")]
426/// Represents a key to reference to packet routing data.
427pub enum RTKey {
428 /// Routing realm.
429 ClassId,
430 /// Routing nexthop.
431 NextHop,
432 /// TCP maximum segment size of route.
433 MTU,
434}
435
436#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash, Serialize, Deserialize, JsonSchema)]
437#[serde(rename_all = "lowercase")]
438/// Represents a protocol family for use by the [rt](RT) expression.
439pub enum RTFamily {
440 /// IPv4 RT protocol family.
441 IP,
442 /// IPv6 RT protocol family.
443 IP6,
444}
445
446#[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize, JsonSchema)]
447#[serde(rename = "ct")]
448/// Create a reference to packet conntrack data.
449pub struct CT<'a> {
450 /// The conntrack expression.
451 ///
452 /// See also: *CONNTRACK EXPRESSIONS* in *ntf(8)*.
453 pub key: Cow<'a, str>,
454 #[serde(skip_serializing_if = "Option::is_none")]
455 /// The [conntrack protocol family](CTFamily).
456 pub family: Option<CTFamily>,
457 #[serde(skip_serializing_if = "Option::is_none")]
458 /// Conntrack flow [direction](CTDir).
459 ///
460 /// Some CT keys do not support a direction.
461 /// In this case, `dir` must not be given.
462 pub dir: Option<CTDir>,
463}
464
465/// Default impl for conntrack with `l3proto` conntrack key.
466impl Default for CT<'_> {
467 fn default() -> Self {
468 CT {
469 key: "l3proto".into(),
470 family: None,
471 dir: None,
472 }
473 }
474}
475
476#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash, Serialize, Deserialize, JsonSchema)]
477#[serde(rename_all = "lowercase")]
478/// Represents a protocol family for use by the [ct](CT) expression.
479pub enum CTFamily {
480 /// IPv4 conntrack protocol family.
481 IP,
482 /// IPv6 conntrack protocol family.
483 IP6,
484}
485
486#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash, Serialize, Deserialize, JsonSchema)]
487#[serde(rename_all = "lowercase")]
488/// Represents a direction for use by the [ct](CT) expression.
489pub enum CTDir {
490 /// Original direction.
491 Original,
492 /// Reply direction.
493 Reply,
494}
495
496#[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize, JsonSchema)]
497#[serde(rename = "numgen")]
498/// Create a number generator.
499pub struct Numgen {
500 /// The [number generator mode](NgMode).
501 pub mode: NgMode,
502 #[serde(rename = "mod")]
503 /// Specifies an upper boundary ("modulus") which is not reached by returned
504 /// numbers.
505 pub ng_mod: u32,
506 #[serde(skip_serializing_if = "Option::is_none")]
507 /// Allows one to increment the returned value by a fixed offset.
508 pub offset: Option<u32>,
509}
510
511/// Default impl for [numgen](Numgen) with mode [inc](NgMode::Inc) and mod `7`.
512impl Default for Numgen {
513 fn default() -> Self {
514 Numgen {
515 mode: NgMode::Inc,
516 ng_mod: 7,
517 offset: None,
518 }
519 }
520}
521
522#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash, Serialize, Deserialize, JsonSchema)]
523#[serde(rename_all = "lowercase")]
524/// Represents a number generator mode.
525pub enum NgMode {
526 /// The last returned value is simply incremented.
527 Inc,
528 /// A new random number is returned.
529 Random,
530}
531
532#[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize, JsonSchema)]
533#[serde(rename = "jhash")]
534/// Hash packet data (Jenkins Hash).
535pub struct JHash<'a> {
536 #[serde(rename = "mod")]
537 /// Specifies an upper boundary ("modulus") which is not reached by returned numbers.
538 pub hash_mod: u32,
539 #[serde(skip_serializing_if = "Option::is_none")]
540 /// Increment the returned value by a fixed offset.
541 pub offset: Option<u32>,
542 /// Determines the parameters of the packet header to apply the hashing,
543 /// concatenations are possible as well.
544 pub expr: Box<Expression<'a>>,
545 #[serde(skip_serializing_if = "Option::is_none")]
546 /// Specify an init value used as seed in the hashing function
547 pub seed: Option<u32>,
548}
549
550/// Default impl for [jhash](JHash).
551impl Default for JHash<'_> {
552 fn default() -> Self {
553 JHash {
554 hash_mod: 7,
555 offset: None,
556 expr: Box::new(Expression::Named(NamedExpression::Payload(
557 Payload::PayloadField(PayloadField {
558 protocol: "ip".into(),
559 field: "saddr".into(),
560 }),
561 ))),
562 seed: None,
563 }
564 }
565}
566
567#[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize, JsonSchema)]
568#[serde(rename = "symhash")]
569/// Hash packet data (Symmetric Hash).
570pub struct SymHash {
571 #[serde(rename = "mod")]
572 /// Specifies an upper boundary ("modulus") which is not reached by returned numbers.
573 pub hash_mod: u32,
574 /// Increment the returned value by a fixed offset.
575 pub offset: Option<u32>,
576}
577
578/// Default impl for [symhash](SymHash).
579impl Default for SymHash {
580 fn default() -> Self {
581 SymHash {
582 hash_mod: 2,
583 offset: None,
584 }
585 }
586}
587
588#[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize, JsonSchema)]
589#[serde(rename = "fib")]
590/// Perform kernel Forwarding Information Base lookups.
591pub struct Fib {
592 /// The data to be queried by fib lookup.
593 pub result: FibResult,
594 #[serde(deserialize_with = "deserialize_flags")]
595 /// The tuple of elements ([FibFlags](FibFlag)) that is used as input to the
596 /// fib lookup functions.
597 pub flags: HashSet<FibFlag>,
598}
599
600/// Default impl for [fib](Fib).
601impl Default for Fib {
602 fn default() -> Self {
603 let mut flags = HashSet::with_capacity(1);
604 flags.insert(FibFlag::Iif);
605 Fib {
606 result: FibResult::Oif,
607 flags,
608 }
609 }
610}
611
612#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash, Serialize, Deserialize, JsonSchema)]
613#[serde(rename_all = "lowercase")]
614/// Represents which data is queried by [fib](Fib) lookup.
615pub enum FibResult {
616 /// Output interface index.
617 Oif,
618 /// Output interface name.
619 Oifname,
620 /// Address type.
621 Type,
622}
623
624#[derive(
625 Debug, Clone, Copy, Eq, PartialEq, Serialize, Deserialize, EnumString, Hash, JsonSchema,
626)]
627#[serde(rename_all = "lowercase")]
628#[strum(serialize_all = "lowercase")]
629/// Represents flags for `fib` lookup.
630pub enum FibFlag {
631 /// Consider the source address of a packet.
632 Saddr,
633 /// Consider the destination address of a packet.
634 Daddr,
635 /// Consider the packet mark.
636 Mark,
637 /// Consider the packet's input interface.
638 Iif,
639 /// Consider the packet's output interface.
640 Oif,
641}
642
643#[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize, JsonSchema)]
644/// Represents a binary operation to be used in an `Expression`.
645pub enum BinaryOperation<'a> {
646 #[serde(rename = "&")]
647 /// Binary AND (`&`)
648 AND(Expression<'a>, Expression<'a>),
649
650 #[serde(rename = "|")]
651 /// Binary OR (`|`)
652 OR(Vec<Expression<'a>>),
653
654 #[serde(rename = "^")]
655 /// Binary XOR (`^`)
656 XOR(Expression<'a>, Expression<'a>),
657
658 #[serde(rename = "<<")]
659 /// Left shift (`<<`)
660 LSHIFT(Expression<'a>, Expression<'a>),
661
662 #[serde(rename = ">>")]
663 /// Right shift (`>>`)
664 RSHIFT(Expression<'a>, Expression<'a>),
665}
666
667#[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize, JsonSchema)]
668#[serde(rename_all = "lowercase")]
669/// A verdict expression (used in [verdict maps](crate::stmt::VerdictMap)).
670///
671/// There are also verdict [statements](crate::stmt::Statement), such as
672/// [accept](crate::stmt::Statement::Accept).
673pub enum Verdict<'a> {
674 /// Terminate ruleset evaluation and accept the packet.
675 ///
676 /// The packet can still be dropped later by another hook, for instance
677 /// accept in the forward hook still allows one to drop the packet later in
678 /// the postrouting hook, or another forward base chain that has a higher
679 /// priority number and is evaluated afterwards in the processing pipeline.
680 Accept,
681 /// Terminate ruleset evaluation and drop the packet.
682 ///
683 /// The drop occurs instantly, no further chains or hooks are evaluated.
684 /// It is not possible to accept the packet in a later chain again, as those
685 /// are not evaluated anymore for the packet.
686 Drop,
687 /// Continue ruleset evaluation with the next rule.
688 ///
689 /// This is the default behaviour in case a rule issues no verdict.
690 Continue,
691 /// Return from the current chain and continue evaluation at the next rule
692 /// in the last chain.
693 ///
694 /// If issued in a base chain, it is equivalent to the base chain policy.
695 Return,
696 /// Continue evaluation at the first rule in chain.
697 ///
698 /// The current position in the ruleset is pushed to a call stack and
699 /// evaluation will continue there when the new chain is entirely evaluated
700 /// or a [return](Verdict::Return) verdict is issued. In case an absolute
701 /// verdict is issued by a rule in the chain, ruleset evaluation terminates
702 /// immediately and the specific action is taken.
703 Jump(JumpTarget<'a>),
704 /// Similar to jump, but the current position is not pushed to the call
705 /// stack.
706 ///
707 /// That means that after the new chain evaluation will continue at the
708 /// last chain instead of the one containing the goto statement.
709 Goto(JumpTarget<'a>),
710}
711
712#[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize, JsonSchema)]
713#[serde(rename = "elem")]
714/// Explicitly set element object.
715///
716/// Element-related commands allow one to change contents of named
717/// [sets](crate::schema::Set) and [maps](crate::schema::Map).
718pub struct Elem<'a> {
719 /// The element value.
720 pub val: Box<Expression<'a>>,
721 /// Timeout value for [sets](crate::schema::Set)/[maps](crate::schema::Map).
722 /// with flag [timeout](crate::schema::SetFlag::Timeout)
723 pub timeout: Option<u32>,
724 /// The time until given element expires, useful for ruleset replication only.
725 pub expires: Option<u32>,
726 /// Per element comment field.
727 pub comment: Option<Cow<'a, str>>,
728 /// Enable a [counter][crate::stmt::Counter] per element.
729 ///
730 /// Added in nftables version *0.9.5*.
731 pub counter: Option<Counter<'a>>,
732}
733
734/// Default impl for [Elem].
735impl Default for Elem<'_> {
736 fn default() -> Self {
737 Elem {
738 val: Box::new(Expression::String("10.2.3.4".into())),
739 timeout: None,
740 expires: None,
741 comment: None,
742 counter: None,
743 }
744 }
745}
746
747#[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize, JsonSchema)]
748#[serde(rename = "socket")]
749/// Construct a reference to packet’s socket.
750pub struct Socket<'a> {
751 /// The socket attribute to match on.
752 pub key: Cow<'a, SocketAttr>,
753}
754
755/// Default impl for [Socket] with [wildcard](SocketAttr::Wildcard) key.
756impl Default for Socket<'_> {
757 fn default() -> Self {
758 Socket {
759 key: Cow::Borrowed(&SocketAttr::Wildcard),
760 }
761 }
762}
763
764#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash, Serialize, Deserialize, JsonSchema)]
765#[serde(rename_all = "lowercase")]
766/// A [socket][Socket] attribute to match on.
767pub enum SocketAttr {
768 /// Match on the `IP_TRANSPARENT` socket option in the found socket.
769 Transparent,
770 /// Match on the socket mark (`SOL_SOCKET`, `SO_MARK`).
771 Mark,
772 /// Indicates whether the socket is wildcard-bound (e.g. 0.0.0.0 or ::0).
773 Wildcard,
774 /// The cgroup version 2 for this socket (path from `/sys/fs/cgroup`).
775 Cgroupv2,
776}
777
778#[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize, JsonSchema)]
779#[serde(rename = "osf")]
780/// Perform OS fingerprinting.
781///
782/// This expression is typically used in the [LHS](crate::stmt::Match::left) of
783/// a [match](crate::stmt::Match) statement.
784pub struct Osf<'a> {
785 /// Name of the OS signature to match.
786 ///
787 /// All signatures can be found at `pf.os` file.
788 /// Use "unknown" for OS signatures that the expression could not detect.
789 pub key: Cow<'a, str>,
790 /// Do TTL checks on the packet to determine the operating system.
791 pub ttl: OsfTtl,
792}
793
794#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash, Serialize, Deserialize, JsonSchema)]
795#[serde(rename_all = "lowercase")]
796/// TTL check mode for [osf](Osf).
797pub enum OsfTtl {
798 /// Check if the IP header's TTL is less than the fingerprint one.
799 ///
800 /// Works for globally-routable addresses.
801 Loose,
802 /// Do not compare the TTL at all.
803 Skip,
804}