Rapimt implements the Flash inverse model transformation pipeline
(see docs/flash-sigcomm22.pdf) entirely in Rust. The crate that you
depend on (rapimt) is a lightweight facade over a set of internal
crates that cover predicate engines, inverse model arithmetic, device
IO, and pluggable verification logic.
rapimt::core— header-space encoders, predicate engines (Ruddy and Oxidd), match macros, and forwarding action traits.rapimt::im— inverse model data structures plus rule monitors such asFastRuleMonitor.rapimt::io— parsers and loaders (default router format and InfiniBand snapshots).rapimt::ver— graph-based verification drivers and plugins.rapimt::prelude— re-exports of the symbols most developers reach for (use rapimt::prelude::*;).
- Pick a
PredicateEngine(Ruddy for fast single-threaded prototyping, Oxidd for multi-threaded production runs) and enable the feature flags for the header fields you care about (dip,sip,sport, ...). - Load topology information with an
InstanceLoaderor your own device specific loader and obtain anActionEncoder. - Parse the device FIB into
Ruleobjects viaFibLoader. - Feed incremental changes into a
RuleMonitor(e.g.FastRuleMonitor) to generate per-device inverse models. - Resize and merge device models into a network-wide
InverseModel, then dispatch verification plugins.
use rapimt::core::prelude::{SeqAction, RuddyPredicateEngine};
use rapimt::io::prelude::{InstanceLoader, DefaultInstLoader, FibLoader, PortInfoBase};
use rapimt::im::prelude::{RuleMonitorLike, FastRuleMonitor, InverseModel, MapInverseModel, TPTRuleStore};
fn demo() -> Result<(), Box<dyn std::error::Error>> {
let engine = RuddyPredicateEngine::init(10_000, 1_000);
let loader = DefaultInstLoader::default();
// Load the action encoder for a device.
let spec = std::fs::read_to_string("specs/dev0.spec")?;
let codex: PortInfoBase = loader.load(&spec).unwrap();
// Parse the FIB and insert rules into a monitor.
let fib = std::fs::read_to_string("fibs/dev0.fib")?;
let (_, rules) = codex.load(&engine, &fib).unwrap();
let mut monitor: FastRuleMonitor<_, _, TPTRuleStore<_, _>> =
FastRuleMonitor::new(&engine);
let update: MapInverseModel<SeqAction<usize>, _, _> = monitor.insert(rules);
assert!(update.property_check());
// Resize/merge updates for a multi-device network.
let mut net: MapInverseModel<SeqAction<usize>, _, _> = InverseModel::default();
net <<= InverseModel::resize(update, /*num_devices*/ 1, /*offset*/ 0);
Ok(())
}For a longer, end-to-end walkthrough read docs/development.md.
The crate documentation includes an auto-generated table of all feature
flags via document_features::document_features!().