Remove policy scripts

Rhai made a decision about a route cost one to three microseconds,
some two hundred times what the same costs in Rust. That was bearable
where a function is asked once for an UPDATE, and is not where every
route is weighed against every peer, as it is when routes are passed
on. What is wanted of a policy (mark routes by where they came from,
mark what is announced, let communities say who is told what) needs no
language; it is to be configuration, done natively.

Kept from that work: route selection goes by a LOCAL_PREF that policy
set on a route from an external peer, and the lab's configuration can
be added to by a phase.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
Rayhaan JaufeerallyandClaude Fable 5.1 committed 2026-10-02 22:47:57 +02:00
1 parent cbf0df1eef
commit 9367c38907
48 files changed
+21 -3435

No files matched your search

-8
View File
@@ -18,7 +18,6 @@ cargo-fuzz = true
bgp-packet = { path = "../crates/packet" }
bgp-primitives = { path = "../crates/primitives" }
bgp-fib = { path = "../crates/fib" }
bgp-policy = { path = "../crates/policy" }
bgp-rib = { path = "../crates/rib" }
bgp-rpki = { path = "../crates/rpki" }
bgp-server = { path = "../crates/server" }
@@ -36,13 +35,6 @@ test = false
doc = false
bench = false
[[bin]]
name = "policy"
path = "fuzz_targets/policy.rs"
test = false
doc = false
bench = false
[[bin]]
name = "message"
path = "fuzz_targets/message.rs"
-1
View File
@@ -15,7 +15,6 @@ you leave them running.
| `rtr` | A stream of RTR PDUs, as an RPKI cache sends them |
| `netlink` | Messages from the kernel's routing socket |
| `attrs` | The routing table's reading of stored attribute bytes |
| `policy` | The example policy script on routes with any attributes |
For the two message targets a finding is either a panic, or a message the
decoder accepted that cannot be written and read back as itself.
-84
View File
@@ -1,84 +0,0 @@
//! The operator's policy script, asked about routes with whatever
//! attributes a peer can send. The example script (testdata/policy.rhai)
//! touches most of what a script can; whatever the route, a function
//! either answers or fails, and never panics. What it changes must still
//! be attributes that can be written.
#![no_main]
use std::sync::{Arc, LazyLock};
use bgp_packet::message::{Message, PathAttribute, UpdateMessage};
use bgp_policy::{Direction, Hook, Peer, Policy, Subject};
use bgp_primitives::ip_prefix::IpPrefix;
use bgp_primitives::parser::ParserContext;
use bytes::BytesMut;
use libfuzzer_sys::fuzz_target;
static HOOKS: LazyLock<(Arc<Policy>, Vec<Hook>)> = LazyLock::new(|| {
let policy = Policy::compile(include_str!("../../testdata/policy.rhai")).unwrap();
let hooks = ["from_peer", "to_peer"]
.into_iter()
.map(|name| policy.hook(name).unwrap())
.collect();
(policy, hooks)
});
fuzz_target!(|data: &[u8]| {
let Some((selector, attributes)) = data.split_first() else {
return;
};
let ctx = ParserContext {
four_octet_asn: true,
ibgp: false,
add_path: Vec::new(),
};
// An UPDATE with no routes withdrawn, these attributes, and one route.
let mut body = vec![0, 0];
let attributes = &attributes[..attributes.len().min(4000)];
body.extend_from_slice(&(attributes.len() as u16).to_be_bytes());
body.extend_from_slice(attributes);
body.extend_from_slice(&[24, 203, 0, 113]);
let Ok(decoded) = UpdateMessage::decode(&ctx, &body) else {
return;
};
let attributes = decoded.update.path_attributes;
let prefix = IpPrefix::try_from("203.0.113.0/24").unwrap();
let roles = ["", "customer", "peer", "provider", "route_server"];
let peer = Peer::new(
"backup-transit",
std::net::Ipv4Addr::new(192, 0, 2, 2).into(),
64602,
65000,
roles[usize::from(selector >> 1) % roles.len()],
);
let (hook, direction) = if selector & 1 == 0 {
(&HOOKS.1[0], Direction::Import)
} else {
(&HOOKS.1[1], Direction::Export)
};
let subject = Subject {
prefix: &prefix,
attributes: &attributes,
next_hop: None,
direction,
};
let Ok(verdict) = hook.run(&peer, &subject) else {
return;
};
if let Some(changed) = verdict.attributes {
let changed: Vec<PathAttribute> = changed;
let update = UpdateMessage {
withdrawn_routes: vec![],
path_attributes: changed,
announced_routes: vec![],
};
let mut wire = BytesMut::new();
// Too long to send is a thing that can be; anything else is not.
if let Err(e) = Message::Update(update).to_wire(&ctx, &mut wire) {
assert!(
matches!(e, bgp_primitives::parser::EncodeError::TooLong { .. }),
"{e}"
);
}
}
});
Binary file not shown.
Binary file not shown.