Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
9a8989c
plan: add exhaustive ipv6 link-local implementation roadmap
Frando Mar 3, 2026
be820f1
feat: add ipv6 link-local plumbing and router iface API
Frando Mar 3, 2026
65dbcbd
docs: document ipv6 link-local behavior and stabilize udp loss tests
Frando Mar 3, 2026
ee3fea7
feat: improve RA-driven IPv6 scoped default-route handling
Frando Mar 3, 2026
e729af5
feat: add router RA controls and worker gating
Frando Mar 3, 2026
2053d34
feat: emit RA advertisement events with lifetime metadata
Frando Mar 3, 2026
7752a12
feat: handle RA lifetime zero for radriven default routes
Frando Mar 3, 2026
6d96fa2
feat: emit rs tracing events in radriven control path
Frando Mar 3, 2026
1af73cd
feat: persist radriven router solicitation events to node logs
Frando Mar 3, 2026
48ae37c
test: cover local v6 routing without default router in radriven mode
Frando Mar 4, 2026
22e8b4c
feat: add runtime router RA controls for radriven route refresh
Frando Mar 4, 2026
988d3d0
feat: reconcile radriven v6 default routes on runtime RA changes
Frando Mar 4, 2026
878350b
feat: make ra worker react to runtime config updates
Frando Mar 4, 2026
ae33db3
test: cover ra worker shutdown on router removal
Frando Mar 4, 2026
d354e13
feat: add ipv6 deployment profiles for lab provisioning
Frando Mar 4, 2026
e712356
feat: map router presets to recommended ipv6 profiles
Frando Mar 4, 2026
ac132e8
feat: allow per-device ipv6 provisioning overrides
Frando Mar 4, 2026
f73fed1
test: verify ra reconcile skips static override devices
Frando Mar 4, 2026
8a9b8bf
test: cover static override route switching with runtime iface changes
Frando Mar 4, 2026
018d9db
test: assert static ipv6 mode skips ra and rs tasks
Frando Mar 4, 2026
28ab0ca
fix: resolve ipv6 link-local review findings
Frando Mar 4, 2026
49846a2
fix: make spawn_reflector async with readiness signalling
Frando Mar 4, 2026
80e1001
merge: bring main into ip6-link-local
Frando Mar 4, 2026
3053fc4
docs: finalize ipv6 link-local plan completion status
Frando Mar 4, 2026
9906e8f
fix: tighten ipv6 default-route handling and align ipv6 ll docs
Frando Mar 4, 2026
cba194c
docs: clarify ipv6 fidelity and add limitations reference
Frando Mar 4, 2026
d9ff2a4
docs: refine prose style and normalize reference wording
Frando Mar 4, 2026
0058fe3
merge: bring main into ip6-link-local
Frando Mar 4, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 42 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,37 @@ between IPv6 and IPv4 headers; nftables masquerade handles port mapping.
Use `RouterPreset::MobileV6` or `.nat_v6(NatV6Mode::Nat64)` directly.
See [docs/reference/ipv6.md](docs/reference/ipv6.md) for details.

### IPv6 link-local and provisioning modes

Every IPv6-capable device/router interface now exposes a link-local address
through the handle snapshots:

- `Device::default_iface().and_then(|i| i.ll6())`
- `Device::interfaces().iter().filter_map(|i| i.ll6())`
- `router.iface("ix").or_else(|| router.iface("wan")).and_then(|i| i.ll6())`
- `router.interfaces().iter().filter_map(|i| i.ll6())`

Patchbay also supports explicit IPv6 provisioning and DAD modes via `LabOpts`:

```rust
let lab = Lab::with_opts(
LabOpts::default()
.ipv6_provisioning_mode(Ipv6ProvisioningMode::Static)
.ipv6_dad_mode(Ipv6DadMode::Enabled),
).await?;
```

`Ipv6ProvisioningMode::Static` keeps route wiring deterministic.
`Ipv6ProvisioningMode::RaDriven` enables patchbay's RA/RS-driven path.
`Ipv6DadMode::Disabled` is the current default for deterministic test setup.

In `RaDriven` mode, patchbay models Router Advertisement and Router
Solicitation behavior through structured events and route updates. It does
not emit raw ICMPv6 RA or RS packets on the virtual links.

For full scope and known gaps, see [Book limitations](docs/limitations.md)
and [IPv6 reference](docs/reference/ipv6.md).

### Firewalls

Firewall presets control both inbound and outbound traffic:
Expand Down Expand Up @@ -265,6 +296,12 @@ provide `spawn`, `run_sync`, `spawn_thread`, `spawn_command`,
namespace. Handle methods return `Result` or `Option` when the underlying
node has been removed from the lab.

For IPv6 diagnostics, use per-interface snapshots instead of only `ip6()`:

- `DeviceIface::ip6()` for global/ULA address.
- `DeviceIface::ll6()` for `fe80::/10` link-local address.
- `RouterIface::ip6()` and `RouterIface::ll6()` for router-side interface state.

## TOML configuration

You can also load labs from TOML files via `Lab::load("lab.toml")`:
Expand Down Expand Up @@ -302,15 +339,15 @@ patchbay run ./sims/my-sim.toml --open

The UI provides five tabs:

- **Topology** interactive graph of routers, devices, and links with a
- **Topology**: interactive graph of routers, devices, and links with a
detail sidebar showing NAT, firewall, IPs, and counters.
- **Events** table of lab lifecycle events (router added, device added,
- **Events**: table of lab lifecycle events (router added, device added,
NAT changed, etc.) with relative/absolute timestamps.
- **Logs** per-namespace tracing log viewer with JSON parsing, level
- **Logs**: per-namespace tracing log viewer with JSON parsing, level
badges, and target filtering. Supports jump-to-log from the timeline.
- **Timeline** grid of extracted `_events` per node over time, with
- **Timeline**: grid of extracted `_events` per node over time, with
detail pane and jump-to-log.
- **Perf** throughput results table (only for TOML runner sims).
- **Perf**: throughput results table (only for TOML runner sims).

Each `Lab` instance writes to a timestamped subdirectory under the outdir.
Multiple runs accumulate in the same outdir and appear in the run selector.
Expand Down
1 change: 1 addition & 0 deletions docs/SUMMARY.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# Summary

[Introduction](introduction.md)
[Limitations](limitations.md)

# Guide

Expand Down
4 changes: 2 additions & 2 deletions docs/guide/getting-started.md
Original file line number Diff line number Diff line change
Expand Up @@ -221,8 +221,8 @@ pollutes the host.

## Viewing results in the browser

patchbay can write structured output to disk topology events,
per-namespace tracing logs, and extracted custom events and serve them
patchbay can write structured output to disk, including topology events,
per-namespace tracing logs, and extracted custom events, and serve them
in an interactive web UI. Set the `PATCHBAY_OUTDIR` environment variable
to enable this:

Expand Down
7 changes: 7 additions & 0 deletions docs/guide/running-code.md
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,13 @@ Handle methods return `Result` or `Option` when the underlying node has
been removed from the lab. If you hold a handle to a device that no longer
exists, calls will return an error rather than panicking.

When debugging IPv6 behavior, inspect interface snapshots instead of only
top-level `ip6()` accessors:

- `device.default_iface().and_then(|i| i.ip6())` for global/ULA IPv6.
- `device.default_iface().and_then(|i| i.ll6())` for link-local `fe80::/10`.
- `router.interfaces()` for `RouterIface` snapshots on `ix`/`wan` and bridge.

## Cleanup

When the `Lab` is dropped, it shuts down all async and sync workers, then
Expand Down
5 changes: 5 additions & 0 deletions docs/guide/topology.md
Original file line number Diff line number Diff line change
Expand Up @@ -120,8 +120,13 @@ You can read a device's assigned addresses through the handle:
```rust
let v4: Option<Ipv4Addr> = server.ip();
let v6: Option<Ipv6Addr> = server.ip6();
let ll: Option<Ipv6Addr> = server.default_iface().and_then(|i| i.ll6());
```

For router-side address inspection, use `router.interfaces()` or
`router.iface("ix")` / `router.iface("wan")` and read `ip6()` plus `ll6()`
from `RouterIface`.

### Multi-homed devices

A device can have multiple interfaces, each connected to a different
Expand Down
4 changes: 4 additions & 0 deletions docs/introduction.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,10 @@ common network scenarios like WiFi handoff and VPN tunnels, the internals
of NAT traversal and hole-punching as implemented in nftables, and the
TOML simulation file format used by the patchbay runner.

The **Limitations** page documents known boundaries of the current model.
Read it before relying on packet-level control-plane behavior, operating
system specific network-stack quirks, or low-level timing fidelity.

A built-in devtools server (`patchbay serve`) provides an interactive web
UI for inspecting lab runs: topology graphs, event timelines,
per-namespace structured logs, and performance results. Set
Expand Down
104 changes: 104 additions & 0 deletions docs/limitations.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
# Limitations

This page documents known limitations of patchbay. The goal is to help you
decide when patchbay is a good fit, and where you should expect differences
from production systems.

## IPv6 limitations

### RA and RS are modeled, not packet-emulated

In `Ipv6ProvisioningMode::RaDriven`, patchbay models Router Advertisement
(RA) and Router Solicitation (RS) behavior through route updates and
structured tracing events. It does not currently send raw ICMPv6 RA or RS
packets on virtual links.

Impact:

- Application-level routing behavior is usually close to production.
- Packet-capture workflows that expect real RA/RS frames are not covered yet.

### SLAAC behavior is partial

Patchbay models default-route and address behavior needed for routing tests,
but it does not currently implement a full Stateless Address
Autoconfiguration (SLAAC) state machine with all timing transitions.

Impact:

- Connectivity and route-selection tests work well.
- Detailed host autoconfiguration timing studies are out of scope.

### Neighbor Discovery timing is not fully emulated

Neighbor Discovery (ND) address and router behavior is represented in route
and interface state, but exact kernel-level timing of ND probes, retries, and
expiration is not fully emulated.

Impact:

- Most application tests are unaffected.
- Low-level protocol timing analysis should use a dedicated packet-level setup.

### DHCPv6 prefix delegation is not implemented

Patchbay does not implement a DHCPv6 Prefix Delegation server or client flow.
Use static /64 allocation in topologies.

Impact:

- Residential-prefix churn workflows are not fully represented.
- Prefix-based routing and NAT64 scenarios still work with static setup.

## General platform and model limitations

### Linux-only execution model

Patchbay uses Linux network namespaces, nftables, and tc. It models network
behavior through the Linux kernel network stack.

Impact:

- Native execution requires Linux.
- macOS and Windows host stacks are not emulated byte-for-byte.

### Requires kernel features and host tooling

Patchbay depends on user namespaces and network tools such as `nft` and `tc`.
If those capabilities are unavailable or restricted, labs cannot run.

Impact:

- Some CI and container environments need extra setup.
- Missing kernel features can block specific scenarios.

### No wireless or cellular radio-layer simulation

Patchbay models link effects with `tc` parameters such as latency, jitter,
loss, and rate limits. It does not model WiFi or cellular PHY/MAC behavior.

Impact:

- Good for transport and application resilience testing.
- Not suitable for radio scheduling or handover signaling research.

### Dynamic routing protocols are not built in

Patchbay focuses on static topology wiring, NAT, firewalling, and route
management through its API. It does not include built-in BGP, OSPF, or RIP
control-plane implementations.

Impact:

- You can still run routing daemons inside namespaces yourself.
- Protocol orchestration is user-managed, not first-class in patchbay.

### Time and clock behavior are not virtualized

Patchbay uses the host kernel clock and scheduler behavior. It does not
virtualize per-node clocks or provide deterministic virtual time.

Impact:

- Most integration tests work as expected.
- Time-sensitive distributed-system tests may need additional controls.
Loading
Loading