Created
March 11, 2021 13:57
-
-
Save Aposhian/11741f4b81c4385ad3ca308edb0911f7 to your computer and use it in GitHub Desktop.
Simulate a lossy network connection
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
#!/usr/bin/env bash | |
[ "$(id -u)" != "0" ] && echo "Please run as root" && exit 1 | |
function usage { | |
echo "Usage: | |
./simulate_bad_connection.sh (-a | --address) <dest-ip-address> | |
[ -d | --delay ] <delay-in-ms> | |
[ -t | --timeout ] <timeout-seconds> | |
" | |
} | |
OPTIONS="$(getopt --name simulate_bad_connection --options ha:d:t: --longoptions help,address:,delay:,timeout: -- "$@")" | |
DELAY=400 # ms | |
TIMEOUT=300 # seconds | |
if [ $? != 0 ]; then | |
# Incorrect options provided | |
usage | |
exit 1 | |
fi | |
eval set -- "$OPTIONS" | |
while true; do | |
case "$1" in | |
-h | --help) | |
echo "Simulate a bad connection with tc and netem" | |
usage | |
exit | |
;; | |
-a | --address) | |
shift | |
DEST_ADDRESS="$1" | |
;; | |
-d | --delay) | |
shift | |
DELAY="$1" | |
;; | |
-t | --timeout) | |
shift | |
TIMEOUT="$1" | |
;; | |
--) | |
shift | |
break | |
;; | |
esac | |
shift | |
done | |
if [ -z "$DEST_ADDRESS" ]; then | |
echo "Please provide a destination address" | |
usage | |
exit 1 | |
fi | |
NETWORK_INTERFACE="$(arp | grep $DEST_ADDRESS | awk '{ print $5 }')" | |
if [ -z "$NETWORK_INTERFACE" ]; then | |
echo "Could not find network interface for address: $DEST_ADDRESS" | |
exit 1 | |
fi | |
# This restores the network | |
function finish { | |
echo " | |
Restoring network on interface: $NETWORK_INTERFACE" | |
# Restore outgoing traffic | |
tc qdisc delete dev $NETWORK_INTERFACE root netem &> /dev/null | |
# Restore incoming traffic | |
tc qdisc delete dev ifb0 root netem &> /dev/null | |
tc qdisc delete dev $NETWORK_INTERFACE ingress &> /dev/null | |
ip link set dev ifb0 down &> /dev/null | |
} | |
# This makes it run when the script exits, no matter how | |
trap finish EXIT | |
echo "Simulating bad connection on interface: $NETWORK_INTERFACE" | |
# Filter outgoing traffic | |
tc qdisc add dev $NETWORK_INTERFACE root netem \ | |
delay ${DELAY}ms 20ms distribution normal \ | |
loss 0.5% 25% \ | |
corrupt 0.1% \ | |
reorder 25% 50% | |
# Filter incoming traffic | |
# https://wiki.linuxfoundation.org/networking/netem#how_can_i_use_netem_on_incoming_traffic | |
modprobe ifb | |
ip link set dev ifb0 up | |
tc qdisc add dev $NETWORK_INTERFACE ingress | |
tc filter add dev $NETWORK_INTERFACE parent ffff: protocol ip u32 match u32 0 0 flowid 1:1 action mirred egress redirect dev ifb0 | |
tc qdisc add dev ifb0 root netem \ | |
delay ${DELAY}ms 20ms distribution normal \ | |
loss 0.5% 25% \ | |
corrupt 0.1% \ | |
reorder 25% 50% | |
# Wait | |
echo "Network will restore in $TIMEOUT seconds, or when this script exits" | |
sleep $TIMEOUT | |
# finish will be called here |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment