Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Simulator for bidirectional bad network conditions like packet delay, loss and low data transfer rate using netem.
#!/bin/bash
# Simulator for bidirectional bad network conditions like packet delay, loss and low data transfer rate using netem.
#
# The script must be execuded as super user.
#
# Hosted at https://gist.github.com/akohlbecker/8bd4b615dceefd3507a85010729fa2b4
#
# (Based on https://unix.stackexchange.com/questions/432925/netem-how-to-delay-packets-sent-to-received-from-some-host#434453)
#
DELAY="200ms"
#DELAY_JITTER="20ms"
#DELAY_CORRELATION="25%"
#LOSS="1%"
RATE_MODEM="56kbit"
RATE_ISDN="64kbit"
RATE_ADSL_LIGHT="384mbit"
RATE_ADSL_2PLUS="25mbit"
RATE=$RATE_ISDN
if [ -z $1 ]; then
echo "You must specify the interface device as argument."
echo "The following devices are available:"
netstat -i | tail -n +3 | awk '{print $1}'
exit -1
fi
# Make sure only root can run our script
if [ "$(id -u)" != "0" ]; then
echo "This script must be run as root" 1>&2
exit 1
fi
interface=$1
# add delay only on client side
tc qdisc add dev $interface root netem delay $DELAY $DELAY_JITTER $DELAY_CORRELATION
if [ -n "$RATE" ]; then
tc qdisc change dev $interface root netem rate $RATE
fi
if [ -n "$LOSS" ]; then
tc qdisc change dev $interface root netem loss random $LOSS
fi
# First, create an Intermediate Functional Block
# pseudo-device IFB (ethernet bridge would also work):
modprobe ifb
ip link set dev ifb0 up
# Next, redirect all incoming traffic to go through
# the IFB device first:
tc qdisc add dev $interface ingress
tc filter add dev $interface parent ffff: protocol ip u32 match u32 0 0 flowid 1:1 action mirred egress redirect dev ifb0
# Now just add delay to the IFB device's outgoing traffic,
# which is now the incoming traffic to $interface:
printf "\nSettings applied:\n"
tc qdisc add dev ifb0 root netem delay $DELAY $DELAY_JITTER $DELAY_CORRELATION
echo "Delay $DELAY $DELAY_JITTER $DELAY_CORRELATION set to $interface"
if [ -n "$RATE" ]; then
tc qdisc change dev ifb0 root netem rate $RATE
echo "Rate $RATE set to $interface"
fi
if [ -n "$LOSS" ]; then
tc qdisc change dev ifb0 root netem loss random $LOSS
echo "Loss random $LOSS set to $interface"
fi
printf "\nResulting configuration:\n"
tc qdisc show | egrep "$interface|ifb0"
echo ""
while [ "$input" != "r" ]
do
read -s -p "Reset the network adapter to normal state? [r]" input
echo ""
done
tc qdisc delete dev ifb0 root netem
tc filter delete dev $interface parent ffff:
tc qdisc delete dev $interface ingress
ip link set dev ifb0 down
tc qdisc delete dev $interface root netem
modprobe -r ifb
echo "Network adapter $interface restored to intial state:"
tc qdisc show | egrep "$interface|ifb0"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment