dslreports logo
site
 
    All Forums Hot Topics Gallery
spc

spacer




how-to block ads


Search Topic:
uniqs
5014
share rss forum feed


DaDawgs
Premium
join:2010-08-02
Deltaville, VA

3 edits

Mikrotik Script to manage PPPoE Queues

The bandwidth variables in this code are self-defining.

The Interval variable and the Percentage variable are not so ...

The Interval is how often you want this script to run. It should agree with the setting you have in your scheduler for this script.

Running the script more often will result in faster capture and faster release of clients who exceed the percentage limit.

The Percentage is how sensitive you want the script to be to user bandwidth usage. Lower percentages will result in capturing and releasing larger numbers of clients who exceed the percentage of allocated bandwidth for their connection.

Essentially you are managing a group of users to try to distribute bandwidth fairly across the group.

Playing with these two variables is an interesting exercise for network managers because of the different types of users the script isolates.

# ============================================================
# (C) 2011 M. Erskine -- All Rights Reserved
#
# Dynamically manages PPPoE Interface Queues to limit excessive video
# streaming or file sharing.
#
# Do the right thing then, If you use this script on your own Mikrotiks; PLEASE
# Set a link to http://www.freeantennas.com on your web site and PLEASE
# Don't remove the Copyright notice.
#
# If you are a developer or consultant and you want to incorporate this
# script into you own products.  PLEASE contact me for permission to do that.
#
# It is a simple script but a very powerful bit of code. Look for *READ* in
# the comments to find the things you might want to change.
#
# You also need to ensure that simple queues are set up on your routers when
# the customer logs in.  This is done in your PPPoE profile settings.
# ---------------------------------------------------------------------------------- ----------------
# General Theory of Operation
# ---------------------------------------------------------------------------------- ----------------
# Check the user's allocated bandwidth.
#      If he has used (p) percent of available bandwidth in this interval
#         then halve his available bandwidth
#         else double his available bandwidth
# Reset the pppoe queue counters.
# ============================================================
:global Name
:global Allocated
:global Id 0
:global TotalBytes 0
:global Limit 0
:global NewLimit 0
:global tpos
:global kpos
:global dBytes 0
:global uBytes 0
:global dRate 0
:global uRate 0
:global MaxRate 0
:global MaxBytes 0
# ---------------------------------------------------------------------------------- ---------------------------------------
# Below set the maximum download/upload rates you want to allow your users.
# This should agree with whatever rate you establish via the pppoe profile
# when your users log in but it does not have to.  *READ*  This number should
# be expressed in K/Bits/Sec.
# ---------------------------------------------------------------------------------- ---------------------------------------
:global dMaxRate 2867
:global uMaxRate 1228
# ---------------------------------------------------------------------------------- ---------------------------------------
# Set the below variable to agree with how often your scheduler calls this script
# This number is expressed in seconds.  The default is once per hour. *READ*
# ---------------------------------------------------------------------------------- ---------------------------------------
:global Interval 3600
# ---------------------------------------------------------------------------------- ---------------------------------------
# The below variable controlls the sensitivity of this program.  The smaller the
# percentage the faster the queue will be locked down but the faster it will then
# be unlocked.  Essentially this controls the sensitivity of the script to spikes and
# luls in bandwidth usage. *READ*
# ---------------------------------------------------------------------------------- ---------------------------------------
:global Percent 50
:global Info ""
# ==============================================================
# Now we will compute data about this interface specifically
# and perhaps modify his bandwidth allocation.
# ==============================================================
:foreach Id in=[/ppp active find] do= {
#
#=================================================
#Collect information about each specific interface
#=================================================
:set Name [/interface get $Id name]
#-------------------------------------------------
#Number of bytes moved on the interface
#-------------------------------------------------
:set TotalBytes [/queue simple get $Name bytes]
:set tpos [:tonum ([:pic [:find $TotalBytes "/"]])]
:set dBytes [:tonum [:pic $TotalBytes ($tpos+1) 30]]
:set uBytes [:tonum [:pic $TotalBytes 0 $tpos]]
:set TotalBytes [:tonum ($dBytes + $uBytes)]
#-------------------------------------------------
#What are the limits on this interface queue?
#-------------------------------------------------
:set Limit [/queue simple get $Name max-limit]
:set tpos [:tonum ([:pic [:find $Limit "/"]] +1)]
:set dRate [:pic $Limit $tpos 30]
:set kpos [:tonum ([:pic [:find $dRate "k"]])]
:set dRate [:tonum [:pic $dRate 0 $kpos]]
:set uRate [:pic $Limit 0 ($tpos -1)]
:set kpos [:tonum ([:pic [:find $uRate "k"]])]
:set uRate [:tonum [:pic $uRate 0 $kpos]]
:set MaxRate ($dRate + $uRate)
#-------------------------------------------------
#What is the maximum bandwidth possible @ Percent%
#-------------------------------------------------
:set MaxBytes ($MaxRate * 1024 * $Interval)
:set MaxBytes (($MaxBytes / 100 * $Percent) / 8)
#
if ($TotalBytes > $MaxBytes) do= {
:set dRate ($dRate / 2)
:set uRate ($uRate / 2)
}
if ($TotalBytes < $MaxBytes) do= {
:set dRate ($dRate * 2)
if ($dRate > $dMaxRate) do= {
:set dRate $dMaxRate
}
:set uRate ($uRate * 2)
if ($uRate > $uMaxRate) do= {
:set uRate $uMaxRate
}
}
:set NewLimit ($uRate . "k/" . $dRate . "k")
/queue simple set $Name limit-at=$NewLimit max-limit=$NewLimit
:set Info ("Name " . $Name . " Limited " . $NewLimit);
:log info $Info;
/queue simple set $Name comment=$Info
}
/queue simple reset-counters-all
 
 

--
Once we IPv6 enable every device on the Internet we will have toasters, baby monitors, and security cameras joining the bot nets which today are populated only by idiots that can not refrain from clicking, "Yes I would like to see those titties..."


Mad Dawg
Mad Dawg
Premium
join:2006-03-19

Nice script DaDawgs

Thanks for sharing this as I have been struggling as to if
I should try and apply Butch's script on my Tik pppoe concentrators
(it doesnt work on the upload unless you set it up as a meta router on each unit...
Too risky testing that on a live pop)

Are you using this ...if so I have a question
If I paste this from a terminal it makes no entries
therfore I gather it must be entered as a script and
then called by the scheduler to run ...is this correct

Thanks

MD

--
Best Regards

MD



DaDawgs
Premium
join:2010-08-02
Deltaville, VA

Enter it as a script.

Then set up your scheduler and make sure that the variables in the script agree with the scheduler.

Then set up your PPPoE simple queues in the PPPoE profile and make sure those agree with the variables in the script or vice versa.

And then I guess watch them to make sure that the customers that need to be limited are actually the ones getting limited.

You can call me if you want... PM me for a phone number.
--
Once we IPv6 enable every device on the Internet we will have toasters, baby monitors, and security cameras joining the bot nets which today are populated only by idiots that can not refrain from clicking, "Yes I would like to see those titties..."



Mad Dawg
Mad Dawg
Premium
join:2006-03-19

1 edit

Thanks DaDawgs

I tested it on a tik with just a couple users and
it did seem to alter their simple ques for a bit

After that I tested it on some heavier loaded Tiks
and it didnt seem to alter their ques at all
(although the time scheduler didnt match the script time which I corrected just now)
So far I am not seeing it alter them but its early yet and traffic is low

My simple ques are set/created by Radius
with 95% of our users on our base package (same as the script setting )
which should work fine however I am wondering how it would handle a simple que from one of our bigger packages
(ie a simple que that was greater than the script setting)

I appreciate you sharing this it would seem to be a much more graceful and simple approach
to basic qos on pppoe locally as opposed to implimenting metarouters and virtual interfaces
on a pile of live Tiks or shaping only at the gateway
--
Best Regards

MD



DaDawgs
Premium
join:2010-08-02
Deltaville, VA

I'm still testing it but I run it on an hourly basis. All I really want to accomplish with it is to slow down people streaming video or downloading very large files (larger than 700 megs).

I want to give every customer as much bandwidth as I possibly can give them without letting them degrade the Internet experience for other customers who are not hammering the network.

The variables I described can be used to change it's behavior quite a bit. If you play with them you will figure out what settings work for your network.


--
Once we IPv6 enable every device on the Internet we will have toasters, baby monitors, and security cameras joining the bot nets which today are populated only by idiots that can not refrain from clicking, "Yes I would like to see those titties..."



DaDawgs
Premium
join:2010-08-02
Deltaville, VA
reply to Mad Dawg

Well I've been running it on various schedules and I'm inclined to believe that the schedule should probably be 20 minutes or 1200 seconds.



DaDawgs
Premium
join:2010-08-02
Deltaville, VA
reply to DaDawgs

Updated version three of this script.

I have decided to release this script into the public domain. I have improved a logical error that was in the original version -v2 which would limit a client continuously until they were allocated zero bandwidth. Once that happened the client went to unlimited bandwidth because in a Mikotik if you set the queue limit to 0 it means no limit.

So as I have said... I hereby release this code under the GNU Copyleft... feel free to use it, just don't try to sell it. ;)

It works very well. Feel free to contact me if you want help installing it on your Mikrotiks.

# =================================================================================
# Author 2011 Michael J. Erskine
# This code is released under the terms of the GNU Copyleft as documented at
# the following link: http://en.wikipedia.org/wiki/Copyleft
#
# Dynamically manages PPPoE queues to decrease or increase users allocated
# bandwidth.  Basically it slows them down if they are hogging the system
# and speeds them up if they are not hogging the system.
#
# Ensure that simple queues are set up on your routers when the
# customer logs in.  This is done in your PPPoE profile settings.
# ---------------------------------------------------------------------------------
# General Theory of Operation
# ---------------------------------------------------------------------------------
# Check the user's allocated bandwidth.
#If he has used exceeded a specified percentage of available bandwidth in 
#this time interval
#then halve his available bandwidth
#If his bandwidth allocation is below the minimum
#then set it to the minimum.
#else double his available bandwidth
#If his bandwidth is above the maximum allocation
#then set it to the maximum
# Reset the pppoe queue counters.
# =================================================================================
#
:global Name
:global Allocated
:global Id 0
:global TotalBytes 0
:global Limit 0
:global NewLimit 0
:global tpos
:global kpos
:global dBytes 0
:global uBytes 0
:global dRate 0
:global uRate 0
:global MaxRate 0
:global MaxBytes 0
#
# ---------------------------------------------------------------------------------- -
# Below set the maximum download/upload rates you want to allow your users.
# This should agree with whatever rate you establish via the pppoe profile
# when your users log in but it does not have to.  This number should
# be expressed in K/Bits/Sec.
# ---------------------------------------------------------------------------------- -
#
:global dMaxRate 2048
:global uMaxRate 512
#
# ---------------------------------------------------------------------------------- -
# Below set the minimum rates you will allow for the user.  This number should be
# expressed in K/Bits/Sec.
# ---------------------------------------------------------------------------------- -
#
:global mindRate 512
:global minuRate 64
#
# ---------------------------------------------------------------------------------- -
# Set the below variable to agree with how often your scheduler calls this script
# This number is expressed in seconds.  The default is once per hour. 
# ---------------------------------------------------------------------------------- -
#
:global Interval 1800
#
# ---------------------------------------------------------------------------------- -
# The below variable controlls the sensitivity of this program.  The smaller the
# percentage the faster the queue will be locked down but the faster it will then
# be unlocked.  Essentially this controls the sensitivity of the script to spikes and
# luls in bandwidth usage. *READ*
# ---------------------------------------------------------------------------------- -
#
:global Percent 70
:global Info ""
#
# ==============================================================
# Now we will compute data about each interface specifically
# and perhaps modify that bandwidth allocation.
# ==============================================================
#
:foreach Id in=[/ppp active find] do= {
#
#=================================================
#Collect information about each specific interface
#=================================================
:set Name [/interface get $Id name]
#-------------------------------------------------
#Number of bytes moved on the interface
#-------------------------------------------------
:set TotalBytes [/queue simple get $Name bytes]
:set tpos [:tonum ([:pic [:find $TotalBytes "/"]])]
:set dBytes [:tonum [:pic $TotalBytes ($tpos+1) 30]]
:set uBytes [:tonum [:pic $TotalBytes 0 $tpos]]
:set TotalBytes [:tonum ($dBytes + $uBytes)]
#-------------------------------------------------
#What are the limits on this interface queue?
#-------------------------------------------------
:set Limit [/queue simple get $Name max-limit]
:set tpos [:tonum ([:pic [:find $Limit "/"]] +1)]
:set dRate [:pic $Limit $tpos 30]
:set kpos [:tonum ([:pic [:find $dRate "k"]])]
:set dRate [:tonum [:pic $dRate 0 $kpos]]
:set uRate [:pic $Limit 0 ($tpos -1)]
:set kpos [:tonum ([:pic [:find $uRate "k"]])]
:set uRate [:tonum [:pic $uRate 0 $kpos]]
:set MaxRate ($dRate + $uRate)
#-------------------------------------------------
#What is the maximum bandwidth possible @ Percent%
#-------------------------------------------------
:set MaxBytes ($MaxRate * 1024 * $Interval)
:set MaxBytes (($MaxBytes / 100 * $Percent) / 8)
#
#       ---------------------------------------------------
#       Reduce his speed if he is using too much bandwidth
#       ---------------------------------------------------
if ($TotalBytes > $MaxBytes) do= {
:set dRate ($dRate / 2)
:set uRate ($uRate / 2)
#-------------------------------------------
#But leave him enough to do bulk downloads.
#-------------------------------------------
        if ($dRate < $mindRate) do= {
:set dRate $mindRate
}
if ($uRate < $minuRate) do= (
:set uRate $minuRate
}
}
#-------------------------------------------
#       If his usage is minimal, increase his speed.
#-------------------------------------------
if ($TotalBytes < $MaxBytes) do= {
:set dRate ($dRate * 2)
if ($dRate > $dMaxRate) do= {
:set dRate $dMaxRate
}
:set uRate ($uRate * 2)
if ($uRate > $uMaxRate) do= {
:set uRate $uMaxRate
}
}
:set NewLimit ($uRate . "k/" . $dRate . "k")
/queue simple set $Name limit-at=$NewLimit max-limit=$NewLimit
:set Info ("Name " . $Name . " Limited " . $NewLimit);
:log info $Info;
/queue simple set $Name comment=$Info
}
/queue simple reset-counters-all
 
 

--
Once we IPv6 enable every device on the Internet we will have toasters, baby monitors, and security cameras joining the bot nets which today are populated only by idiots that can not refrain from clicking, "Yes I would like to see those titties..."