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;