feat: bootstrap awg2 harness rust workspace and docs
This commit is contained in:
@@ -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(())
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user