High-performance nftables formatter and linter
Find a file
2025-05-24 23:56:52 +03:00
nix nix: init tooling 2025-05-24 23:16:00 +03:00
src treewide: fmt 2025-05-24 23:41:06 +03:00
.envrc nix: init tooling 2025-05-24 23:16:00 +03:00
.gitignore initial commit 2025-05-24 16:03:32 +03:00
Cargo.lock chore: drop unused nftables crate 2025-05-24 23:47:10 +03:00
Cargo.toml chore: drop unused nftables crate 2025-05-24 23:47:10 +03:00
flake.lock nix: init tooling 2025-05-24 23:16:00 +03:00
flake.nix nix: init tooling 2025-05-24 23:16:00 +03:00
LICENSE docs: add project README 2025-05-24 23:56:52 +03:00
README.md docs: add project README 2025-05-24 23:56:52 +03:00

nff

This is a high performance configuration parser and written in Rust. The goal is to receive possibly jumbled up nftables rule files, and output pretty human readable output in return. The main emphasis is on the syntax-aware formatting with comprehensive grammar support. It is a future goal to allow editors to hook into nff in order to format your rulesets directly from your editor, or as a diagnostics source.

Features

nff is in its early stages of development. While most of the syntax is supported, I cannot guarantee that everything is supported just yet.

Core Functionality

  • Syntax-aware formatting - Deep understanding of nftables grammar with semantic preservation
  • Multi-family support - Handles inet, ip, ip6, arp, bridge, and netdev table families
  • Flexible indentation - Configurable tabs/spaces with custom depth
  • CIDR notation - Proper handling of network addresses (192.168.1.0/24)
  • Chain properties - Hooks, priorities (including negative), policies, device bindings

Advanced Features

  • CST - Lossless representation preserving all tokens
  • Debug mode - Comprehensive inspection of lexer tokens, AST, and CST
  • Validation - Syntax checking with precise error locations
  • Optimization - Configurable empty line reduction and whitespace control

Usage

# Basic formatting
nff -f /etc/nftables.conf

# Custom indentation (4 spaces)
nff -f config.nft --indent spaces --spaces 4

# Optimize formatting (reduce empty lines)
nff -f config.nft --optimize

# Output to file
nff -f config.nft -o formatted.nft

# Syntax validation only
nff -f config.nft --check

# Debug output for development (or debugging)
nff -f config.nft --debug

Architecture

Processing Pipeline

nff implements a multi-stage pipeline:

graph TD
    Input --> Lexer
    Lexer --> Tokens
    Lexer --> Parser
    Tokens --> Parser
    Parser --> CST
    Parser --> AST
    AST --> Formatter
    Formatter --> Output
    CST --> Formatter

Installation

Recommended way of installing nff is to use Nix.

Development

Testing

# Run test suite
cargo test

# Run with verbose output
cargo test -- --nocapture

# Test specific module
cargo test lexer

Code Quality

# Check compilation
cargo check

# Format code
cargo fmt

# Lint code
cargo clippy

# Check for unused dependencies
cargo machete

Supported nftables Features

Table Families

  • inet - Dual-stack IPv4/IPv6 (most common)
  • ip - IPv4 only
  • ip6 - IPv6 only
  • arp - ARP protocol
  • bridge - Bridge/Layer 2
  • netdev - Network device (ingress/egress)

Chain Types & Hooks

  • filter: input, forward, output
  • nat: prerouting, input, output, postrouting
  • route: output
  • security: input, forward, output

Expression Types

  • Protocol matching: ip protocol tcp, tcp dport 80
  • Interface matching: iifname "eth0", oifname "wlan0"
  • Address matching: ip saddr 192.168.1.0/24, ip6 daddr ::1
  • Connection tracking: ct state established,related
  • Port specifications: tcp dport { 22, 80, 443 }
  • Rate limiting: limit rate 10/minute burst 5 packets
  • Sets and maps: Named sets with timeout support

Actions & Statements

  • Verdicts: accept, drop, reject, return
  • NAT: snat to 192.168.1.1, dnat to 192.168.1.100:80
  • Marking: mark set 0x1, ct mark set 0x1
  • Logging: log prefix "dropped: "
  • Counters: counter packets 0 bytes 0

Examples

Basic Firewall

Input (minified):

table inet firewall{chain input{type filter hook input priority 0;policy drop;ct state established,related accept;iifname lo accept;tcp dport 22 accept}}

Output (formatted):

#!/usr/sbin/nft -f
table inet firewall {
        chain input {
                type filter hook input priority 0; policy drop;
                ct state established,related accept
                iifname lo accept
                tcp dport 22 accept
        }
}

NAT Configuration

#!/usr/sbin/nft -f
table ip nat {
        chain prerouting {
                type nat hook prerouting priority -100; policy accept;
                iifname "eth0" tcp dport 80 dnat to 192.168.1.100:8080
        }

        chain postrouting {
                type nat hook postrouting priority 100; policy accept;
                oifname "eth0" masquerade
        }
}

Rate Limiting

#!/usr/sbin/nft -f
table inet protection {
        chain input {
                type filter hook input priority 0; policy accept;
                tcp dport 22 limit rate 5/minute burst 10 packets accept
                tcp dport 22 drop
        }
}

Contributing

Code Style

  • Follow cargo fmt formatting
  • Use cargo clippy recommendations
  • Maintain comprehensive documentation
  • Add tests for new features

Testing Strategy (WIP)

  • Unit tests: Individual component validation
  • Integration tests: End-to-end formatting verification
  • Regression tests: Known issue prevention
  • Performance tests: Benchmark critical paths

Building

Build with cargo build as usual. If you are using Nix, you will also want to ensure that the Nix package builds as expected.

Technical Notes

CST Implementation

The Concrete Syntax Tree (CST) preserves all source information including:

  • Whitespace and indentation
  • Comments and their positions
  • Token-level error recovery
  • Lossless round-trip formatting

Parser Architecture

Below are the design goals of nff's architechture.

  • Error recovery: Continues parsing after syntax errors
  • Incremental parsing: Supports partial file processing
  • Memory efficiency: Streaming token processing where possible
  • Grammar completeness: Covers full nftables syntax specification

License

nff is licensed under MPL v2.0. See license file for more details on what the license entails.