The import policy did the same to every route of a session. Now `rules` can do more to some of them: those with certain communities, those for certain prefixes, or both. Each rule can set the local preference and put communities on; each route takes the first rule that holds for it. Rules see a route as the session's own statements leave it, with our communities taken off and the session's marks put on. So a router can act on where another router of ours learned a route, by the mark that router put on it, and a customer's single prefix can be marked for a prepend. Routes of one UPDATE that different rules hold for go into the table with attribute sets of their own. An UPDATE that no rule touches is taken as before, without its attributes being written out again. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Ferrix BGP
An implementation of the Border Gateway Protocol, which is used to exchange routing and control plane information between Autonomous Systems.
The aim of this project is to provide a modern, high performance, secure, programmatic and customizable software package that can be useful to network operators, researchers, and people interested in Internet.
Current status
The daemon establishes BGP sessions with configured neighbors, evaluates received routes against import policy, validates them with the RPKI (route origin validation and ASPA), selects the best path for each prefix, and, on Linux, installs it in the kernel. It advertises the routes that it originates and, to neighbors configured for it, the best paths learned from other neighbors, as BGP roles (RFC 9234) and communities permit.
Ferrix has not been deployed in a production network.
Unsupported Features
- Route reflection, per-client best path selection for route servers, and ADD-PATH for advertised routes
- TCP-AO, TCP MD5, and GTSM
- Graceful restart, BFD, and configuration changes without a restart
- Recursive resolution of next hops that are not directly connected
Layout
| Crate | What is in it |
|---|---|
crates/primitives |
Prefixes, address families, parsing helpers |
crates/packet |
The wire format: messages, attributes, capabilities |
crates/rib |
The routing table, best route selection, the journal of changes |
crates/rpki |
The RTR client; origin validation and ASPA path verification |
crates/fib |
The best routes in the Linux kernel, over netlink |
crates/server |
Sessions, the state machine, policy, configuration |
crates/web |
The status page, HTTP API and metrics |
bin/bgp |
The daemon |
Documentation
The documentation is a website built from docs/ with
Zola:
zola --root docs serve # http://127.0.0.1:1111
- Overview and quick start
- User guide: BGP neighbors, import policy, BGP roles, RPKI, kernel route installation, route advertisement, configuration examples
- Deployment and monitoring
- Reference: configuration, HTTP API, metrics, supported standards
- Architecture and testing
Development
CI runs these on every push, and fails on any warning:
cargo fmt --all -- --check
cargo clippy --workspace --all-targets -- -D warnings
cargo test --workspace
RUSTDOCFLAGS="-D warnings" cargo doc --workspace --no-deps --document-private-items
zola --root docs build
It also runs the tests that need a real Linux kernel
(scripts/kernel-tests.sh) and the lab with FRR, BIRD and Routinator
(scripts/interop/lab.sh); scripts/linux-vm.sh runs either from macOS.
Lints are configured once, under [workspace.lints] in the root Cargo.toml.
unsafe code is forbidden throughout.
cargo test includes property tests: generated messages must survive being
written and read back, and no input, however damaged, may make a parser
panic. They take about a second; for a longer hunt:
PROPTEST_CASES=1000000 cargo test --release -p bgp-packet --test properties
Coverage-guided fuzz targets for the same parsers are in fuzz/; see
fuzz/README.md. CI runs each of them for a minute.
License
Apache License 2.0; see LICENSE.