Last active
August 29, 2022 23:27
-
-
Save andrewhodel/9b5ec6805d202ca84cc1a2db7d424355 to your computer and use it in GitHub Desktop.
network congestion steps (latency and loss) for linux (iptables and tc)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/sh | |
remove_rules() | |
{ | |
echo "removing iptables and tc rules" | |
sudo iptables -F | |
echo "removing tc qdisc for ${netif}" | |
sudo tc qdisc del dev ${netif} root | |
} | |
ctrl_c() | |
{ | |
# remove rules | |
remove_rules | |
# exit | |
exit 0 | |
} | |
trap ctrl_c INT | |
ip="${2}" | |
netif="${1}" | |
cycle_duration_seconds=120 | |
rejected_step_percent=5 | |
rejected_step_current_percent=85 | |
latency_step_ms=500 | |
latency_max=4000 | |
latency_first=500 | |
latency_current=${latency_first} | |
if [[ -z "${ip}" ]] | |
then | |
echo "An IP Address is required as the second argument." | |
exit 1 | |
fi | |
if [[ -z "${netif}" ]] | |
then | |
echo "An interface name is required as the first argument." | |
exit 1 | |
fi | |
duration=0 | |
((duration=${cycle_duration_seconds}*(${latency_max}/${latency_step_ms}))) | |
echo "Executing network congestion for ${ip}" | |
echo -e "\tduration per rejected packet step: ${rejected_step_current_percent}% to 0% at ${rejected_step_percent}%: ${duration}s" | |
echo -e "\tlatency range per rejected packet step: ${latency_current}ms to ${latency_max}ms at ${latency_step_ms}ms per latency step" | |
echo -e "\tTest your network code during this time, the levels are printed to the console to allow you to repeat network conditions that cause problems and fix them." | |
echo "" | |
while [[ "$rejected_step_current_percent" > "0" ]] | |
do | |
# drop % of traffic through range | |
remove_rules | |
if [[ "${rejected_step_current_percent}" == "100" ]] | |
then | |
# from IP | |
sudo iptables -I INPUT -m statistic --mode random --probability 1 -s ${ip} -j REJECT | |
# to IP | |
sudo iptables -I OUTPUT -m statistic --mode random --probability 1 -d ${ip} -j REJECT | |
else | |
# from IP | |
sudo iptables -I INPUT -m statistic --mode random --probability 0.${rejected_step_current_percent} -s ${ip} -j REJECT | |
# to IP | |
sudo iptables -I OUTPUT -m statistic --mode random --probability 0.${rejected_step_current_percent} -d ${ip} -j REJECT | |
fi | |
while [[ ${latency_current} -lt ${latency_max} ]] | |
do | |
# set latency through range | |
# remove existing queues | |
echo "removing tc qdisc for ${netif}" | |
sudo tc qdisc del dev ${netif} root | |
sudo tc qdisc add dev ${netif} root handle 1: prio | |
sudo tc qdisc add dev ${netif} parent 1:3 handle 30: netem delay ${latency_current}ms | |
sudo tc filter add dev ${netif} protocol ip parent 1:0 prio 3 u32 match ip dst ${ip} flowid 1:3 | |
sudo tc filter add dev ${netif} protocol ip parent 1:0 prio 3 u32 match ip src ${ip} flowid 1:3 | |
echo "latency: ${latency_current}ms with ${rejected_step_current_percent}% traffic rejected to and from ${ip} for ${cycle_duration_seconds} seconds." | |
# wait for the cycle | |
sleep ${cycle_duration_seconds} | |
# increase the step value of latency | |
((latency_current=${latency_current}+${latency_step_ms})) | |
done | |
# increase the step value of drop percent | |
((rejected_step_current_percent=${rejected_step_current_percent}+${rejected_step_percent})) | |
# reset latency step to first value | |
latency_current=${latency_first} | |
done | |
remove_rules |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment