Limitando largura de banda com o CBQ
Publicado por Romulo 23/09/2003
[ Hits: 45.791 ]
Script usado para limitar largura de banda com o CBQ.
#!/bin/sh
PATH="/bin:/sbin:/usr/bin:/usr/sbin"
CBQ_PATH="/etc/sysconfig/cbq"
### Uncomment for debugging
#LOG_FILE="/var/run/cbq-$1"
if [ -n "$LOG_FILE" ]; then
### Initialize log file
echo "# `date`" > $LOG_FILE
### Logging equivalent of "ip" command
ip () {
[ -z "$LOG_FILE" ] && { /sbin/ip "$@"; return; }
echo -e "\nip $@\n" >> $LOG_FILE
/sbin/ip "$@" 2>&1 | tee -a $LOG_FILE
} # ip
### Logging equivalent of "tc" command
tc () {
[ -z "$LOG_FILE" ] && { /sbin/tc "$@"; return; }
echo -e "\ntc $@\n" >> $LOG_FILE
/sbin/tc "$@" 2>&1 | tee -a $LOG_FILE
} # tc
fi # command logging
### Remove CBQ from all devices
cbq_off () {
for dev in `ip link| sed -n '/^[0-9]/ { s/^[0-9]\+:
\([a-z0-9]\+\)[:@].*/\1/; p; }'`; do
cbq_device_off $dev
done
return
} # cbq_off
### Remove root class from device $1
cbq_device_off () {
tc qdisc del dev $1 root &>/dev/null
return
} # cbq_device_off
### Display CBQ setup
cbq_show () {
for dev in $DEVICES; do
echo ---[ $dev: configured classes ]---------------------------
echo; tc $1 class show dev $dev; echo
echo ---[ $dev: queueing disciplines ]-------------------------
echo; tc $1 qdisc show dev $dev; echo
done
} # cbq_show
### Check configuration and load DEVFIELDS/CLASSLIST
cbq_init () {
### Check configuration in $CBQ_PATH directory and get CLASSLIST
CLASSLIST=`find $CBQ_PATH -name 'cbq-*' -maxdepth 1 -printf "%f\n"| sort`
if [ -z "$CLASSLIST" ]; then
echo "**CBQ: not configured in $CBQ_PATH!"
exit
fi
### Collect all DEVICE fields from $CBQ_PATH/cbq-*
DEVFIELDS=`find $CBQ_PATH -name 'cbq-*' -maxdepth 1 -exec sed -ne\
's/#.*//; s/ //g; /^DEVICE=.*,.*,.*/ { s/.*=//; p; q; }; \
/^DEVICE=/ q' {} \;| sort -u`
### Check if there are any devices to set up
if [ -z "$DEVFIELDS" ]; then
echo "**CBQ: can't find any DEVICE field in $CBQ_PATH/cbq-*!"
exit
fi
### Extract all device names from DEVICE fields in $CBQ_PATH/cbq-*
DEVICES=`echo "$DEVFIELDS"| sed 's/,.*//'| sort -u`
### Check for multiple devices with different DEVICE fields
if [ `echo "$DEVICES"| wc -l` -ne `echo "$DEVFIELDS"| wc -l` ]; then
echo "**CBQ: multiple different DEVICE fields for one device found!"
echo "$DEVFIELDS"
exit
fi
} # cbq_init
### Load class configuration from file $1
cbq_load_class () {
CNAME="$CBQ_PATH/$1"
CFILE=`sed -e 's/#.*//; s/ //g; /^$/ d' $CNAME`
CLASS=`echo $1| sed 's/^cbq-0*//; s/\..*//'`
if [ `/usr/bin/printf "%d" 0x$CLASS` -le 1 ]; then
echo "**CBQ: class ID of $1 must be > 1!"
cbq_off
exit
fi
### Device parameters
DEVICE=`echo "$CFILE"| sed -n '/^DEVICE=/ { s/.*=//; s/,.*//; p; q; }'`
BANDWIDTH=`echo "$DEVFIELDS"| sed -n "/^$DEVICE,/ { s/.*,\(.*\),.*/\1/; p; q; }"`
### Class parameters
CLASSID="1:$CLASS"
PARENT=`echo "$CFILE"| sed -n '/^PARENT=/ { s/.*=0*//; p; q; }'`
[ -z "$PARENT" ] && PARENT="1:1" || PARENT="1:$PARENT"
LEAF=`echo "$CFILE"| sed -n '/^LEAF=/ { s/.*=//; p; q; }'`
[ -z "$LEAF" ] && LEAF="tbf"
BOUNDED=`echo "$CFILE"| sed -n '/^BOUNDED=/ { s/.*=//; p; q; }'`
[ "$BOUNDED" = "no" ] && BOUNDED="" || BOUNDED="bounded"
ISOLATED=`echo "$CFILE"| sed -n '/^ISOLATED=/ { s/.*=//; p; q; }'`
[ "$ISOLATED" = "yes" ] && ISOLATED="isolated" || ISOLATED=""
PRIO=`echo "$CFILE"| sed -n '/^PRIO=/ { s/.*=//; p; q; }'`
RATE=`echo "$CFILE"| sed -n '/^RATE=/ { s/.*=//; p; q; }'`
WEIGHT=`echo "$CFILE"| sed -n '/^WEIGHT=/ { s/.*=//; p; q; }'`
if [ -z "$RATE" -o -z "$WEIGHT" -o -z "$PRIO" ]; then
echo "**CBQ: missing RATE, WEIGHT or PRIO field(s) in $1!"
cbq_off
exit
fi
### Leaf qdisc parameters for TBF
if [ "$LEAF" = "tbf" ]; then
BUFFER=`echo "$CFILE"| sed -n '/^BUFFER=/ { s/.*=//; p; q; }'`
[ -z "$BUFFER" ] && BUFFER="10Kb/8"
LIMIT=`echo "$CFILE"| sed -n '/^LIMIT=/ { s/.*=//; p; q; }'`
[ -z "$LIMIT" ] && LIMIT="15Kb"
PEAK=`echo "$CFILE"| sed -n '/^PEAK=/ { s/.*=//; p; q; }'`
[ -n "$PEAK" ] && PEAK="peakrate $PEAK"
MTU=`echo "$CFILE"| sed -n '/^MTU=/ { s/.*=//; p; q; }'`
[ -z "$MTU" ] && MTU="1500"
elif [ "$LEAF" = "sfq" ]; then
PERTURB=`echo "$CFILE"| sed -n '/^PERTURB=/ { s/.*=//; p; q; }'`
[ -n "$PERTURB" ] && PERTURB="perturb $PERTURB"
QUANTUM=`echo "$CFILE"| sed -n '/^QUANTUM=/ { s/.*=//; p; q; }'`
[ -n "$QUANTUM" ] && QUANTUM="quantum $QUANTUM"
elif [ "$LEAF" = "cbq" ]; then
echo "**CBQ: class $1, leaf qdisc CBQ not yet supported!"
fi
return 0
} # cbq_load_class
### Check if ip-route is installed
if [ ! -f /sbin/tc -o ! -f /sbin/ip ]; then
echo "**CBQ: ip-route2 utilities not installed!"
exit
fi
########################################################################
# See how were we called #
########################################################################
case "$1" in
### START ###
start)
### If you have cbq, tbf and u32 compiled into kernel, comment it out
for module in sch_cbq sch_tbf sch_sfq sch_prio cls_u32; do
if ! modprobe $module; then
echo "**CBQ: could not load module $module"
exit
fi
done
########################################################################
# Get all devices from configuration files $CBQ_PATH/cbq-* #
# and setup CBQ root classes for them (if it is possible). #
########################################################################
### Load DEVICES, DEVFIELDS and CLASSLIST
cbq_init
### Try to discover interface bandwidth from DEVICE
### field and if OK - setup root class for this one
for dev in $DEVICES; do
### Retrieve device bandwidth and weight
DEVTEMP=`echo "$DEVFIELDS"| sed -n "/^$dev,/ { s/.*,\(.*\),\(.*\)/\1,\2/; p;
q; }"`
DEVBWDT=${DEVTEMP%%,*}
DEVWGHT=${DEVTEMP##*,}
### If correctly set and the device is up, setup root class
if [ -n "$DEVBWDT" -a -n "$DEVWGHT" ]; then
if ! ip link | grep -q "$dev[:@].*UP"; then
echo "**CBQ: could not find device $dev! CBQ turned off."
cbq_off
exit
fi
### Remove old root class from device
cbq_device_off $dev
### Setup root class (queueing discipline) for device
tc qdisc add dev $dev root handle 1:0 cbq \
bandwidth $DEVBWDT avpkt 1000 cell 8
### Create parent class :1. Every shaper will use it as
### parent unless specified otherwise using PARENT=xxxx
tc class add dev $dev parent 1:0 classid 1:1 cbq \
bandwidth $DEVBWDT rate $DEVBWDT weight $DEVWGHT \
prio 8 allot 1514 cell 8 maxburst 20 avpkt 1000
else
echo "**CBQ: could not determine bandwidth or weight for device $dev!"
echo "**CBQ: setup DEVICE field properly!"
exit
fi
done # device
#######################################################################
# Set up all classes described in $CBQ_PATH/cbq-* #
#######################################################################
for classfile in $CLASSLIST; do
cbq_load_class $classfile
### Create class and setup leaf qdisc
tc class add dev $DEVICE parent $PARENT classid $CLASSID cbq \
bandwidth $BANDWIDTH rate $RATE weight $WEIGHT prio $PRIO \
allot 1514 cell 8 maxburst 20 avpkt 1000 $BOUNDED $ISOLATED
### Setup leaf queueing discipline
if [ "$LEAF" = "tbf" ]; then
tc qdisc add dev $DEVICE parent $CLASSID tbf \
rate $RATE buffer $BUFFER limit $LIMIT mtu $MTU $PEAK
elif [ "$LEAF" = "sfq" ]; then
tc qdisc add dev $DEVICE parent $CLASSID sfq \
$PERTURB $QUANTUM
elif [ "$LEAF" = "cbq" ]; then
:
fi
### Create u32 filter for addresses specified by RULE fields
RULESET=`echo "$CFILE"| sed -n '/^RULE/ { s/.*=//; p; }'`
[ -z "$RULESET" ] && continue
### Rules present, parse them
for rule in $RULESET; do
u32_s=""; u32_d=""
SADDR=""; SPORT=""
### Split up destination
DST=${rule##*,}
DADDR=${DST%%:*}
[ "$DADDR" != "$DST" ] && DPORT=${DST##*:} || DPORT=""
[ "$DADDR" = "*" ] && DADDR=""
### Split up source (if specified)
if [ "$DST" != "$rule" ]; then
SRC=${rule%%,*}
SADDR=${SRC%%:*}
[ "$SADDR" != "$SRC" ] && SPORT=${SRC##*:}
[ "$SADDR" = "*" ] && SADDR=""
fi
### Compose the u32 filter rules
[ -n "$SPORT" ] && u32_s="match ip sport $SPORT 0xffff"
[ -n "$SADDR" ] && u32_s="match ip src $SADDR $u32_s"
[ -n "$DPORT" ] && u32_d="match ip dport $DPORT 0xffff"
[ -n "$DADDR" ] && u32_d="match ip dst $DADDR $u32_d"
### Uncomment the following if you want to see parsed rules
# echo "$rule: $u32_s $u32_d"
### Attach u32 filter to the appropriate class
tc filter add dev $DEVICE parent 1:0 protocol ip \
prio 100 u32 $u32_s $u32_d flowid $CLASSID
done ### rule
done ### class file
;;
### TIMECHECK ###
timecheck)
### Load DEVICES, DEVFIELDS and CLASSLIST
cbq_init
### Current time in hh:mm format
TIME_NOW=`date +%k:%M`
TIME_ABS=$[${TIME_NOW%%:*}*60 + ${TIME_NOW##*:}]
### Check every config file for TIME parameter
for classfile in $CLASSLIST; do
TIMERATES=`sed -ne 's/#.*//; s/ //g; /^TIME/ { s/.*=//; p; }'
$CBQ_PATH/$classfile`
[ -z "$TIMERATES" ] && continue
MATCH=0; CHANGE=0;
for timerate in $TIMERATES; do
### Split up TIME parameter
INTERVAL=${timerate%%;*}; PARAMS=${timerate##*;}
BEG_TIME=${INTERVAL%%-*}; END_TIME=${INTERVAL##*-}
### Compute interval boundaries
BEG_ABS=$[${BEG_TIME%%:*}*60 + ${BEG_TIME##*:}]
END_ABS=$[${END_TIME%%:*}*60 + ${END_TIME##*:}]
### Midnight wrap fixup
if [ $BEG_ABS -gt $END_ABS ]; then
[ $TIME_ABS -le $END_ABS ] && TIME_ABS=$[TIME_ABS + 24*60]
END_ABS=$[END_ABS + 24*60]
fi
### If the time matches, remembers params and set flag
if [ $TIME_ABS -ge $BEG_ABS -a $TIME_ABS -lt $END_ABS ]; then
TMP_RATE=${PARAMS%%/*}
TMP_WGHT=${PARAMS#*/}
TMP_PEAK=${TMP_WGHT#*/}
[ "$TMP_PEAK" = "$TMP_WGHT" ] && TMP_PEAK="" || TMP_WGHT={$TMP_WGHT%%/*}
[ -n "$TMP_PEAK" ] && TMP_PEAK="peakrate $TMP_PEAK"
MATCH=1
fi
done ### timerate
cbq_load_class $classfile
### Get current RATE of CBQ class
RATE_NOW=`tc class show dev $DEVICE| sed -n \
"/cbq $CLASSID / { s/.*rate //; s/ .*//; p; q; }"`
[ -z "$RATE_NOW" ] && continue
### Time interval match is found
if [ $MATCH -ne 0 ]; then
### Check if there is any change in class RATE
if [ "$RATE_NOW" != "$TMP_RATE" ]; then
NEW_RATE="$TMP_RATE"
NEW_WGHT="$TMP_WGHT"
NEW_PEAK="$TMP_PEAK"
CHANGE=1
fi
### Match not found, reset to default RATE if necessary
elif [ "$RATE_NOW" != "$RATE" ]; then
NEW_WGHT="$WEIGHT"
NEW_RATE="$RATE"
NEW_PEAK="$PEAK"
CHANGE=1
fi
### If there's a change, replace CBQ class and leaf qdisc
[ $CHANGE -ne 1 ] && continue
### Get leaf qdisc handle
LEAF_HND=`tc class show dev $DEVICE| sed -n \
"/cbq $CLASSID .* leaf / { s/.*leaf //; s/ .*//; p; q; }"`
[ -z "$LEAF_HND" ] && continue
### Replace CBQ class
tc class replace dev $DEVICE classid $CLASSID cbq \
bandwidth $BANDWIDTH rate $NEW_RATE weight $NEW_WGHT prio $PRIO \
allot 1514 cell 8 maxburst 20 avpkt 1000 $BOUNDED $ISOLATED
### Replace leaf qdisc
if [ "$LEAF" = "tbf" ]; then
tc qdisc replace dev $DEVICE handle $LEAF_HND tbf \
rate $NEW_RATE buffer $BUFFER limit $LIMIT mtu $MTU $NEW_PEAK
elif [ "$LEAF" = "sfq" ]; then
### SFQ does not support parameter changes
### yet so it does not need replacing
#tc qdisc replace dev $DEVICE handle $LEAF_HND sfq \
#$PERTURB $QUANTUM
:
elif [ "$LEAF" = "cbq" ]; then
:
fi
echo "**CBQ: $TIME_NOW: class $CLASS on $DEVICE changed rate ($RATE_NOW ->
$NEW_RATE)"
done ### class file
5
;;
### STOP ###
stop)
cbq_off
;;
### RESTART ###
restart)
$0 stop
$0 start
;;
### LIST ###
list)
cbq_init
cbq_show
;;
### STATS ###
stats)
cbq_init
cbq_show -s
;;
### default ###
*)
echo "Usage: " `basename $0` "{start|stop|restart|timecheck|list|stats}"
esac
slackpigs - veja os pacotes que mais ocupam espaço no Slackware
Script para criação de pacotes auto extrator.
SCRIPT PARA AUTOMAÇÃO DE ATUALIZAÇÃO EM AMBIENTE DEBIAN OU DERIVADOS.
Trocar senha de root NO BRACO remotamente
Bashblog v1.0 0 - cria um microblog em HTML5
IA Turbina o Desktop Linux enquanto distros renovam forças
Como extrair chaves TOTP 2FA a partir de QRCODE (Google Authenticator)
Linux em 2025: Segurança prática para o usuário
Desktop Linux em alta: novos apps, distros e privacidade marcam o sábado
Atualizando o Fedora 42 para 43
Como saber se o seu e-mail já teve a senha vazada?
Como descobrir se a sua senha já foi vazada na internet?
E aí? O Warsaw já está funcionando no Debian 13? [RESOLVIDO] (15)
Secure boot, artigo interessante, nada técnico. (4)
copiar library para diretorio /usr/share/..... su com Falha na a... (1)









