diff --git a/src/schema.rs b/src/schema.rs index 212e5e3..0beed2e 100644 --- a/src/schema.rs +++ b/src/schema.rs @@ -42,6 +42,7 @@ pub enum NfListObject { CTTimeout(CTTimeout), #[serde(rename = "ct expectation")] CTExpectation(CTExpectation), + SynProxy(SynProxy), } #[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)] @@ -449,3 +450,31 @@ pub struct CTExpectation { #[serde(skip_serializing_if = "Option::is_none")] pub size: Option, } + +/// [SynProxy] intercepts new TCP connections and handles the initial 3-way handshake using +/// syncookies instead of conntrack to establish the connection. +/// +/// Named SynProxy requires **nftables 0.9.3 or newer**. +/// +/// [SynProxy]: https://wiki.nftables.org/wiki-nftables/index.php/Synproxy +#[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize)] +pub struct SynProxy { + /// The table’s family. + pub family: NfFamily, + /// The table’s name. + pub table: String, + /// The synproxy's name. + pub name: String, + #[serde(skip_serializing_if = "Option::is_none")] + /// The synproxy's handle. For input, it is used by the [delete command][NfCmd::Delete] only. + pub handle: Option, + #[serde(skip_serializing_if = "Option::is_none")] + /// The maximum segment size (must match your backend server). + pub mss: Option, + #[serde(skip_serializing_if = "Option::is_none")] + /// The window scale (must match your backend server). + pub wscale: Option, + #[serde(skip_serializing_if = "Option::is_none")] + /// The synproxy's [flags][crate::types::SynProxyFlag]. + pub flags: Option>, +} diff --git a/src/stmt.rs b/src/stmt.rs index 5845c56..c0d8f63 100644 --- a/src/stmt.rs +++ b/src/stmt.rs @@ -4,7 +4,7 @@ use serde::{Deserialize, Serialize}; use strum_macros::EnumString; -use crate::types::RejectCode; +use crate::types::{RejectCode, SynProxyFlag}; use crate::visitor::single_string_to_option_hashset_logflag; use crate::expr::Expression; @@ -36,6 +36,7 @@ pub enum Statement { #[serde(rename = "quota")] /// reference to a named quota object QuotaRef(String), + // TODO: last Limit(Limit), /// The Flow statement offloads matching network traffic to flowtables, @@ -51,6 +52,7 @@ pub enum Statement { Redirect(Option), // redirect is subset of NAT options Reject(Option), Set(Set), + // TODO: map Log(Option), #[serde(rename = "ct helper")] @@ -60,6 +62,7 @@ pub enum Statement { Meter(Meter), Queue(Queue), #[serde(rename = "vmap")] + // TODO: vmap is expr, not stmt! VerdictMap(VerdictMap), #[serde(rename = "ct count")] @@ -76,9 +79,12 @@ pub enum Statement { /// This represents an xt statement from xtables compat interface. /// Sadly, at this point, it is not possible to provide any further information about its content. XT(Option), - + /// A netfilter synproxy intercepts new TCP connections and handles the initial 3-way handshake using syncookies instead of conntrack to establish the connection. + SynProxy(SynProxy), /// Redirects the packet to a local socket without changing the packet header in any way. TProxy(TProxy), + // TODO: reset + // TODO: secmark } #[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize)] @@ -444,6 +450,22 @@ pub struct CTCount { pub inv: Option, } +#[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize)] +/// Limit the number of connections using conntrack. +/// +/// Anonymous synproxy was requires **nftables 0.9.2 or newer**. +pub struct SynProxy { + #[serde(skip_serializing_if = "Option::is_none")] + /// maximum segment size (must match your backend server) + pub mss: Option, + #[serde(skip_serializing_if = "Option::is_none")] + /// window scale (must match your backend server) + pub wscale: Option, + #[serde(skip_serializing_if = "Option::is_none")] + /// The synproxy's [flags][crate::types::SynProxyFlag]. + pub flags: Option>, +} + #[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize)] #[serde(rename_all = "lowercase")] /// Redirects the packet to a local socket without changing the packet header in any way. diff --git a/src/types.rs b/src/types.rs index 74a08ad..1b75b05 100644 --- a/src/types.rs +++ b/src/types.rs @@ -90,3 +90,14 @@ pub enum RejectCode { /// Address unreachable (ICMPv6) AddrUnreach, } + +#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize, Hash)] +#[serde(rename_all = "lowercase")] +/// Describes a SynProxy's flags. +pub enum SynProxyFlag { + /// Pass client timestamp option to backend. + Timestamp, + #[serde(rename = "sack-perm")] + /// Pass client selective acknowledgement option to backend. + SackPerm, +}