Update to scripts to better handle netem

This commit is contained in:
Valère Plantevin
2026-05-13 15:40:09 -04:00
parent f226e53118
commit ac8a319b40
2 changed files with 139 additions and 52 deletions

View File

@@ -16,6 +16,10 @@ RATE_HZ="${RATE_HZ:-100}"
BUILD="${BUILD:-release}"
IFACE="${IFACE:-eth0}"
RUN_SIMULATOR="${RUN_SIMULATOR:-1}"
# Bidirectional loss via ifb (ingress redirect). Set BIDI=0 to disable and fall
# back to egress-only shaping on $IFACE.
BIDI="${BIDI:-1}"
IFB_DEV="${IFB_DEV:-ifb0}"
OUT_CSV="${OUT_CSV:-data/loopback/final_table.csv}"
@@ -45,6 +49,67 @@ for port in 9000 9100; do
done
[[ -f certs/server.crt ]] || make certs >/dev/null
# --- netem helpers -----------------------------------------------------------
# tc qdiscs are egress-only. To shape ingress (traffic arriving on $IFACE) we
# install an ingress qdisc that redirects every packet to an ifb device, then
# put the netem qdisc on the ifb's egress. Net effect: both directions of
# $IFACE see the configured loss percentage.
#
# Egress-only fallback (BIDI=0) keeps the historical behaviour: shape outgoing
# CM5 → peer traffic only.
netem_init() {
[[ "$HAS_TC" -eq 1 && "$BIDI" -eq 1 ]] || return 0
# Load the ifb module (idempotent on modern kernels; ignored if built in).
sudo modprobe ifb numifbs=1 2>/dev/null || true
if ! ip link show "$IFB_DEV" >/dev/null 2>&1; then
fail "ifb device $IFB_DEV not present after modprobe; BIDI mode unavailable"
echo " - check 'modprobe ifb' on this kernel, or run with BIDI=0"
return 1
fi
sudo ip link set "$IFB_DEV" up
}
netem_clear() {
[[ "$HAS_TC" -eq 1 ]] || return 0
sudo tc qdisc del dev "$IFACE" root 2>/dev/null || true
sudo tc qdisc del dev "$IFACE" ingress 2>/dev/null || true
if [[ "$BIDI" -eq 1 ]]; then
sudo tc qdisc del dev "$IFB_DEV" root 2>/dev/null || true
fi
}
# Apply $1% loss in both directions (or egress-only when BIDI=0).
netem_apply() {
local pct="$1"
[[ "$HAS_TC" -eq 1 ]] || return 0
netem_clear
[[ "$pct" -gt 0 ]] || return 0
# Egress: outgoing from $IFACE.
sudo tc qdisc add dev "$IFACE" root netem loss "${pct}%" 2>/dev/null || {
echo "Warning: failed to apply egress netem loss on $IFACE."
return 1
}
if [[ "$BIDI" -eq 1 ]]; then
# Ingress: incoming on $IFACE, redirected to $IFB_DEV egress and shaped there.
sudo tc qdisc add dev "$IFACE" handle ffff: ingress 2>/dev/null || {
echo "Warning: failed to add ingress qdisc on $IFACE."
return 1
}
sudo tc filter add dev "$IFACE" parent ffff: protocol all u32 \
match u32 0 0 action mirred egress redirect dev "$IFB_DEV" 2>/dev/null || {
echo "Warning: failed to install ingress redirect filter."
return 1
}
sudo tc qdisc add dev "$IFB_DEV" root netem loss "${pct}%" 2>/dev/null || {
echo "Warning: failed to apply netem on $IFB_DEV."
return 1
}
fi
}
netem_init || true
step "Building ($BUILD)"
if [[ "$BUILD" == "release" ]]; then
if [[ "$RUN_SIMULATOR" -eq 1 ]]; then
@@ -84,9 +149,7 @@ done
cleanup() {
[[ -n "${SIM_PID:-}" ]] && kill -TERM "$SIM_PID" 2>/dev/null || true
[[ -n "${SUBSTRATE_PID:-}" ]] && kill -TERM "$SUBSTRATE_PID" 2>/dev/null || true
if [[ "$HAS_TC" -eq 1 ]]; then
sudo tc qdisc del dev $IFACE root 2>/dev/null || true
fi
netem_clear
wait 2>/dev/null || true
}
trap cleanup EXIT INT TERM
@@ -115,15 +178,8 @@ for entities in "${ENTITIES_LIST[@]}"; do
devices=$(( entities / 7 ))
for loss in "${LOSS_LIST[@]}"; do
# Apply tc netem loss
if [[ "$HAS_TC" -eq 1 ]]; then
sudo tc qdisc del dev $IFACE root 2>/dev/null || true
if [[ "$loss" -gt 0 ]]; then
sudo tc qdisc add dev $IFACE root netem loss ${loss}% 2>/dev/null || {
echo "Warning: failed to apply tc netem loss on interface $IFACE."
}
fi
fi
# Apply tc-netem loss in both directions (or egress-only when BIDI=0).
netem_apply "$loss"
if [[ "$RUN_SIMULATOR" -eq 1 ]]; then
sim_args=(
@@ -178,8 +234,6 @@ for entities in "${ENTITIES_LIST[@]}"; do
done
done
if [[ "$HAS_TC" -eq 1 ]]; then
sudo tc qdisc del dev $IFACE root 2>/dev/null || true
fi
netem_clear
printf '\n%sCSV written to:%s %s\n' "$DIM" "$RESET" "$OUT_CSV"