Created
January 5, 2023 16:33
-
-
Save scoky/a096f5bd5381024da79f4ca6f4ccfa9f to your computer and use it in GitHub Desktop.
Adding simulate network delay, jitter, and loss
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
network_simulate() { | |
[ $# -ne 3 ] && echo 'usage: loss (fraction) delay (ms) jitter (ms)' && return 0 | |
loss=$1 | |
delay=$2 | |
jitter=$3 | |
if [ "$loss" != "0" ]; then | |
# Rather than drop, use NFQUEUE. | |
# Drop is detected by the application as an error and may trigger a retry, negating the impact of probabilistic loss. | |
# NFQUEUE moves the packets to a queue (666 here) which, because it is unread, silently drops the packets on overflow. | |
iptables -A INPUT -m statistic --mode random --probability $loss -s $REMOTE_IP -j NFQUEUE --queue-num 666 | |
iptables -A OUTPUT -m statistic --mode random --probability $loss -d $REMOTE_IP -j NFQUEUE --queue-num 666 | |
# N.B. using iptables to simulate loss because, like DROP, loss using tc is also detected by applications. | |
fi | |
if [ "$delay" != "0" ]; then | |
# Construct the filter parameters for delay and jitter | |
filter="delay ${delay}ms" | |
if [ "$jitter" != "0" ]; then | |
# This is uniform jitter. Others are possible. | |
# N.B. jitter can cause packet reordering | |
filter="$filter ${jitter}ms" | |
fi | |
# Simulate egress properties | |
tc qdisc add dev $INTERFACE root handle 1: prio | |
tc filter add dev $INTERFACE parent 1:0 protocol ip prio 1 u32 match ip dst $REMOTE_IP flowid 2:1 | |
tc qdisc add dev $INTERFACE parent 1:1 handle 2: netem $filter | |
# Simulate ingress properties | |
tc qdisc add dev $INTERFACE ingress | |
# Need to create $IFB first, e.g.,: | |
# ip link add name $IFB type ifb | |
# ip link set dev $IFB up | |
tc filter add dev $INTERFACE parent ffff: protocol ip u32 match ip src $REMOTE_IP flowid 1:1 action mirred egress redirect dev $IFB | |
tc qdisc add dev $IFB root netem $filter | |
fi | |
} | |
network_simulate_clean() { | |
[ $# -ne 3 ] && echo 'usage: loss (fraction) delay (ms) jitter (ms)' && return 0 | |
loss=$1 | |
delay=$2 | |
jitter=$3 | |
if [ "$delay" != "0" ]; then | |
# Delete tc configuration | |
tc qdisc del dev $INTERFACE root | |
tc qdisc del dev $INTERFACE ingress | |
tc qdisc del dev $IFB root | |
fi | |
if [ "$loss" != "0" ]; then | |
# Delete ingress/egress loss rules | |
iptables -D INPUT -m statistic --mode random --probability $loss -s $REMOTE_IP -j NFQUEUE --queue-num 666 | |
iptables -D OUTPUT -m statistic --mode random --probability $loss -d $REMOTE_IP -j NFQUEUE --queue-num 666 | |
fi | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment