feat: bootstrap awg2 harness rust workspace and docs

This commit is contained in:
2026-05-09 02:17:25 +05:00
commit d937f816bf
47 changed files with 4195 additions and 0 deletions
+73
View File
@@ -0,0 +1,73 @@
use crate::{config::Config, docker, lock::FileLock, wg};
pub fn reconcile_traffic(cfg: &Config) -> anyhow::Result<()> {
if !cfg.traffic.enabled {
return Ok(());
}
let _lock = FileLock::acquire("/run/awg2-harness/traffic.lock")?;
let target = docker::discover_target(cfg)?;
let peers = wg::discover_peers(&target.container_name, &cfg.amnezia.peer_ipv4_cidr)?;
if peers.is_empty() {
println!("no peers found, skip tc apply");
return Ok(());
}
if cfg.traffic.full_rebuild_on_drift {
teardown_owned_topology(&target.container_name, &target.interface_name, &cfg.traffic.ifb_name)?;
apply_full_topology(cfg, &target.container_name, &target.interface_name, &cfg.traffic.ifb_name, &peers)?;
}
Ok(())
}
fn teardown_owned_topology(container: &str, iface: &str, ifb: &str) -> anyhow::Result<()> {
let cmd = format!(
"tc qdisc del dev {iface} root 2>/dev/null || true; \
tc qdisc del dev {iface} ingress 2>/dev/null || true; \
ip link del {ifb} 2>/dev/null || true"
);
let _ = docker::run_capture(&["docker", "exec", container, "sh", "-c", &cmd])?;
Ok(())
}
fn apply_full_topology(
cfg: &Config,
container: &str,
iface: &str,
ifb: &str,
peers: &[wg::Peer],
) -> anyhow::Result<()> {
let setup_cmd = format!(
"tc qdisc add dev {iface} root handle 1: htb; \
tc class add dev {iface} parent 1: classid 1:1 htb rate {root} ceil {root}; \
modprobe ifb 2>/dev/null || true; \
ip link add name {ifb} type ifb 2>/dev/null || true; \
ip link set dev {ifb} up; \
tc qdisc add dev {iface} handle ffff: ingress; \
tc filter add dev {iface} parent ffff: protocol all u32 match u32 0 0 action mirred egress redirect dev {ifb}; \
tc qdisc add dev {ifb} root handle 2: htb; \
tc class add dev {ifb} parent 2: classid 2:1 htb rate {root} ceil {root}",
root = cfg.traffic.root_rate
);
let _ = docker::run_capture(&["docker", "exec", container, "sh", "-c", &setup_cmd])?;
for (idx, p) in peers.iter().enumerate() {
let class_id = cfg.traffic.class_start_id + idx as u16;
let ip = p.ipv4;
let per_peer = format!(
"tc class add dev {iface} parent 1:1 classid 1:{class_id} htb rate {limit} ceil {limit}; \
tc qdisc add dev {iface} parent 1:{class_id} fq_codel; \
tc filter add dev {iface} parent 1: protocol ip u32 match ip dst {ip} flowid 1:{class_id}; \
tc class add dev {ifb} parent 2:1 classid 2:{class_id} htb rate {limit} ceil {limit}; \
tc qdisc add dev {ifb} parent 2:{class_id} fq_codel; \
tc filter add dev {ifb} parent 2: protocol ip u32 match ip src {ip} flowid 2:{class_id}",
limit = cfg.traffic.peer_limit
);
let _ = docker::run_capture(&["docker", "exec", container, "sh", "-c", &per_peer])?;
}
Ok(())
}