Gentoo Forums
Gentoo Forums
Gentoo Forums
Quick Search: in
Traffic Control Next Generation (TCNG) init script
View unanswered posts
View posts from last 24 hours

 
Reply to topic    Gentoo Forums Forum Index Documentation, Tips & Tricks
View previous topic :: View next topic  
Author Message
SkyBeam
n00b
n00b


Joined: 27 Nov 2006
Posts: 6
Location: Switzerland

PostPosted: Sun Jan 14, 2007 10:38 pm    Post subject: Traffic Control Next Generation (TCNG) init script Reply with quote

Hi all,

This weekend I set up my first Gentoo-based server by migrating my Rad-Hat-based Server. I was used to use TC/TCNG to control internet bandwidth. Especially to ensure that interactive communication gets higher priority when power-users/downloaders are on the net.

I tried to emerge 'tcng' but it did not work since it had a dependency on linux-atm which did not compile on my AMD64 linux box (seems to work for kernel 2.5 only (I am using linux-2.6.18-gentoo-r6).

So that's what I tried:
Code:
# emerge iproute2
# echo "sys-apps/tcng ~* *" >> /etc/portage/package.keywords
# emerge -O tcng


After this did not work I downloaded and installed TCNG manually from the TCNG homepage, compiled and installed it.

After that I noticed that there is no Gentoo init-script available. I remembered that it was already a problem years ago when I installed it on Red-Hat. At this time I found a tcng-init script somewhere on the net. For Gentoo I was unable to locate such a script and therefore I wrote my own one (of course based on tcng-init). In order not to get lost and to be helpful for somebody else here's the code.

Put this to /etc/init.d/tcng:
Code:
#!/sbin/runscript
# Distributed under the terms of the GNU General Public License v2

# path to the directory where all config files are stored
TCCONFBASEDIR=${TCCONFBASEDIR:-/etc/tcng}

# main configuration file
# note that more configuration files can be acquired by the #include directive
TCCONF=${TCCONF:-${TCCONFBASEDIR}/tcng.conf}

# enable/disable statisitcal output
# TCSTATS=${TCSTATS:-yes}
TCSTATS=${TCSTATS:-no}

# debug level
# typical startup script usage
TCDEBUG=${TCDEBUG:-0}
# more information about what's going on
# TCDEBUG=${TCDEBUG:-1}
# real debugging information
# TCDEBUG=${TCDEBUG:-2}

# make sure path is exported correctly
export PATH=$PATH:/usr/local/bin

# path to the 'tc' binary
TC=${TC:-`which tc`}

# path to the tcc binary
TCC=${TCC:-`which tcc`}

PRINTSTATS=""
[ "$TCSTATS" = "yes" ] && PRINTSTATS="-s"

# get a list of deivces
devs=`ifconfig -a | awk '/^\w+:/ || /^lo/ {next}; /^[a-z]/{print $1}'`

# advertise optional commands
opts="show status"

# helper functions

error() {
        echo "$@" >&2
}
inform() {
        [ $TCDEBUG -ge 1 ] && error "$@"
}
debug() {
        [ $TCDEBUG -ge 2 ] && error "$@"
}

# ###
# returns 0 if the qdisc is located on the specified device
# ###
isup() {
        local device=$1
        local qtype=$2
        if [ "$qtype" = "ingress" ]; then
                $TC qdisc show dev $device 2>/dev/null | grep -q $qtype && return 0
                # no ingress qdisc, return 0
                return 1
        fi

        #
        # -- sadly, we break our nice symmetry, because the "root" qdisc
        #    can sometimes be a dsmark qdisc....so; let's account for it
        #
        $TC qdisc show dev $device 2>/dev/null | grep -q root   && return 0
        $TC qdisc show dev $device 2>/dev/null | grep -q dsmark && return 0

        # if no qdiscs could be found
        return 1;
}

# ###
# check if an ingress or root qdisc exists on the specified interface
# returns 0 if true, 1 if no such qdisc exists
# ###
exist_qdisc() {
        local device=$1
        isup $device ingress && return 0
        isup $device root && return 0
        return 1
}

# ###
# tests if a qdisc exists and removes it if found
# ###
clearqdisc() {
        local device=$1
        local qtype=$2
        RETURNVALUE=0
        isup $device $qtype
        if [ $? -eq 0 ]; then
                inform "Removing $qtype qdisc: $device"
                $TC qdisc del dev $device $qtype 2>/dev/null
                [ $? -ne 0 ] && RETURNVALUE=$?
        else
                inform "No $qtype qdisc running on device: $device"
        fi
        return $RETURNVALUE
}

# ###
# checks syntax of configuration file
# returns 0 if everything is fine, 1 otherwise
# ###
syntaxcheck() {
        local RETURNVALUE=0
        if [ -z "$TCCONF" -o ! -r "$TCCONF" ]; then
                error "Error: Config file at '$TCCONF' has to be readable, please check \$TCCONF"
                RETURNVALUE=1
        fi

        $TCC -c $TCCONF >/dev/null 2>&1
        if [ $? -ne 0 ]; then
                error "syntax errror in '$TCCONF', make sure \$TCCONF is set"
                RETURVNALUE=1
        fi
        return $RETURNVALUE
}


# main functions

depend() {
        after net
        # use logger
}

start() {
        # get devices if passed as parameter
        [ $# -ne 0 ] && local devs=$@

        ebegin "Starting traffic shaping (TCNG)"
        debug "checking syntax of configuration file"
        syntaxcheck
        local RETURNVALUE=$?

        if [ $RETURNVALUE -eq 0 ]; then
                debug "test for active qdiscs on devices in $TCCONF"
                # for device in `$TCC $TCCONF | grep -e '^tc' | cut -d" " -f5 | uniq | sort`; do
                for device in `$TCC $TCCONF | awk '/^tc/{ print $5 }' | uniq | sort`; do
                        exist_qdisc $device
                        if [ $? -eq 0 ]; then
                                error "found active traffic control on device $device"
                                error "device $device is used in $TCCONF"
                                error "remove traffic control with \"$0 stop $device\""
                                error "consider also \"$0 restart\" or \"$0 flush\""
                                RETURNVALUE=1
                        fi
                done

                # parse the tcng config file and spit it through a little loop which executes
                # the tc commands one at a time
                if [ $RETURNVALUE -eq 0 ]; then
                        $TCC $TCCONF | grep -Ev "^#|^$" | sed -e "s/^tc//" | {
                                while read cmd; do
                                        # inform user we are adding qdisc to devices when new
                                        # new devices are found
                                        thisdev=`echo $cmd | awk '/root/{print $4}'`
                                        [ "$thisdev" = "" ] || inform "adding root qdisc to $thisdev"
                                        thisdev=`echo $cmd | awk '/ingress/{print $4}'`
                                        [ "$thisdev" = "" ] || inform "adding ingress qdisc to $thisdev"

                                        # if necessary this will print the command just prior to
                                        # execution
                                        debug "executing: $cmd"
                                        $TC $cmd
                                        [ $? -ne 0 ] && RETURNVALUE=$?
                                done
                        }
                fi
        fi
        eend $RETURNVALUE
}

stop() {
        [ $# -ne 0 ] && local devs=$@
        ebegin "Stopping traffic shaping (TCNG)"
        STATUS=0
        for device in $devs; do
                inform "stopping traffic control on: $device"
                clearqdisc $device ingress
                [ $? -ne 0 ] && STATUS=$?
                clearqdisc $device root
                [ $? -ne 0 ] && STATUS=$?
        done
        eend $STATUS
}

status() {
        [ $# -ne 0 ] && local devs=$*
        ebegin "Check traffic shaping (TCNG)"
        STATUS=0
        for device in $devs; do
                exist_qdisc $device
                if [ $? -eq 0 ]; then
                        error "traffic control on $device enabled"
                else
                        error "traffic control on $device disabled"
                        STATUS=1
                fi
        done
        eend $STATUS
}

show() {
        ebegin "Show current traffic shaping (TCNG) settings"
        WHAT=all
        if [ $# -gt 0 ]; then
                case "$1" in
                        qdisc|class|filter)
                                what=$1
                                shift
                        ;;
                esac
                [ $# -gt 0 ] && local devs=$@
        fi
        for device in $devs; do
                isup $device root
                if [ $? -eq 0 ]; then
                        for OBJ in qdisc class filter; do
                                [ "$WHAT" = "all" -o "$WHAT" = "$OBJ" ] \
                                        && $TC $stats $OBJ show dev $device
                        done
                fi
        done
        eend 0
}


Additionally put the following to /etc/conf.d/tcng:
Code:
# configuration for TCNG (Trafic Control Next Generation)

# path to the directory where all config files are stored
TCCONFBASEDIR=${TCCONFBASEDIR:-/etc/tcng}

# main configuration file
# note that more configuration files can be acquired by the #include directive
TCCONF=${TCCONF:-$TCCONFBASEDIR/tcng.conf}

# enable/disable statisitcal output
# TCSTATS=${TCSTATS:-yes}
TCSTATS=${TCSTATS:-no}

# debug level
# typical startup script usage
TCDEBUG=${TCDEBUG:-0}
# more information about what's going on
# TCDEBUG=${TCDEBUG:-1}
# real debugging information
# TCDEBUG=${TCDEBUG:-2}


And do not forget to add tcng to your default runlevel:
Code:
# rc-update add tcng default


Now just put your config file ($TCCONF) to $TCCONFBASEDIR. By default this will be /etc/tcng/tcng.conf (see /etc/conf.d/tcng above).

I hope this will be useful for somebody else as well.
_________________
SkyBeam :: the sky isn't the limit
Back to top
View user's profile Send private message
SeeksTheMoon
Apprentice
Apprentice


Joined: 24 Sep 2003
Posts: 158

PostPosted: Thu Mar 08, 2007 11:54 am    Post subject: Reply with quote

how did you compile tcng? It doesn't compile at all (first it needs a 2.4 or 2.5 kernel and after adding my 2.6 kernel it begins but fails)
Back to top
View user's profile Send private message
SkyBeam
n00b
n00b


Joined: 27 Nov 2006
Posts: 6
Location: Switzerland

PostPosted: Sat Mar 24, 2007 6:32 pm    Post subject: Reply with quote

SeeksTheMoon wrote:
how did you compile tcng? It doesn't compile at all (first it needs a 2.4 or 2.5 kernel and after adding my 2.6 kernel it begins but fails)


Better late than never...

I did the following:

Code:

# emerge iproute2
# echo "sys-apps/tcng ~* *" >> /etc/portage/package.keywords
# emerge -O tcng


However you're right this dis NOT compile at all.
So I went to the tcng homepage and downlaoded the latest sources (10b at that time), compiled it:

Quote:

# cd /usr/src
# gunzip -c /path/to/sources.tar.gz | tar xvf -
# cd tcng tcng-10b
# ./configure && make && make install


Then I wrote the script I posted above to /etc/init.d/tcng and installed /etc/conf.d/tcng (quoted above) and added tcng to default runlevel:
Quote:

# rc-update add tcng default


That's it.

HTH
_________________
SkyBeam :: the sky isn't the limit
Back to top
View user's profile Send private message
SeeksTheMoon
Apprentice
Apprentice


Joined: 24 Sep 2003
Posts: 158

PostPosted: Sun Mar 25, 2007 12:24 am    Post subject: Reply with quote

in the meantime I installed debian in VirtualBox and experimented with their tcng package but not all the rules produced by tcng are usable by a modern tc version which makes all rules worthless. I think it's best to follow the advice from their mailinglist: "tcng is dead, learn tc"...
Back to top
View user's profile Send private message
Display posts from previous:   
Reply to topic    Gentoo Forums Forum Index Documentation, Tips & Tricks All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum