tpt-netctl
RustBackend-independent Rust API for Linux dataplane control (filter/NAT/rate-limit) over nftables and eBPF/XDP.
0 stars0 forks0 watchersApache License 2.0
Languages
Rust100.0%
README
tpt-netctl
Backend-independent dataplane control for Linux — nftables and eBPF behind a single stable Rust API.
Overview
tpt-netctl lets consumers apply, validate, and read back filter rules, NAT
rules, rate limits, interface state, and per-rule counters without knowing
which dataplane backend is active.
Crates
| Crate | Description |
|---|---|
tpt-netctl-core | DataplaneBackend trait and shared types |
tpt-netctl-nftables | NftablesBackend — netlink-based nftables implementation |
Usage
use tpt_netctl_core::{
Action, Chain, DataplaneBackend, Matcher, Policy, Rule, Ruleset, RulesetDiff,
};
use tpt_netctl_nftables::NftablesBackend;
fn main() -> Result<(), tpt_netctl_core::NetctlError> {
// Connect (requires CAP_NET_ADMIN on Linux).
let backend = NftablesBackend::connect()?;
// Describe the desired change.
let diff = RulesetDiff {
add: vec![Rule {
id: 1,
description: Some("allow ssh".into()),
matcher: Matcher {
protocol: Some("tcp".into()),
dst_port: Some("22".into()),
..Default::default()
},
action: Action::Accept,
}],
update: vec![],
remove: vec![],
};
// Dry-run: what would change? (no mutation)
let report = backend.validate(&diff)?;
println!("planned: {:?}", report.planned_changes);
// Atomic apply — all-or-nothing.
let applied = backend.apply(&diff)?;
println!("added {} rule(s)", applied.added);
// Read back state and per-rule counters.
let state = backend.read_state()?;
let counters = backend.counters(1)?;
println!(
"installed chains: {}, rule 1 counters: {} pkts / {} bytes",
state.ruleset.chains.len(),
counters.packets,
counters.bytes
);
Ok(())
}
Architecture
A single trait, two backend implementations:
trait DataplaneBackend {
fn validate(&self, diff: &RulesetDiff) -> Result<ValidationReport>;
fn apply(&self, diff: &RulesetDiff) -> Result<ApplyReport>;
fn read_state(&self) -> Result<DataplaneState>;
fn counters(&self, rule_id: RuleId) -> Result<Counters>;
fn interfaces(&self) -> Result<Vec<InterfaceInfo>>;
}
NftablesBackend(default): netlink-based, uses nftables' native atomic transaction commits.EbpfBackend(planned, opt-in): aya-based acceleration for specific hot paths — gated behind real performance measurements per the spec's phased approach.
Privilege
All kernel-touching methods require CAP_NET_ADMIN on Linux. This is
documented per-method in rustdoc.
Development
See CONTRIBUTING.md.
cargo test --workspace
cargo clippy --workspace --all-targets -- -D warnings
cargo doc --workspace --no-deps
# Privileged integration tests (Linux, root):
sudo cargo test -p tpt-netctl-nftables --features integration -- --ignored
License
Licensed under either of
- Apache License, Version 2.0 (LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0)
- MIT license (LICENSE-MIT or http://opensource.org/licenses/MIT)
at your option.