Skip to content

Instantly share code, notes, and snippets.

@joshrosso
Last active March 23, 2020 16:26
Show Gist options
  • Save joshrosso/9874b8384a5898b06df2e685438270a5 to your computer and use it in GitHub Desktop.
Save joshrosso/9874b8384a5898b06df2e685438270a5 to your computer and use it in GitHub Desktop.
#!/bin/bash
# This script using tc (`man tc`) to shape egress traffic from a host to specific
# IP CIDR(s).
# RATES Bandwidths or rates. These parameters accept a floating point
# number, possibly followed by either a unit (both SI and IEC units supported),
# or a float followed by a '%' character to specify the rate as a percentage of
# the device's speed (e.g. 5%, 99.5%). Warning: specifying the rate as
# a percentage means a fraction of the current speed; if the speed changes, the
# value will not be recalculated.
#
# default Bits per second
#
# kbit Kilobits per second
#
# mbit Megabits per second
#
# gbit Gigabits per second
#
# tbit Terabits per second
#
# bps Bytes per second
#
# kbps Kilobytes per second
#
# mbps Megabytes per second
#
# gbps Gigabytes per second
#
# tbps Terabytes per second
#
#
# Location of tc command
TC=/sbin/tc
# Network Interface (`ip a`) to shape.
IF=ens160
# Egress limit
UPLD=1mbit
# CIDR ranges
# There should be 1 per target edge network
EDGE_1=3.224.75.242/32 # Edge Site 1 Description
EDGE_2=3.224.75.242/32 # Edge Site 2 Description
# Filter options for limiting the intended interface.
U32="$TC filter add dev $IF protocol ip parent 1:0 prio 1 u32"
create () {
echo "===> Setting up shaping"
# Hierarchical Token Bucket (HTB) is used as it provides bandwidth-based shaping
# HTB The Hierarchy Token Bucket implements a rich linksharing
# hierarchy of classes with an emphasis on conforming to existing
# practices. HTB facilitates guaranteeing bandwidth to classes, while
# also allowing specification of upper limits to inter-class sharing. It
# contains shaping elements, based on TBF and can prioritize classes.
# root qdisc
$TC qdisc add dev $IF root handle 1: htb default 30
echo "===> Setup root qdisc on $IF"
# child qdiscs
# shapers of bandwidth
# a child qdisc should exist for every edge network
$TC class add dev $IF parent 1: classid 1:1 htb rate $UPLD
$TC class add dev $IF parent 1: classid 1:2 htb rate $UPLD
echo "===> Setup child qdisc(s) on $IF"
# filters for child qdiscs
# matches will go to the classid referenced after flowid
# a filter should exist for every edge network
$U32 match ip dst $EDGE_1 flowid 1:1
$U32 match ip dst $EDGE_2 flowid 1:2
echo "===> Setup filters"
echo "===> Shaping configuration complete"
}
# clean removes *all* existing qdiscs from the target interface
clean () {
echo "===> Deleting existing qdiscs on $IF"
$TC qdisc del dev $IF root
echo "===> Deleted existing qdiscs on $IF"
}
# run script; always clean then create
clean
create
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment