Skip to content

Instantly share code, notes, and snippets.

@bb01100100
Created March 17, 2021 23:59
Show Gist options
  • Save bb01100100/05c460fb1810794c345c79d0311ebaa3 to your computer and use it in GitHub Desktop.
Save bb01100100/05c460fb1810794c345c79d0311ebaa3 to your computer and use it in GitHub Desktop.
Introduce networking delay, packet loss, or restrict bandwidth to specified destinations on a linux host.
#!/usr/bin/env bash
# Author: Kel Graham
# Date: 2021-03-17
# Purpose:
# This script uses the linux traffic control `tc` command to add delay, drop packets, etc
# which is useful when we want to test software behaviour under stress conditions, e.g.
# such as spiking latency between Zookeeper or Kafka nodes, simulating a data centre outage
# or restricting bandwidth between components to simulate inter-DC resource contention.
latency_ms=50
jitter=5
packet_loss_percent=1
network_interface=etho0
# Shared Env zookeepers; these can be as broad or specific as needed
subnets='10.0.0.1/32 10.0.2.0/16 10.0.3.15/32'
ACTION="$1"
TYPE="$2"
# Default to adding latency between subnets.
if [ -z "$TYPE" ]; then
TYPE="delay"
fi
if [ "$ACTION" == "enable" ] || [ "$ACTION" == "start" ]; then
# Will complain if it already exists
/usr/sbin/tc qdisc add dev ${network_interface} root handle 1: prio > /dev/null
echo "Setting queuing discipline..."
if [ "$TYPE" == "delay" ]; then
/usr/sbin/tc qdisc add dev ${network_interface} parent 1:1 handle 10: sfq #> /dev/null
/usr/sbin/tc qdisc add dev ${network_interface} parent 1:2 handle 20: sfq #> /dev/null
/usr/sbin/tc qdisc add dev ${network_interface} parent 1:3 handle 30: netem delay ${latency_ms}ms ${jitter}ms 20.00 #> /dev/null
for subnet in $subnets; do
echo "Setting up traffic control for ${subnet}..."
/usr/sbin/tc filter add dev ${network_interface} protocol ip parent 1:0 prio 1 u32 match ip dst ${subnet} flowid 1:3 #> /dev/null
done
elif [ "$TYPE" == "drop" ]; then
#echo "1..."
#/usr/sbin/tc qdisc add dev ${network_interface} root handle 1: prio
echo "2..."
/usr/sbin/tc qdisc add dev ${network_interface} parent 1:1 handle 10: sfq #> /dev/null
/usr/sbin/tc qdisc add dev ${network_interface} parent 1:2 handle 20: sfq #> /dev/null
/usr/sbin/tc qdisc add dev ${network_interface} parent 1:3 handle 30: netem loss 100%
echo "3..."
for subnet in $subnets; do
echo "Setting up traffic control for ${subnet}..."
/usr/sbin/tc filter add dev ${network_interface} protocol ip parent 1:0 prio 1 u32 match ip dst ${subnet} flowid 1:3 #> /dev/null
done
fi
elif [ "$ACTION" == "disable" ] || [ "$ACTION" == "stop" ]; then
echo "Stopping traffic control..."
/usr/sbin/tc qdisc del dev ${network_interface} root
elif [ -z "$ACTION" ]; then
echo "Usage $0 start [delay | drop]"
echo " stop"
exit 0
else
echo "No clue what to do with ${ACTION} command."
exit 1
fi
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment