nftables_json/
lib.rs

1// Copyright (c) nftables-json Developers
2// SPDX-License-Identifier: MIT OR Apache-2.0
3
4//! Serde JSON model for interacting with the nftables `nft` executable
5//!
6//! Provides Rust types that map directly to the nftables JSON object model,
7//! allowing serialization and deserialization of input and output from the
8//! `nft --json` command using [Serde](https://crates.io/crates/serde) and
9//! [`serde_json`](https://crates.io/crates/serde_json).
10//!
11//! # Example
12//!
13//! Creating commands that can be piped into `nft --json --file -`
14//!
15//! ```rust
16//! use nftables_json::{command::*, expression::*, statement::*};
17//!
18//! let mut commands = Commands::default();
19//! commands.extend([
20//!     // flush rulesets for all families
21//!     Command::Flush(Flush::Ruleset(None)),
22//!     // create a new table called "default"
23//!     Command::Add(Add::Table(AddTable {
24//!         family: "inet".into(),
25//!         name: "default".into(),
26//!         ..AddTable::default()
27//!     })),
28//!     // attach a chain to the "default" table called "input"
29//!     Command::Add(Add::Chain(AddChain {
30//!         family: "inet".into(),
31//!         table: "default".into(),
32//!         name: "input".into(),
33//!         r#type: Some("filter".into()),
34//!         hook: Some("input".into()),
35//!         prio: Some(0),
36//!         policy: Some("accept".into()),
37//!         ..AddChain::default()
38//!     })),
39//!     Command::Add(Add::Rule(AddRule {
40//!         // attach a rule to the "input" chain in the "default" table that drops udp sport 53
41//!         family: "inet".into(),
42//!         table: "default".into(),
43//!         chain: "input".into(),
44//!         expr: Some(vec![
45//!             Statement::Match(Match {
46//!                 left: Expression::Payload {
47//!                     payload: Payload::Named { protocol: "udp".into(), field: "sport".into() },
48//!                 }
49//!                 .into(),
50//!                 right: Expression::Immediate(Immediate::Number(53)).into(),
51//!                 op: "==".into(),
52//!             }),
53//!             Statement::Drop(()),
54//!         ]),
55//!         ..AddRule::default()
56//!     })),
57//! ]);
58//!
59//! // not shown: how to invoke `nft` from Rust and pipe json to stdin
60//! println!("{}", commands.to_string().unwrap());
61//!
62//! /*
63//! {"nftables":[
64//!   {"flush":{"ruleset":null}},
65//!   {"add":{"table":{"family":"inet","name":"default"}}},
66//!   {"add":{"chain":{"family":"inet","table":"default","name":"input","policy":"accept","type":"filter","hook":"input","prio":0}}},
67//!   {"add":{"rule":{"family":"inet","table":"default","chain":"input","expr":[
68//!     {"match":{"left":{"payload":{"protocol":"udp","field":"sport"}},"right":53,"op":"=="}},
69//!     {"drop":null}
70//!   ]}}}
71//! ]}
72//! */
73//! ```
74//!
75//! # Example
76//!
77//! Parsing a ruleset produced by
78//! `printf '{"nftables":[{"list":{"ruleset":null}}]}' | nft --json --file -`
79//!
80//! ```rust
81//! use nftables_json::{object::*, expression::*, statement::*};
82//!
83//! // not shown: how to invoke `nft` from Rust and collect stdout
84//! let output_str = r#"
85//! {"nftables":[
86//!   {"metainfo":{"version":"0.9.8","release_name":"E.D.S.","json_schema_version":1}},
87//!   {"table":{"family":"inet","name":"default","handle":3}},
88//!   {"chain":{"family":"inet","table":"default","name":"input","handle":1,"type":"filter","hook":"input","prio":0,"policy":"accept"}},
89//!   {"rule":{"family":"inet","table":"default","chain":"input","handle":3,"expr":[
90//!     {"match":{"op":"==","left":{"payload":{"protocol":"udp","field":"sport"}},"right":53}},
91//!     {"drop":null}
92//!   ]}},
93//!   {"chain":{"family":"inet","table":"default","name":"output","handle":2,"type":"filter","hook":"output","prio":0,"policy":"accept"}}
94//! ]}
95//! "#;
96//!
97//! let objects = Objects::from_str(output_str).unwrap();
98//!
99//! for object in objects.iter() {
100//!     match object {
101//!         Object::Metainfo(Metainfo { json_schema_version, .. }) => {
102//!             eprintln!("[metainfo] schema version {json_schema_version}");
103//!         }
104//!         Object::Table(Table { family, name, .. }) => {
105//!             eprintln!("[table] {family} {name}");
106//!         }
107//!         Object::Chain(Chain { family, table, name, hook: Some(hook), .. }) => {
108//!             eprintln!("[chain] {family} {table} {name} hook {hook}");
109//!         }
110//!         Object::Rule(Rule { family, table, chain, .. }) => {
111//!             eprintln!("[rule] {family} {table} {chain}");
112//!         }
113//!         _ => {}
114//!     }
115//! }
116//!
117//! /*
118//! schema version 1
119//! table family inet name default
120//! chain family inet table default name input hook input
121//! rule family inet table default chain input
122//! chain family inet table default name output hook output
123//! */
124//! ```
125
126pub mod command;
127pub mod expression;
128pub mod object;
129pub mod statement;