Limitando largura de banda com o CBQ
Publicado por Romulo 23/09/2003
[ Hits: 45.324 ]
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
Jftp Script - Script para automação de um processo FTP
Inserção de máquinas no banco de dados para controle interno
Ver último twitter pelo terminal ou na barra de notificação
Script para correção de arquivos Makefile usando comando patch
Enviar mensagem ao usuário trabalhando com as opções do php.ini
Meu Fork do Plugin de Integração do CVS para o KDevelop
Compartilhando a tela do Computador no Celular via Deskreen
Como Configurar um Túnel SSH Reverso para Acessar Sua Máquina Local a Partir de uma Máquina Remota
Configuração para desligamento automatizado de Computadores em um Ambiente Comercial
Compartilhamento de Rede com samba em modo Público/Anônimo de forma simples, rápido e fácil
Cups: Mapear/listar todas as impressoras de outro Servidor CUPS de forma rápida e fácil
Criando uma VPC na AWS via CLI
Tem como instalar o gerenciador AMD Adrenalin no Ubuntu 24.04? (6)