Skip to content

Latest commit

 

History

1 Commit

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

fw100 — Linux High-Performance Firewall / NAT / PAT

A production-grade stateful firewall, NAT and PAT targeting 100 Gbps, built with a strict two-language split:

  • C owns the packet path — parsing, conntrack, NAT/PAT, ACL, routing, rate limiting, checksums, batching. Nothing in Go ever touches a packet.
  • Go owns the control plane — REST API, CLI, config, policy compilation, metrics, health, audit, supervision, async event logging. Nothing in Go sits on the critical packet path.

The two meet only through shared memory (config Go→C, stats C→Go), a lock-free event ring (C→Go logging), and a Unix-domain-socket command channel (Go→C runtime commands). Config updates are applied without stopping the data plane.

Honesty rule. Every performance figure in this repo is either tied to the exact hardware it was measured on, or it is explicitly labelled NOT MEASURED. The synthetic pipeline numbers below come from an in-memory PMD on a laptop CPU — they are not NIC throughput. See docs/PERFORMANCE.md.


Design absolutes (enforced by construction)

Rule How it is enforced
C = packet processing All per-packet code lives in c/. Go never receives an fw_buf_t.
Go = management/control Go only reads shm stats, writes policy, and issues UDS commands.
PAT in the C fast path fw_pat_alloc is per-core, lock-free, O(1).
Go creates policy, C enforces it Go compiles YAML→ipc.Policy; C consumes it via seqlock.
C collects counters, Go exposes them Per-core lock-free counters in shm; Go renders Prometheus.
C emits events, Go logs async MPSC event ring drained by a Go goroutine; never inline.

Fast-path discipline (per core, per packet): no malloc/free, no mutex on the hot path, no printf, no synchronous logging, no syscalls, no contended global counters. NAT/ACL/routing take a shard lock or RCU read only on a flow-cache miss.


Features

Data plane (C)

  • DPDK PMD (gated on HAVE_DPDK) plus tap and afpacket fallbacks so the whole stack runs and is testable on any Linux box.
  • Stateful conntrack: 5-tuple TCP/UDP/ICMP, per-IP / per-zone / global limits, timing-wheel expiry (no full-table scans).
  • NAT: PAT/NAPT (per-core port pools, O(1) lookup, collision + exhaustion handling), SNAT, DNAT, port-forwarding, incremental RFC-1624 checksums.
  • ACL (5-tuple + state), DIR-24-8-8-style LPM routing with RCU publish, token-bucket rate limiting (fixed-point TSC), flow classification, batching, RSS, CPU affinity, NUMA-aware pools, sharded/lock-free tables.

Control plane (Go)

  • REST API (/rules, /nat, /stats, /connections, /nat/translations, /health, /metrics, /config, /reload, /log, /neigh).
  • fwctl CLI, YAML config, atomic hot reload, bearer-token auth, per-IP rate limiting, JSON audit log, async event-log consumer, supervision with watchdog + restart.
  • Prometheus metrics (fw100_*), health endpoint with heartbeat freshness.

Quick start

# 1. Build the C data plane + tests (Release). Sanitizer builds below.
cmake -B build -DCMAKE_BUILD_TYPE=Release
cmake --build build -j"$(nproc)"

# 2. Build the Go control plane.
cd go && go build ./... && go vet ./... && go test ./...
go build -o ../build/firewalld ./cmd/firewalld
go build -o ../build/fwctl     ./cmd/fwctl
cd ..

# 3. Run the C unit tests (9 suites) and the synthetic benchmark.
ctest --test-dir build --output-on-failure
./build/fwbench

# 4. End-to-end (needs root for TAP/netns).
sudo ./scripts/e2e.sh            # control-plane integration (REST, reload, auth)
sudo ./scripts/e2e-forward.sh    # real SNAT/PAT packet through the tap PMD

Run the daemon against the sample config:

sudo ./build/firewalld -config configs/firewall.yaml \
     -dp-bin "$PWD/build/fw100-dp" -shm /fw100-shm \
     -sock /run/fw100/ctl.sock -pmd tap -cores 2 \
     -api-addr 127.0.0.1:8080 -api-token secret

Then talk to it:

export FW100_API_TOKEN=secret
./build/fwctl -api http://127.0.0.1:8080 status
./build/fwctl -api http://127.0.0.1:8080 stats
curl -s -H "Authorization: Bearer secret" http://127.0.0.1:8080/metrics

Repository layout

firewall/
├── c/                  # C data plane (packet path only)
│   ├── packet/         #   parser, hashing, incremental checksum
│   ├── conntrack/      #   per-core conntrack + timing-wheel GC
│   ├── nat/            #   NAT/PAT/SNAT/DNAT, port pools
│   ├── acl/            #   5-tuple + stateful ACL
│   ├── routing/        #   LPM, neighbor table
│   ├── ratelimit/      #   token buckets (fixed-point TSC)
│   ├── flowcache/      #   per-core direct-mapped verdict cache
│   ├── ipc/            #   shm (seqlock), event ring, UDS ctl
│   ├── dpdk/           #   PMD vtable: tap / afpacket / dpdk / test
│   ├── numa/  util/    #   NUMA, mempool, timing wheel
│   └── dataplane/      #   pipeline glue + fw100-dp main
├── go/                 # Go control plane (no packets)
│   ├── ipc/            #   cgo shm/seqlock/UDS client + ABI guard
│   ├── config/ policy/ #   YAML config + compile to ipc.Policy
│   ├── api/ metrics/   #   REST server, Prometheus rendering
│   ├── health/ audit/  #   health checker, JSON audit
│   ├── logproc/        #   async event-ring consumer
│   ├── controller/     #   supervision, atomic reload
│   └── cmd/            #   firewalld, fwctl, abicrc
├── include/            # shared C headers (the ABI)
├── configs/            # sample + e2e YAML policies
├── tests/  benchmarks/ # C unit tests + fwbench
├── scripts/  systemd/  # ops scripts + service unit
└── docs/               # ARCHITECTURE / PERFORMANCE / OPERATIONS

Performance (read the labels)

Synthetic pipeline cost on this development machine (in-memory PMD, single core, no NIC). tsc_hz ≈ 1.90 GHz.

Scenario cycles/pkt Mpps (synthetic)
cached allow ~166 ~11.4
cached SNAT ~194 ~9.8
new-flow SNAT ~428 ~4.4
drop flood ~211 ~9.0

These are NOT MEASURED on a NIC. Reaching 100 Gbps requires the DPDK PMD and real hardware; the math and the measurement methodology are in docs/PERFORMANCE.md.


Documentation

License

No license is applied yet. Choose and add a LICENSE file before distribution.

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages