Re: traffic shape per ip

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Bounced for HTML.  Re-sending as plaintext.

On Fri, Sep 20, 2013 at 9:15 AM, Ray Soucy <rps@xxxxxxxxx> wrote:
> Try something like this.
>
> It's not perfect, but it will work for a pool of up to 8000 IPs (TC limit is
> 9999 I believe).  Sorry for it being in PHP, it was tossed on a box where
> everything else is already PHP.
>
> Verified to work, and a modest Linux system doesn't have a problem keeping
> up with it.
>
> #!/bin/php
> <?php
>
> $config['wan_if']            = 'eth0';
> $config['lan_if']            = 'eth1';
> $config['global_down']       = '300mbit';
> $config['global_up']         = '300mbit';
> $config['default_down']      = '1mbit';
> $config['default_up']        = '1mbit';
> $config['network_list'] = array('172.19.0.0/20');
>
>
>
>
> function cidrtorange($network) {
>   list($ip, $bits) = explode('/', $network);
>   $ip = ip2long($ip);
>   $mask = ~((1 << (32 - $bits)) - 1);
>   $start = ($ip & $mask) + 1;
>   $end = ($start - 3) - $mask;
>   $range = array($start, $end);
>   return $range;
> }
>
> function exec_cmds($cmd) {
>   $log_data = "";
>   $cmd = str_replace('iptables ', '/usr/local/sbin/iptables ', $cmd);
>   $cmd = str_replace('tc ', '/usr/sbin/tc ', $cmd);
>   $cmd_list = explode("\n", $cmd);
>   foreach ($cmd_list as $c) {
>     if (strlen($c) < 1) continue;
>     $out = array();
>     exec($c . ' 2>&1', $out, $status);
>     if ($status == 0) $log_data .= $c . "\n";
>     else {
>       $log_data .= '# FAILED ' . $c . "\n";
>       foreach ($out as $o) $log_data .= '# ' . $o . "\n";
>     }
>   }
>   echo $log_data;
> }
>
>
>
> function do_start() {
>   global $config;
>   $host_list = array();
>   foreach ($config['network_list'] as $network) {
>     list($start_ip, $end_ip) = cidrtorange($network);
>     for ($i = $start_ip + 1; $i < $end_ip; $i++) {
>       $host = long2ip($i);
>       $host_list[$host]['down'] = $config['default_down'];
>       $host_list[$host]['up'] = $config['default_up'];
>     }
>   }
>   $cmd = "";
>   $cmd .= 'iptables -t mangle -N Traffic_Control' . "\n";
>   $cmd .= 'iptables -t mangle -A PREROUTING -i ' . $config['lan_if'] . ' -j
> Traffic_Control' . "\n";
>   $cmd .= 'tc qdisc add dev ' . $config['lan_if'] . ' root handle 1: htb
> default 9999' . "\n";
>   $cmd .= 'tc class add dev ' . $config['lan_if'] . ' parent 1: classid
> 1:9999 htb rate ' . $config['global_down'] . "\n";
>   $cmd .= 'tc qdisc add dev ' . $config['lan_if'] . ' parent 1:9999 handle
> 9999: sfq perturb 10' . "\n";
>   $cmd .= 'tc qdisc add dev ' . $config['wan_if'] . ' root handle 1: htb
> default 9999' . "\n";
>   $cmd .= 'tc class add dev ' . $config['wan_if'] . ' parent 1: classid
> 1:9999 htb rate ' . $config['global_up'] . "\n";
>   $cmd .= 'tc qdisc add dev ' . $config['wan_if'] . ' parent 1:9999 handle
> 9999: sfq perturb 10' . "\n";
>   $tc_index = 1;
>   foreach ($host_list as $host => $lim) {
>     $cmd .= 'iptables -t mangle -A Traffic_Control -s ' . $host . ' -j MARK
> --set-mark ' . $tc_index . "\n";
>     $cmd .= 'tc class add dev ' . $config['wan_if'] . ' parent 1: classid
> 1:' . $tc_index . ' htb rate ' . $lim['up'] . "\n";
>     $cmd .= 'tc filter add dev ' . $config['wan_if'] . ' protocol ip parent
> 1: prio 1 handle ' . $tc_index . ' fw flowid 1:' . $tc_index . "\n";
>     $cmd .= 'tc class add dev ' . $config['lan_if'] . ' parent 1: classid
> 1:' . $tc_index . ' htb rate ' . $lim['down'] . "\n";
>     $cmd .= 'tc filter add dev ' . $config['lan_if'] . ' protocol ip parent
> 1: prio 1 u32 match ip dst ' . $host . ' flowid 1:' . $tc_index . "\n";
>     $tc_index++;
>   }
>   exec_cmds($cmd);
> }
>
> function do_stop() {
>   global $config;
>   $cmd = "";
>   $cmd .= 'tc qdisc del dev ' . $config['lan_if'] . ' root' . "\n";
>   $cmd .= 'tc qdisc del dev ' . $config['wan_if'] . ' root' . "\n";
>   $cmd .= 'iptables -t mangle -D PREROUTING -i ' . $config['lan_if'] . ' -j
> Traffic_Control' . "\n";
>   $cmd .= 'iptables -t mangle -F Traffic_Control' . "\n";
>   $cmd .= 'iptables -t mangle -X Traffic_Control' . "\n";
>   exec_cmds($cmd);
> }
>
>
>
>
> if ($argc == 2) {
>   if ($argv[1] == 'start') {
>     do_start();
>   } elseif ($argv[1] == 'stop') {
>     do_stop();
>   } elseif ($argv[1] == 'restart') {
>     do_stop();
>     do_start();
>   } else {
>     echo 'Usage: ' . $argv[0] . ' {start|stop|restart}' . "\n";
>   }
>
> } else {
>   echo 'Usage: ' . $argv[0] . ' {start|stop|restart}' . "\n";
> }
>
>
>
> On Thu, Sep 19, 2013 at 4:34 PM, Andrew Beverley <andy@xxxxxxxxxxx> wrote:
>>
>> On Thu, 2013-09-19 at 21:43 +0300, binary wrote:
>> > i would to limit the bandwidth of some users based on IPs:
>>
>> [...]
>>
>> This is not as simple as you might think. In order to shape per-IP,
>> you'll need to set up a class for each individual IP address, and then
>> filter to that class. I am not aware of a way to write one rule to say
>> "limit each IP address to this amount".
>>
>> Presumably the reason to filter per-IP is to stop single users hogging
>> the bandwidth. If so, a better approach might be to classify the type of
>> traffic and then shape on that, or alternatively share bandwidth evenly
>> per-IP rather than per-connection (as is the default). There is some
>> information on how to do this on this page at the end of the "downlink"
>> section:
>>
>>
>> http://www.andybev.com/index.php/Fair_traffic_shaping_an_ADSL_line_for_a_local_network_using_Linux
>>
>> If you have any more questions you might want to use the LARTC mailing
>> list instead of this mailing list.
>>
>> Andy
>>
>>
>> --
>> To unsubscribe from this list: send the line "unsubscribe netfilter" in
>> the body of a message to majordomo@xxxxxxxxxxxxxxx
>> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>
>
>
>
> --
> Ray Patrick Soucy
> Network Engineer
> University of Maine System
>
> T: 207-561-3526
> F: 207-561-3531
>
> MaineREN, Maine's Research and Education Network
> www.maineren.net



-- 
Ray Patrick Soucy
Network Engineer
University of Maine System

T: 207-561-3526
F: 207-561-3531

MaineREN, Maine's Research and Education Network
www.maineren.net
--
To unsubscribe from this list: send the line "unsubscribe netfilter" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html




[Index of Archives]     [Linux Netfilter Development]     [Linux Kernel Networking Development]     [Netem]     [Berkeley Packet Filter]     [Linux Kernel Development]     [Advanced Routing & Traffice Control]     [Bugtraq]

  Powered by Linux