Gentoo Forums
Gentoo Forums
Gentoo Forums
Quick Search: in
HOWTO: Bandwidth limiting
View unanswered posts
View posts from last 24 hours

Goto page 1, 2, 3, 4  Next  
Reply to topic    Gentoo Forums Forum Index Documentation, Tips & Tricks
View previous topic :: View next topic  
Author Message
abali
n00b
n00b


Joined: 19 Sep 2004
Posts: 69
Location: Budapest, Hungary

PostPosted: Mon Sep 20, 2004 6:41 pm    Post subject: HOWTO: Bandwidth limiting Reply with quote

Bandwidth limiting howto
Last updated: 10. 07. 2004

0. When do you need this?

You may want to read this howto and implement bandwidth limiting if:

  1. You are running P2P software and want to ensure that your uploads use only bandwidth that is unused otherwise, so they do not slow down your web surfing/etc;
  2. You are running a WEB/FTP/whatever server and consider their traffic to be of a lower priority than your other activites;
  3. You have a DSL connection and experience slowdowns in your downloads when uploading;
  4. If none of these apply but for any reasons you want to control the uplink bandwidth used by your computer or other boxes that you provide network connection for.


1. Introduction

Linux has a very powerful mechanism for controlling network bandwidth usage. As being powerful inevitably implies being complex, this feature is documented in lengthy and exhaustive documents in great details. These documents however can prove to be excessive in their length and language to users who are looking for simple solutions for simple questions. This guide aims to give a short and practical introduction on how to solve some common issues that users tend to experience on an everyday basis.

Before we start, you may want to note what this howto is not about:

  1. First, it will not tell you how to limit the rate at which data is sent to your computer (download rate). See section 7 to find out why is this difficult to implement.
  2. Second, it will not tell you how to limit the total network usage for specific clients (aka. accounting). There are many great software available that will do this for you.
  3. Third, it will not tell you about basic networking concepts, nor will it go into details on advanced topics. This guide is for the "average" user who has a basic understanding of how the TCP/IP protocol works. Those who might find this document excessively simplified are advised to refer to the more comprehensive resources listed below.


2. Prerequisites

For all the examples in this guide to work, you will need the following two packages emerged onto your system:

Code:
$ emerge sys-apps/iproute2
$ emerge net-firewall/iptables


Iptables is not required if you are not going to use advanced methods for classifying network traffic; it is however a useful piece of software that every network-enabled computer shall have installed.

In your kernel, you shall have at least the following options compiled in or as modules:

Code:
Kernel 2.6.x
------------

Device Drivers --> Networking Support --> Networking options
[*] Network packet filtering (replaces ipchains)
QoS and/or fair queueing -->
<M> HTB packet scheduler
<M> SFQ queue
[*] Packet classifier API
<M> Firewall based classifier
<M> U32 Classifier
[*] Traffic policing

Kernel 2.4.x
------------
Networking options --> IP: Netfilter Configuration
<*> IP tables support
Networking options --> QoS and/or fair queueing
<M> HTB packet scheduler
<M> SFQ queue
[*] Packet classifier API
<M> Firewall based classifier
<M> U32 classifier


It is recommended to select everything under QoS and iptables and compile them into modules -- you can never know when you are going to need it.

The HTB packet scheduler is included in the kernel from 2.4.20; should you have an older kernel installed, then come out of your cave and install a recent one. :)

3. How bandwidth limiting works

Bandwidth limiting, more specifically queueing determines the way in which data is sent from your computer. With iproute2 you create so-called classes for the outgoing network traffic (that is called egress) and attach a queueing discipline (qdisc) to these classes that determine how the data is sent from them. By default, your outgoing queue (egress) has no classes and it has a simple queueing discipline that sends your data out in a FIFO (First In, First Out) order. You are free to divide this queue into as many classes and subclasses as you wish, with different queueing disciplines attached to each of them.

Once we have classes for the network traffic, we need to classify the actual network packets into the class we designated for them. This is done with the help of specific rules that may match upon the characteristics of network packets such as the destination IP address or the source port number.

4. Creating classes for bandwidth limiting

The only queueing discipline we are going to use in this guide is the HTB (Hierarchical Token Bucket) qdisc. It was meant as a more understandable, intuitive and faster replacement for the CBQ qdisc, and works indeed in a simple, easy to learn way and scales nicely for more complex solutions.

In this example, we are going to create 3 classes for our outgoing traffic, where each of the classes has a different speed limit set. Explanations follow.

If your network interface for outgoing traffic is not 'eth0', you will need to change it to the appropriate one (eg. ppp0, wlan0).

Code:
$ tc qdisc add dev eth0 root handle 1: htb default 10
$ tc class add dev eth0 parent 1: classid 1:1 htb rate 120kbit burst 6k
$ tc class add dev eth0 parent 1:1 classid 1:10 htb rate 120kbit burst 6k prio 1
$ tc class add dev eth0 parent 1:1 classid 1:20 htb rate  60kbit burst 6k prio 2
$ tc class add dev eth0 parent 1:1 classid 1:30 htb rate  30kbit burst 6k prio 3
$ tc qdisc add dev eth0 parent 1:10 handle 10: sfq perturb 10
$ tc qdisc add dev eth0 parent 1:20 handle 20: sfq perturb 10
$ tc qdisc add dev eth0 parent 1:30 handle 30: sfq perturb 10


Let's see these commands explained.

Code:
$ tc qdisc add dev eth0 root handle 1: htb default 10


This line adds the HTB qdisc to the root handle and gives it the "handle" 1:, which we will use later to refer to. default 10 means that is not otherwise classified will be assigned to the class 1:10.

Code:
$ tc class add dev eth0 parent 1: classid 1:1 htb rate 120kbit burst 6k


This command adds a subclass 1:1 to the class defined above. rate 120kbit specifies that network traffic in this class may not use more than 120kbit/s of the bandwidth. burst 6k controls the amount of data that may be sent at once at maximal speed. Without going into deep details, the concept of burst comes from the fact that network speed is not measured instantly, but is computed from averages. If you set burst to a low value, you may experience transfer rates lower than desired; if it's too large, rate limiting will become imprecise and eventually useless. If in doubt, do not specify it, a fairly recent iproute2 will compute the smallest possible value for you.

Usually it is a good idea to set the root upload rate to a somewhat lower value than your actual uplink is, because this way you can ensure that packet scheduling is performed on your machine, not in your DSL modem/whatever, which might result in a lower performance than what your shiny Linux system would offer.

Code:
$ tc class add dev eth0 parent 1:1 classid 1:10 htb rate 120kbit burst 6k prio 1
$ tc class add dev eth0 parent 1:1 classid 1:20 htb rate  60kbit burst 6k prio 2
$ tc class add dev eth0 parent 1:1 classid 1:30 htb rate  30kbit burst 6k prio 3


These commands create three subclasses under the class specified above. These classes will be given the handle 1:10, 1:20 and 1:30. 1:10 (which, as you might remember, is the default class) has the same parameters as the parent class has; this will be useful for traffic we do not want to limit. 1:20 has a speed limit of 60kbit/s, whereas 1:30 is limited to 30kbit/s. By giving each of them a priority, we specify that 1:20 may use up to 60kbit/s of bandwidth, but only to the extent 1:10 is unused. So if we have traffic at 80k/s in 1:10, 1:20 will receive only 40k/s; if 1:10 has 20kbit/s, 1:20 will get 60kbit/s. 1:30 is similar: it may use only 30kbit/s at most, but only if the other classes do not require that bandwidth.

If that helps, you might look at the classes as leaves of a tree:

Code:
               1:1
            120kbit/s

  1:10        1:20        1:30
120kbit/s   60kbit/s    30kbit/s


But do not forget that 1:10, 1:20 and 1:30 are not equal, as there is a specific priority order for them.

HTB offers an endless number of possibilities thanks to the hierarchical structure, and these are all well documented in its great user guide. Remember, this guide is only meant to be a short introduction on how these things work; once you get the basics, it will be easy to learn and implement new ways of bandwidth throttling.

Code:
$ tc qdisc add dev eth0 parent 1:10 handle 10: sfq perturb 10
$ tc qdisc add dev eth0 parent 1:20 handle 20: sfq perturb 10
$ tc qdisc add dev eth0 parent 1:30 handle 30: sfq perturb 10


Finally, these lines add an additional qdisc beneath those three classes we already have. The SFQ (Stochastic Fairness Queueing) qdisc is a simple algorithm that ensures that the available bandwidth in the specified class is divided in a "fair" manner among the network streams, that is: bandwidth is distributed in a round-robin fashion. It is recommended to always use this qdisc, as it usually turns out to be better than the plain FIFO queue, unless all your packets have the proper ToS (Type of Service) flag set, which is pretty unlikely.

5. Classifying network streams

Network streams can be assigned to classes using the tc filter command. If you have a fairly simple class tree such as the one above, you might attach your rules for classifying to the root handle, that is being 1: in our case. For more complicated setups, you might want to take benefit of the fact that filters are attached to handles and are processed in a hierarchical manner.

Let's see some examples. If you have a friend with the IP number 1.2.3.4 who is downloading a lot from you, you might simply direct all the traffic going to him into the 1:30 class so he will never use more than 30kbit/s of your bandwidth (you may add a netmask like /24 to the IP number):

Code:
$ tc filter add dev eth0 parent 1: protocol ip u32 match ip dst 1.2.3.4 flowid 1:30


Another situation might be that you are running a web server on port 80 and you don't want it to take up all your bandwidth serving requests, so you limit it to 60kbit/s and make sure that it only uses bandwidth you wouldn't use otherwise (ie. not used by the default 1:10 class):

Code:
$ tc filter add dev eth0 parent 1: protocol ip u32 match ip sport 80 0xffff flowid 1:20


You can also match on the so-called marks you might make on packets using iptables, which enables the use of iptables' advanced rules not supported by the u32 classifier. This document is not meant to be a guide for iptables, so let's see only one example. I'm running DC++ under wine and want to limit the upload bandwidth it can use. Iptables has a nifty match extension called owner, which makes it possible to check if an outgoing locally-generated packet was created by a process with a given UID, GID, PID, SID, or command name. So I look for "wineserver" (see "ps -A" for process names) and assign mark "2" to all the packets coming from it, and then use tc to assign these packets to a restricted class (1:30):

Code:
$ iptables -t mangle -A OUTPUT -m owner --cmd-owner wineserver -j MARK --set-mark 2
$ tc filter add dev eth0 protocol ip parent 1:0 handle 2 fw flowid 1:30


U32 has many more options and so does iptables, so be sure to check the docs if you need other matches. Should you have matches on the same level that might conflict each other, be sure to assign priorities to each of them (prio 1, prio 2 etc.) to your liking.

6. Other useful commands


To see a list of your classes, enter:

Code:
$ tc class show dev eth0
class htb 1:1 root rate 120Kbit ceil 120Kbit burst 6Kb cburst 1752b
class htb 1:10 parent 1:1 leaf 10: prio 1 rate 120Kbit ceil 120Kbit burst 6Kb cburst 1752b
class htb 1:20 parent 1:1 leaf 20: prio 2 rate 60Kbit ceil 60Kbit burst 6Kb cburst 1675b
class htb 1:30 parent 1:1 leaf 30: prio 3 rate 30Kbit ceil 30Kbit burst 6Kb cburst 1637b


To check the statistics for the classes, add "-s":

Code:
$ tc -s class show dev eth0
class htb 1:1 root rate 120Kbit ceil 120Kbit burst 6Kb cburst 1752b
 Sent 440085220 bytes 2961615 pkts (dropped 0, overlimits 0)
 rate 5170bps 23pps
 lended: 0 borrowed: 0 giants: 0
 tokens: 291200 ctokens: -1534

class htb 1:10 parent 1:1 leaf 10: prio 1 rate 120Kbit ceil 120Kbit burst 6Kb cburst 1752b
 Sent 157506822 bytes 2213767 pkts (dropped 0, overlimits 0)
 rate 1306bps 18pps
 lended: 2213767 borrowed: 0 giants: 0
 tokens: 402094 ctokens: 109360

class htb 1:20 parent 1:1 leaf 20: prio 2 rate 60Kbit ceil 60Kbit burst 6Kb cburst 1675b
 Sent 0 bytes 0 pkts (dropped 0, overlimits 0)
 lended: 0 borrowed: 0 giants: 0
 tokens: 819200 ctokens: 223466

class htb 1:30 parent 1:1 leaf 30: prio 3 rate 30Kbit ceil 30Kbit burst 6Kb cburst 1637b
 Sent 275743173 bytes 747867 pkts (dropped 34476, overlimits 0)
 rate 3826bps 4pps backlog 19p
 lended: 747848 borrowed: 0 giants: 0
 tokens: 728678 ctokens: -472923


To delete all your classes and restore the boot-time default setting, enter:

Code:
$ tc qdisc del dev eth0 root


7. Limiting download bandwidth

As already mentioned, this guide aimed to introduce egress shaping, ie. how you can control the way packets are sent from your host. Ingress (download) shaping, on the other hand, is a more complicated issue. Strictly speaking, you have no direct control of what people send you from other machines. However the Internet is mostly based on TCP/IP nowadays, which basically offers three means of throttling the download bandwidth:


  1. If data is coming at a greater rate than you would prefer, you can start dropping incoming packets. A well-behaved remote end would then recognize this and slow down to a rate at which the packet loss is minimal. Unfortunately we all know that many corporations see standards as if they were merely loose guidelines, so there is a chance that the rate will not be decreased. And if it won't, then the situation will be even worse: data will be coming at the same speed, and moreover you will be dropping packets. And anyway, all packets that you have received and dropped in order to indicate your need for a lower speed will be retransmitted, so this is also a waste of network capacity. Nevertheless, iproute2 supports this and if you already know a bit about egress shaping it shouldn't be a great deal to implement it.

  2. If you know TCP/IP, you might have already heard that one has to notify the sender of each packet he receives that he has actually received it. This response is called the ACK packet (coming from acknowledge). Delaying these ACK packets could make the transfer slow down, but this is something that I've met only in theories.

  3. TCP window manipulation is an advanced and better method of influencing the speed of network streams, unfortunately AFAIK there are no open source applications that implement that for the time being.


8. Resources

You are advised to refer to the following resources for more information:

---
Corrections, questions, ideas, typo fixes are welcome!


Last edited by abali on Thu Oct 07, 2004 7:59 pm; edited 2 times in total
Back to top
View user's profile Send private message
PoLiPiE
n00b
n00b


Joined: 25 May 2003
Posts: 15
Location: www.pckliniek.be

PostPosted: Mon Sep 20, 2004 7:51 pm    Post subject: Reply with quote

nice howto man :D


looks very nifty

very nice work :lol: :lol: :lol: :lol:
_________________
www.pckliniek.be
Back to top
View user's profile Send private message
abali
n00b
n00b


Joined: 19 Sep 2004
Posts: 69
Location: Budapest, Hungary

PostPosted: Wed Sep 22, 2004 2:53 pm    Post subject: Reply with quote

Added section 0 so people can decide if they should read this howto even if they have never heard of bandwidth limiting.
Back to top
View user's profile Send private message
gutter
Moderator
Moderator


Joined: 13 Mar 2004
Posts: 7160
Location: Aarau, Aargau, Switzerland

PostPosted: Tue Sep 28, 2004 9:08 pm    Post subject: Reply with quote

abali wrote:
Added section 0 so people can decide if they should read this howto even if they have never heard of bandwidth limiting.


A very very very great work :wink:
_________________
Registered as User #281564 and Machines #163761
Back to top
View user's profile Send private message
eNTi
Veteran
Veteran


Joined: 20 Oct 2002
Posts: 1011
Location: Salzburg, Austria

PostPosted: Tue Oct 05, 2004 12:07 pm    Post subject: Reply with quote

good work.
_________________
If you fall off a cliff, you might as well try to fly. After all, you got nothing to lose.

-- John Sheridan - Babylon 5, Season 4
Back to top
View user's profile Send private message
Kovid
Apprentice
Apprentice


Joined: 25 Aug 2003
Posts: 217
Location: California, USA

PostPosted: Thu Oct 07, 2004 5:37 pm    Post subject: Reply with quote

Nice HOWTO. One small suggestion

You should probably add the "Firewall based classifier" as a required module. It's needed to do mark based matching. Took me a while to figure that out.
Back to top
View user's profile Send private message
abali
n00b
n00b


Joined: 19 Sep 2004
Posts: 69
Location: Budapest, Hungary

PostPosted: Thu Oct 07, 2004 8:00 pm    Post subject: Reply with quote

Kovid wrote:
You should probably add the "Firewall based classifier" as a required module. It's needed to do mark based matching. Took me a while to figure that out.


Thanks, added.
Back to top
View user's profile Send private message
Kanniball
Apprentice
Apprentice


Joined: 23 Jan 2004
Posts: 208
Location: Portugal

PostPosted: Wed Oct 13, 2004 2:34 pm    Post subject: Reply with quote

Congratulations for this great tuturial...
Can I give a little suggestion?

Compile this as a bash file and use variables for devices. So we can read the tutorial and change the settings, because they are very well commented?

Thanks again for this how-to!!! and keep giving us more :)
Back to top
View user's profile Send private message
blackphiber
Tux's lil' helper
Tux's lil' helper


Joined: 11 Sep 2003
Posts: 86
Location: IL

PostPosted: Sun Oct 31, 2004 8:14 am    Post subject: Reply with quote

I could put this all into a bash file (say we call it htb) and do something like: (in /etc/init.d and chmod it: chmod +x /etc/init.d/htb )
Code:
#!/sbin/runscript

depend() {
        use logger
        need net
}

start() {
        ebegin "Starting htb"
        /etc/htb-start.sh
        eend $?
}

stop() {
        ebegin "Stopping htb"
        /etc/htb-stop.sh
        eend $?
}



and inside of htb-start.sh would be all the commands that you use to configure it as pointed out above (very nice, thank you!) and inside htb-stop.sh would be tc qdisc del dev eth0 root
and of course those two files should be chmoded to execute too
Back to top
View user's profile Send private message
LeTene
Guru
Guru


Joined: 02 Mar 2004
Posts: 348
Location: Ah'll glass ye!

PostPosted: Sun Nov 14, 2004 9:23 pm    Post subject: Reply with quote

I am slowly beginning to understand traffic shaping thanks to this excellent howto, thanks abali!

I'm having problems however trying to shape incoming traffic to my machine (which is behind an ADSL modem/router/firewall) to handle P2P connections. My machine is connected to the router via a 100baseT cable. Here's my layout:
Code:
    INTERNET
        |
   MODEM/ROUTER
        |
  My Gentoo Box


My 'Net connection is 1024/256, and I want to limit uploads that I serve on P2P to 200kbits, to allow me to SSH/surf reasonably, so I came up with this script based on the guide above - it attempts to limit bandwidth on port 9176 to 200kbits max. The problem is, it limits ingress (download rate) as well as egress (upload rates) and I can't figure it out...

Code:
# Clear old queues, and set up root
tc qdisc del dev eth0 root
tc qdisc add dev eth0 root handle 1: htb default 10

# Full rate of LAN by default
tc class add dev eth0 parent 1: classid 1:1 htb rate 99mbit
tc class add dev eth0 parent 1:1 classid 1:10 htb rate 99mbit prio 1

# Class for P2P
tc class add dev eth0 parent 1:1 classid 1:20 htb rate 200kbit prio 2

# Filter port 9176 to the P2P class defined peviously
tc filter add dev eth0 parent 1: protocol ip u32 match ip sport 9176 0xffff flowid 1:20


It's my understanding that traffic shaping only affects egress, but the ingress is being limited to the 200kbits as well! Am I completely on the wrong track here? Any help appreciated!
_________________
Docs, Tips & Tricks at the Gentoo Wiki page.
Back to top
View user's profile Send private message
Parasietje
Apprentice
Apprentice


Joined: 25 Jan 2004
Posts: 194

PostPosted: Mon Nov 29, 2004 6:02 pm    Post subject: Reply with quote

This is completely what I want! Thank you!
Don't know a solution to your problem though. :x
Back to top
View user's profile Send private message
LeTene
Guru
Guru


Joined: 02 Mar 2004
Posts: 348
Location: Ah'll glass ye!

PostPosted: Mon Nov 29, 2004 6:14 pm    Post subject: Reply with quote

Parasietje wrote:
This is completely what I want! Thank you!
Don't know a solution to your problem though. :x


Hehehe - I solved it, and should have posted this earlier. I just used the marking-packets-by-app method to end up with this (remember this is for a machine inside a firewall on a 100mbit LAN - I want to limit traffic destined for the firewall & the Internet):

Code:
#!/bin/bash

# Zap the iptables mangle queue
iptables -t mangle -F

# Egress device
OUT=eth0

# Flow rates
# NOTE: Bruce is a mate of mine, I give him a big bandwidth hit ;)
MAX=100mbit
VALKNUT=90kbit
BRUCE=100kbit

# Delete existing shaping
tc qdisc del dev $OUT root

# ===========
# Our classes
# ===========
# Top
tc qdisc add dev $OUT root handle 1: htb default 40
tc class add dev $OUT parent 1: classid 1:1 htb rate $MAX

tc class add dev $OUT parent 1:1 classid 1:10 htb rate $MAX
tc class add dev $OUT parent 1:1 classid 1:20 htb rate $VALKNUT ceil $VALKNUT
tc class add dev $OUT parent 1:1 classid 1:30 htb rate $BRUCE ceil $BRUCE
tc class add dev $OUT parent 1:1 classid 1:40 htb rate $MAX ceil $MAX

# Rehashing
tc qdisc add dev $OUT parent 1:10 handle 10: sfq perturb 10
tc qdisc add dev $OUT parent 1:20 handle 20: sfq perturb 10
tc qdisc add dev $OUT parent 1:30 handle 30: sfq perturb 10
tc qdisc add dev $OUT parent 1:40 handle 40: sfq perturb 10

# ===================
# the magic begins...
# NOTE: Bruce's IP address altered for privacys' sake for this post
# ===================

# DC++
iptables -t mangle -A OUTPUT -m owner --destination ! 213.218.xxx.xx --cmd-owner valknut -j MARK --set-mark 2
tc filter add dev $OUT protocol ip parent 1:0 handle 2 fw flowid 1:20

# Bruce
iptables -t mangle -A OUTPUT -m owner --destination 213.218.xxx.xx --cmd-owner valknut -j MARK --set-mark 3
tc filter add dev $OUT protocol ip parent 1:0 handle 3 fw flowid 1:30

_________________
Docs, Tips & Tricks at the Gentoo Wiki page.
Back to top
View user's profile Send private message
Parasietje
Apprentice
Apprentice


Joined: 25 Jan 2004
Posts: 194

PostPosted: Mon Nov 29, 2004 6:18 pm    Post subject: Reply with quote

By the way, can't this script be used for incoming traffic on a router too? Limit outgoing traffic on eth0 that comes from ports higher than 1024 to limit the same incoming traffic on ppp0.
Back to top
View user's profile Send private message
SaFrOuT
Apprentice
Apprentice


Joined: 08 Jul 2003
Posts: 256
Location: Egypt

PostPosted: Wed Dec 01, 2004 2:34 am    Post subject: Reply with quote

i am on ADSL 512/128 :roll:
and i just want to use thi Tip to handle my uploads for the torrent world :wink: , my upload's maximum is about 12kb/sec i want to be sure that the uplaods for the torrents won't exceed 6~7kb/sec while i am browsing
can anyone please explain what do i need to change in those commands to make it work ?
_________________

[1] DFI NF4-Ultra
[2] Opteron 165 @ 2.5Ghz
[3] Palit X800Pro ( trying to change it for a 7600GT )
[4] G.Skill 2GB ZX @ DDR500 3-3-3-8
[5] SkyHAwk 620watt
Back to top
View user's profile Send private message
LeTene
Guru
Guru


Joined: 02 Mar 2004
Posts: 348
Location: Ah'll glass ye!

PostPosted: Thu Dec 02, 2004 7:58 am    Post subject: Reply with quote

Parasietje wrote:
By the way, can't this script be used for incoming traffic on a router too? Limit outgoing traffic on eth0 that comes from ports higher than 1024 to limit the same incoming traffic on ppp0.


I've never done ingress (incoming) quality-of-service stuff, but recall reading that it's better done upstream. I think this means - assuming you have a Linux firewall box - that you should limit the rate it delivers packets to your LAN, and so it's still egress (outgoing) quality-of-service.

SaFrOuT wrote:
i am on ADSL 512/128
and i just want to use thi Tip to handle my uploads for the torrent world, my upload's maximum is about 12kb/sec i want to be sure that the uplaods for the torrents won't exceed 6~7kb/sec while i am browsing
can anyone please explain what do i need to change in those commands to make it work ?


Here's my shot at a cut-down version of the script for you ;). You will want to change the BT_RATE to your maximum desired upload, and the BT_APP to the name of your Bittorrent client (e.g. qtorrent, azureus). Also, make sure the OUT variable is set to your actual egress device (ppp0, eth0, whatever):

Code:
#!/bin/bash

# Zap the iptables mangle queue
iptables -t mangle -F

# Egress device
OUT=eth0

# Flow rates
MAX=100mbit
BT_MAX=90kbit

# Application names (for "marking")
BT_APP=qtorrent

# Delete existing shaping
tc qdisc del dev $OUT root

# ===========
# Our classes
# ===========
# Top
tc qdisc add dev $OUT root handle 1: htb default 30
tc class add dev $OUT parent 1: classid 1:1 htb rate $MAX

tc class add dev $OUT parent 1:1 classid 1:10 htb rate $MAX
tc class add dev $OUT parent 1:1 classid 1:20 htb rate $BT_MAX ceil $BT_MAX
tc class add dev $OUT parent 1:1 classid 1:30 htb rate $MAX ceil $MAX

# Rehashing
tc qdisc add dev $OUT parent 1:10 handle 10: sfq perturb 10
tc qdisc add dev $OUT parent 1:20 handle 20: sfq perturb 10
tc qdisc add dev $OUT parent 1:30 handle 30: sfq perturb 10

# ===================
# the magic begins...
# ===================

# Bittorrent
iptables -t mangle -A OUTPUT -m owner --cmd-owner $BT_APP -j MARK --set-mark 2
tc filter add dev $OUT protocol ip parent 1:0 handle 2 fw flowid 1:20

_________________
Docs, Tips & Tricks at the Gentoo Wiki page.
Back to top
View user's profile Send private message
SaFrOuT
Apprentice
Apprentice


Joined: 08 Jul 2003
Posts: 256
Location: Egypt

PostPosted: Sat Dec 04, 2004 10:05 am    Post subject: Reply with quote

Thanks LeTene for your help
bt i get this error when i try to run your script

Code:

home Desktop # ./upload.sh
iptables v1.2.11: can't initialize iptables table `mangle': iptables who? (do you need to insmod?)
Perhaps iptables or your kernel needs to be upgraded.
RTNETLINK answers: No such file or directory
RTNETLINK answers: Invalid argument
RTNETLINK answers: No such file or directory
RTNETLINK answers: No such file or directory
RTNETLINK answers: No such file or directory
RTNETLINK answers: No such file or directory
RTNETLINK answers: No such file or directory
RTNETLINK answers: No such file or directory
RTNETLINK answers: No such file or directory
iptables v1.2.11: can't initialize iptables table `mangle': iptables who? (do you need to insmod?)
Perhaps iptables or your kernel needs to be upgraded.
RTNETLINK answers: Invalid argument
We have an error talking to the kernel
home Desktop #       


and my kernel 2.6.9-ck3's config looks like this

Code:

# Networking options
#
CONFIG_PACKET=y
# CONFIG_PACKET_MMAP is not set
# CONFIG_NETLINK_DEV is not set
CONFIG_UNIX=y
# CONFIG_NET_KEY is not set
CONFIG_INET=y
# CONFIG_IP_MULTICAST is not set
# CONFIG_IP_ADVANCED_ROUTER is not set
# CONFIG_IP_PNP is not set
# CONFIG_NET_IPIP is not set
# CONFIG_NET_IPGRE is not set
# CONFIG_ARPD is not set
CONFIG_SYN_COOKIES=y
# CONFIG_INET_AH is not set
# CONFIG_INET_ESP is not set
# CONFIG_INET_IPCOMP is not set
# CONFIG_INET_TUNNEL is not set

#
# IP: Virtual Server Configuration
#
# CONFIG_IP_VS is not set
# CONFIG_IPV6 is not set
CONFIG_NETFILTER=y
# CONFIG_NETFILTER_DEBUG is not set

#
# IP: Netfilter Configuration
#
CONFIG_IP_NF_CONNTRACK=m
# CONFIG_IP_NF_CT_ACCT is not set
# CONFIG_IP_NF_CT_PROTO_SCTP is not set
CONFIG_IP_NF_FTP=m
CONFIG_IP_NF_IRC=m
CONFIG_IP_NF_TFTP=m
CONFIG_IP_NF_AMANDA=m
CONFIG_IP_NF_QUEUE=m
CONFIG_IP_NF_IPTABLES=m
CONFIG_IP_NF_MATCH_LIMIT=m
CONFIG_IP_NF_MATCH_IPRANGE=m
CONFIG_IP_NF_MATCH_MAC=m
CONFIG_IP_NF_MATCH_PKTTYPE=m
CONFIG_IP_NF_MATCH_MARK=m
CONFIG_IP_NF_MATCH_MULTIPORT=m
CONFIG_IP_NF_MATCH_TOS=m
CONFIG_IP_NF_MATCH_RECENT=m
CONFIG_IP_NF_MATCH_ECN=m
CONFIG_IP_NF_MATCH_DSCP=m
CONFIG_IP_NF_MATCH_AH_ESP=m
CONFIG_IP_NF_MATCH_LENGTH=m
CONFIG_IP_NF_MATCH_TTL=m
CONFIG_IP_NF_MATCH_TCPMSS=m
CONFIG_IP_NF_MATCH_HELPER=m
CONFIG_IP_NF_MATCH_STATE=m
CONFIG_IP_NF_MATCH_CONNTRACK=m
CONFIG_IP_NF_MATCH_OWNER=m
# CONFIG_IP_NF_MATCH_ADDRTYPE is not set
# CONFIG_IP_NF_MATCH_REALM is not set
# CONFIG_IP_NF_MATCH_SCTP is not set
# CONFIG_IP_NF_MATCH_COMMENT is not set
CONFIG_IP_NF_FILTER=m
CONFIG_IP_NF_TARGET_REJECT=m
CONFIG_IP_NF_TARGET_LOG=m
CONFIG_IP_NF_TARGET_ULOG=m
CONFIG_IP_NF_TARGET_TCPMSS=m
CONFIG_IP_NF_NAT=m
CONFIG_IP_NF_NAT_NEEDED=y
CONFIG_IP_NF_TARGET_MASQUERADE=m
CONFIG_IP_NF_TARGET_REDIRECT=m
CONFIG_IP_NF_TARGET_NETMAP=m
CONFIG_IP_NF_TARGET_SAME=m
CONFIG_IP_NF_NAT_LOCAL=y
CONFIG_IP_NF_NAT_SNMP_BASIC=m
CONFIG_IP_NF_NAT_IRC=m
CONFIG_IP_NF_NAT_FTP=m
CONFIG_IP_NF_NAT_TFTP=m
CONFIG_IP_NF_NAT_AMANDA=m
CONFIG_IP_NF_MANGLE=m
CONFIG_IP_NF_TARGET_TOS=m
CONFIG_IP_NF_TARGET_ECN=m
CONFIG_IP_NF_TARGET_DSCP=m
CONFIG_IP_NF_TARGET_MARK=m
CONFIG_IP_NF_TARGET_CLASSIFY=m
# CONFIG_IP_NF_RAW is not set
CONFIG_IP_NF_ARPTABLES=m
CONFIG_IP_NF_ARPFILTER=m
CONFIG_IP_NF_ARP_MANGLE=m
# CONFIG_IP_NF_COMPAT_IPCHAINS is not set
# CONFIG_IP_NF_COMPAT_IPFWADM is not set


#
# QoS and/or fair queueing
#
CONFIG_NET_SCHED=y
CONFIG_NET_SCH_CLK_JIFFIES=y
# CONFIG_NET_SCH_CLK_GETTIMEOFDAY is not set
# CONFIG_NET_SCH_CLK_CPU is not set
# CONFIG_NET_SCH_CBQ is not set
CONFIG_NET_SCH_HTB=m
CONFIG_NET_SCH_HFSC=m
CONFIG_NET_SCH_PRIO=m
CONFIG_NET_SCH_RED=m
CONFIG_NET_SCH_SFQ=m
CONFIG_NET_SCH_TEQL=m
CONFIG_NET_SCH_TBF=m
CONFIG_NET_SCH_GRED=m
CONFIG_NET_SCH_DSMARK=m
CONFIG_NET_SCH_NETEM=m
CONFIG_NET_SCH_INGRESS=m
# CONFIG_NET_QOS is not set
CONFIG_NET_CLS=y
# CONFIG_NET_CLS_TCINDEX is not set
# CONFIG_NET_CLS_ROUTE4 is not set
# CONFIG_NET_CLS_ROUTE is not set
CONFIG_NET_CLS_FW=m
CONFIG_NET_CLS_U32=m
# CONFIG_CLS_U32_PERF is not set
# CONFIG_NET_CLS_IND is not set


_________________

[1] DFI NF4-Ultra
[2] Opteron 165 @ 2.5Ghz
[3] Palit X800Pro ( trying to change it for a 7600GT )
[4] G.Skill 2GB ZX @ DDR500 3-3-3-8
[5] SkyHAwk 620watt
Back to top
View user's profile Send private message
Parasietje
Apprentice
Apprentice


Joined: 25 Jan 2004
Posts: 194

PostPosted: Sun Dec 05, 2004 12:05 pm    Post subject: Reply with quote

http://www.szabilinux.hu/bandwidth/
This URL is worth checking out. Download bandwidth limiting works like a charm on my router. If you run a squid proxy, you may have problems limiting download traffic if you use transparent proxying.
Use Delaying Pools for squid bandhwith limiting. (Line 2849 in squid.conf)


Last edited by Parasietje on Sat Dec 18, 2004 11:07 am; edited 1 time in total
Back to top
View user's profile Send private message
Deranger
Veteran
Veteran


Joined: 26 Aug 2004
Posts: 1215

PostPosted: Thu Dec 09, 2004 12:20 am    Post subject: Reply with quote

Nevermind...

Last edited by Deranger on Fri Mar 25, 2005 7:40 pm; edited 1 time in total
Back to top
View user's profile Send private message
hardcampa
n00b
n00b


Joined: 11 Oct 2002
Posts: 58

PostPosted: Mon Dec 27, 2004 3:09 pm    Post subject: It's a nice howto but I think you've made some big errors Reply with quote

Code:
class htb 1:1 root rate 120Kbit ceil 120Kbit burst 6Kb cburst 1752b
class htb 1:10 parent 1:1 leaf 10: prio 1 rate 120Kbit ceil 120Kbit burst 6Kb cburst 1752b
class htb 1:20 parent 1:1 leaf 20: prio 2 rate 60Kbit ceil 60Kbit burst 6Kb cburst 1675b
class htb 1:30 parent 1:1 leaf 30: prio 3 rate 30Kbit ceil 30Kbit burst 6Kb cburst 1637b


The parameters which you typed sets the minimum rate at 120Kbit for class 1.
Then you set the ceiling at 120Kbit as well?
This makes the other 2 classes not recieve any traffic at all during high loads.

Shouldn't you instead divide the maximum rate over the rate parameters in the classes and let the ceiling be the maximum rate so that the other classes can lend each other tokens, thus making sure the full bandwidth can be shared if there's no traffic, seems to me that this is the big thing with HTB over CBQ?

Like this for example:
Code:
class htb 1:1 root rate 120Kbit ceil 120Kbit burst 6Kb cburst 1752b
class htb 1:10 parent 1:1 leaf 10: prio 1 rate 60Kbit ceil 120Kbit burst 6Kb cburst 1752b
class htb 1:20 parent 1:1 leaf 20: prio 2 rate 30Kbit ceil 120Kbit burst 6Kb cburst 1675b
class htb 1:30 parent 1:1 leaf 30: prio 3 rate 30Kbit ceil 120Kbit burst 6Kb cburst 1637b


This guarantees class 1:10 gets at least 60Kbit but will use 120Kbit if the other classes aren't using the bandwidth, etc.

Btw, here's a small oneliner to interactively watch the traffic on the classes so that you can verify that they indeed get the traffic:
Code:

#!bin/sh
watch tc -s class show eth0


Type that in a file and chmod it 755 then just run it.
Just change the device (eth0) to whatever you're using
_________________
http://gibbage.mine.nu
Back to top
View user's profile Send private message
barberio
n00b
n00b


Joined: 29 Dec 2004
Posts: 4

PostPosted: Wed Dec 29, 2004 2:48 am    Post subject: Using HTB's full capability Reply with quote

After playing around with the Wondershaper script, and reading the HTB docs, I discovered that theres a lot more you can do with HTB to maintain good bandwidth use on an ADSL line.

Most current simple HTB scripts just limit rates on the queues, so low priority trafic never gets to use the full amount. but use of prio, ceil, burst and cburst offer a relativly simple method to allow low priority trafic to use full bandwidth without the priority trafic being drowned out, or the low priority trafic starved.

I've created simple rc scripts to do this.
The script and it's config

It might also be useful to use MSS clamping. http://howtos.linux.com/howtos/Adv-Routing-HOWTO/lartc.cookbook.mtu-mss.shtml
Back to top
View user's profile Send private message
barberio
n00b
n00b


Joined: 29 Dec 2004
Posts: 4

PostPosted: Wed Dec 29, 2004 6:02 pm    Post subject: Reply with quote

It should also be noted that there is a critical bug with the 2.6.8 linux kernel that causes a crash and kernel oops on removing/creating ingress queues and policing. There is a patch available at http://lists.debian.org/debian-kernel/2004/08/msg01623.html and a Report (#76041) on gentoo bugs.
Back to top
View user's profile Send private message
kkh
n00b
n00b


Joined: 02 Dec 2004
Posts: 7

PostPosted: Thu Dec 30, 2004 5:48 pm    Post subject: Reply with quote

i'm using this simple script to limit the outgoing traffic on eth0 (connected to lan and wan) that won't go to local lan:

#!/bin/bash

iptables -t mangle -F

tc qdisc del dev eth0 root

tc qdisc add dev eth0 root handle 1: htb default 10

tc class add dev eth0 parent 1: classid 1:1 htb rate 100mbit

tc class add dev eth0 parent 1:1 classid 1:10 htb rate 100mbit
tc class add dev eth0 parent 1:1 classid 1:20 htb rate 10kbps
tc class add dev eth0 parent 1:1 classid 1:30 htb rate 5kbps

tc qdisc add dev eth0 parent 1:10 handle 10: sfq perturb 10
tc qdisc add dev eth0 parent 1:20 handle 20: sfq perturb 10
tc qdisc add dev eth0 parent 1:30 handle 30: sfq perturb 10

tc filter add dev eth0 protocol ip parent 1:0 handle 2 fw flowid 1:20
tc filter add dev eth0 protocol ip parent 1:0 handle 3 fw flowid 1:30

iptables -t mangle -A OUTPUT -d ! 192.168.0.0/24 -j MARK --set-mark 2


this works fine beside that the traffic limiting is rather inaccurate. the wan-traffic that gets marked by iptables jumps up and down between 5kb/s and 12kb/s - when limited by software and without htb/sfq the traffic is precisely 10kb/s
Back to top
View user's profile Send private message
barberio
n00b
n00b


Joined: 29 Dec 2004
Posts: 4

PostPosted: Thu Dec 30, 2004 7:21 pm    Post subject: Reply with quote

Try putting Lan trafic on its own root handle. As your tree is now, HTB has to calculate against two other peer qdiscs for the lan trafic.

Also, check quantum? I need to work on that in my own script.
Back to top
View user's profile Send private message
barberio
n00b
n00b


Joined: 29 Dec 2004
Posts: 4

PostPosted: Thu Dec 30, 2004 7:52 pm    Post subject: Reply with quote

Updated my bandwidth RC script to try to calculate working quantum sizes from the MTU of the device being used. This should get rid of messages like 'HTB: quantum of class 10001 is big. Consider r2q change.'
Back to top
View user's profile Send private message
tuxlover
Apprentice
Apprentice


Joined: 21 Oct 2003
Posts: 297
Location: weltweit

PostPosted: Wed Jan 19, 2005 11:09 pm    Post subject: Reply with quote

There's also a very good howto packet shaping on gentoo linux at the gentoo wiki.
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
Goto page 1, 2, 3, 4  Next
Page 1 of 4

 
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