Skip to content

Instantly share code, notes, and snippets.

@akohlbecker
Last active February 6, 2020 13:55
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save akohlbecker/8bd4b615dceefd3507a85010729fa2b4 to your computer and use it in GitHub Desktop.
Save akohlbecker/8bd4b615dceefd3507a85010729fa2b4 to your computer and use it in GitHub Desktop.
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