This repository contains the Dataplane for Hedgehog's Open Network Fabric. This component acts as a gateway between different VPCs managed by the Fabric, or to communicate with endpoints outside of the Fabric.
- A recent
x86_64linux machine is required for development - Nix (the nix-shell provides the full toolchain, including Rust, Cargo, and all required libraries). The single-user installation is recommended unless you are familiar with nix and prefer the multi-user installation; both will work.
- just (task runner — install through your package manager or
nix-env -i just)
git clone [email protected]:githedgehog/dataplane.git
cd dataplaneFrom the source directory, enter the development shell:
just shellThis provides the full development toolchain, including Rust, Cargo, Clippy, cargo-nextest, and all required
libraries and system dependencies.
To build the dataplane with default settings
just buildis sufficient.
If you wish to build a specific package from this workspace, such as the init system or the cli
just build workspace.init
just build workspace.cliMost just recipes are impacted by the profile argument which selects the cargo profile to use.
For instance, to build in release mode
just profile=release buildYou can also select a target platform via the platform argument.
The default is x86-64-v3.
just platform=zen4 buildTo run the full test suite
just testTo run tests in release mode
just profile=release testYou can enable a comma separated list of sanitizers via the sanitize argument.
You don't strictly need to use the fuzz profile with the sanitizers, but it is recommended.
just sanitize=address,leak profile=fuzz test
just sanitize=safe-stack profile=fuzz test
just sanitize=thread profile=fuzz testYou can also build and run the tests for a specific package from within this workspace.
For example, to run the dataplane-net package's tests
just test netThis covers basic testing and building of dataplane, but there is more to testing dataplane.
Note that running just build dataplane only builds the binary, not the container.
To build the dataplane container
just build-container dataplaneOr, if you wish to build in release mode
just profile=release build-container dataplaneYou can build the FRR container as well
just build-container frr.dataplaneSanitizers work with the container builds too
just sanitize=address,leak profile=fuzz build-container dataplane
just sanitize=address,leak profile=fuzz build-container frr.dataplane
just sanitize=thread profile=fuzz build-container dataplane
just sanitize=thread profile=fuzz build-container frr.dataplaneTo build and push a container image to the configured OCI registry
just push-container dataplane
just push-container frr.dataplaneBy default, images are pushed to 127.0.0.1:30000.
You can override this with the oci_repo argument
just oci_repo=my-registry.example.com:5000 push-container dataplaneMost just recipes accept the following arguments, which can be combined freely:
| Argument | Default | Description |
|---|---|---|
profile |
debug |
Cargo build profile (debug, release, or fuzz) |
sanitize |
(none) | Comma-separated list of sanitizers (address, leak, thread, safe-stack, cfi) |
instrument |
none |
Instrumentation mode (none or coverage) |
platform |
x86-64-v3 |
Target platform (x86-64-v3 or zen3, zen4, zen5, bluefield2, bluefield3) |
jobs |
1 |
Number of nix jobs to run in parallel |
just lintjust docsTo build docs for a specific package
just docs netCreate the devroot and sysroot symlinks needed for local IDE integration and development
just setup-rootsThe fabric pin in npins/sources.json is frozen to prevent accidental updates.
To update it to a specific version:
npins unfreeze fabric
npins add github githedgehog fabric --at <version>
npins freeze fabricAfter updating, exit and restart nix-shell for the changes to take effect.
The nix-shell provides the full toolchain, so IDE setup is straightforward. Here are the suggested configurations for various IDEs:
Launch VSCode from within the nix-shell so that rust-analyzer and other tools can find the correct toolchain:
nix-shell --run "code ."Note
VSCode must be started from within the nix-shell, otherwise the correct rust-analyzer will not be found.
Add the following to your .vscode/settings.json file:
{
"rust-analyzer.check.command": "clippy",
"[rust]": {
"editor.defaultFormatter": "rust-lang.rust-analyzer",
"editor.formatOnSave": true
}
}Save the following to the .zed/settings.json file:
{
"languages": {
"Rust": {
"formatter": "language_server",
"format_on_save": "on"
}
},
"lsp": {
"rust-analyzer": {
"binary": {
"path": "nix-shell",
"arguments": ["--run", "rust-analyzer"]
},
"initialization_options": {
"check": {
"command": "clippy"
}
}
}
},
"dap": {
"CodeLLDB": {
"binary": "nix-shell",
"args": ["--run", "lldb-dap"]
}
},
"terminal": {
"shell": {
"program": "nix-shell"
}
}
}Zed wraps rust-analyzer and the debugger with nix-shell --run, so it does not need to be launched from the
nix-shell.
The dataplane code is organized in a set of crates.
All crates aren't equal (or they are but some are more equal than others).
The dataplane crate contains the main binary and may include any other as a dependency.
The crates developed within this project are aliased to dataplane-NAME and referred to as internal.
Since Rust is not a good friend of circular dependencies, here come some guidelines to avoid those.
There is a set of low-level infrastructure crates (tier-1) with limited internal dependencies which many other crates
may refer to.
The tier-1 set of crates includes: net, pipeline, lpm or config.
Note that some of those refer to the others (e.g. net is a dependency of pipeline).
A second tier of crates use the prior set to add extended functionalities.
These include nat or routing.
These crates may have config as dependency, but not vice-versa.
I.e. in general, tier-n can only have as dependencies, crates in tier-k, k<=n.
Finally, crate mgmt (tier-3) may make use of any the internal crates (tier-1 and tier-2).
No other crate (other than dataplane) (tier-4) should depend on mgmt.
- No crate should ever depend on
dataplane. - No crate except
dataplaneshould depend onmgmt. - Crate
configshould never depend on tier-2 crates (e.g.natorrouting). - The general rule is that a tier-n crate can only have as dependencies crates in tier-k, k<=n.
- In other words, in a graphical representation as below, dependency arrows can never go upwards.
┌─────────────────────────────────┐
│ dataplane │
└┬───────────┬─────────┬──────────┘
│ │ │
│ │ │
│ │ ┌─────▼────┐
│ │ │ │
│ │ │ mgmt ┼───────────────┐ tier-3
│ │ │ │ │
│ │ └┬───────┬─┘ │
│ │ │ │ │
┌────┘ ┌────▼────▼┐ ┌──▼───────┐ │
│ │ │ │ │ │
│ ┌─────┼ nat │ │ routing ┼───────┐ │ tier-2
│ │ │ │ │ │ │ │
│ │ └──────┬───┘ └──────────┘ │ │
│ │ │ │ │
┌▼─────▼───┐ ┌─────▼────┐ ┌──────────┐ ┌────▼─▼───┐
│ │ │ │ │ │ │ │
│ net │ │ lpm │ │ pipeline │ │ config │ tier-1
│ │ │ │ │ │ │ │
└───▲──────┘ └──────────┘ └───┬──────┘ └──────────┘
│ │
└───────────────────────────┘
Figure: full workspace dependency graph. Note that tier-1 packages (like net) never depend on tier-2 packages (like nat).
The Dataplane of the Hedgehog Open Network Fabric is licensed under the Apache License, Version 2.0.