A firewall you review like code.
Songbird is an open-source network firewall for Linux. Policy is YAML in a Git repository, the data plane is eBPF on the NIC, and a change reaches production the way code does: as a validated, reviewed commit.
Status: design phase, no release yet. The requirements, the architecture, eighteen decision records and the configuration schema are public; the code is written as a consequence of those documents.
apiVersion: "config.songbird-fw.com/v1alpha1"kind: "RuleSet"metadata: name: "internal-to-untrusted"spec: from: "internal" to: "untrusted" rules: - name: "block-printers-internet" source: ["printers"] action: "drop" log: "all" - name: "lan-web-dns" comment: "Only web, DNS and ping out" source: ["grp-lan"] destination: ["any"] service: ["web", "dns", "ping"] action: "accept" nat: { type: "snat" }
Why another firewall
Community firewalls ask you to click through a web interface and trust that the last backup is recent. Enterprise platforms give you clean operations and charge per seat, per feature, per year. Songbird keeps the operational model of the enterprise appliance (zones, named objects, one RuleSet per zone pair, first match wins) and puts it in files you can diff, review, and revert.
- Default deny, written down
- Traffic between two zones is dropped unless a RuleSet says otherwise. An empty RuleSet is a valid, explicit statement (
rules: []), and the schema ships a negative corpus of 49 configurations that must fail validation. schema/examples/invalid - eBPF on the interface
- XDP decides, the kernel forwards, TC rewrites. A dropped packet never becomes a socket buffer; NAT happens on the hooks that can see both directions. Connection tracking is Songbird's own, so a policy change can decide what happens to flows that are already open. ADR-0002 · ADR-0003 · ADR-0004
- Rollback is
git revert - The applied configuration is a commit. The schema is versioned (
config.songbird-fw.com/v1alpha1) with conversion rules, so a previous commit is always loadable, and the appliance image is A/B updatable. ADR-0001 · ADR-0008 · ADR-0017
Where the packet goes
Every IPv4 frame on a physical interface is parsed, pre-filtered, matched against connection tracking and classified in XDP, before the kernel allocates anything for it. Only accepted packets continue into the stack; NAT is applied by TC programs that read the decision XDP left in packet metadata, so nothing is looked up twice.
Kernel 6.6 or newer. TC programs attach with TCX (link-managed, ordered, detachable without qdisc surgery); XDP native where the driver supports it, generic as the fallback. ADR-0013
Atomic apply. A new configuration is compiled into a fresh generation of maps and switched in one step; flows that no longer match a rule are handled according to the policy-change decision, not left to time out silently. ADR-0004
Honest scope. IPv6 is deferred to a later release and is dropped, with an event, rather than passed through unfiltered. FQDN objects are accepted by the schema but cannot yet be enabled in a rule. Data plane design
Documents first, then code
The repository ships its reasoning before its binaries. Every artefact below exists today, is versioned, and changes through pull requests like everything else will.
| Artefact | What it fixes | State |
|---|---|---|
| Requirements Analysis | Stakeholders, glossary, constraints, 90-odd requirements each with a verification criterion, explicit exclusions, traceability. | 2.0.6-draft in team review |
| Project Plan | Release roadmap, scope of MVP 0.1, milestones, work breakdown, risks, process rules. | 0.2.2-draft for team decision |
| Architecture | Domain model, component view, reconciliation loop, eBPF data plane with its pipeline, conntrack and NAT design. | data plane 3.3-draft for review |
| Decision records | 18 ADRs, one file per decision, never deleted: YAML in Git as source of truth, forwarding model, own conntrack, kernel floor, Go control plane, cilium/ebpf, Hadron as appliance OS, CRD-style objects. | 7 accepted 11 proposed |
| Configuration schema | JSON Schema 2020-12 for config.songbird-fw.com/v1alpha1: Address, AddressGroup, Service, Interface, Zone, RuleSet, Color, System. Example configuration and a negative corpus. |
43 valid objects 49 cases that must fail |
| Test Plan | How each requirement is verified: unit, eBPF, integration, benchmark; the coverage matrix from requirement to test. | 0.1.1-draft milestone M0 |
Where help is useful right now
No code to compile yet means the most valuable contributions are the ones that are usually hardest to get: a second pair of eyes on a decision, a configuration that should not validate, a NIC that does not behave.
- Review a proposed ADR
Eleven decisions are still proposed. The kernel floor (ADR-0013), the DHCP and DNS engines (ADR-0014) and the capacity limits (ADR-0006) want opinions from people who run networks.
- Break the schema
Write a configuration that should be rejected and is not. Each one becomes a numbered case in
schema/examples/invalidand a test the validator must keep failing. - Report your hardware
Native XDP depends on the NIC driver. Which cards and kernels you run, and what
ethtoolsays about them, is the evidence behind the reference platform (ADR-0007). - Edit the documents
Right now the documents are the product. An ambiguous requirement or a diagram that does not match the text is a real bug; file it like one.