Queue tree and e-mailing stats

From MikroTik Wiki
Jump to: navigation, search

The goal

The goal is to limit every user to specific download/upload speeds, to guarantee specific download/upload speeds to each user and e-mail yourself the stats of users that exceed 1MB. Feel free to change the value to any desired value.

I found a lot of mangle and queue scripts that simply stopped all traffic but port 80 so I wrote my own. It's not the greatest but it works (for me).


The script - mangle

First mark packets for all users (all IP addresses) For upload:

:for x from=1 to=254 do={ /ip firewall mangle add chain=prerouting src-address="10.0.0.$x" action=mark-packet new-packet-mark="U0_$x" passthrough=no }

For download:

:for x from=1 to=254 do={ /ip firewall mangle add chain=postrouting dst-address="10.0.0.$x" action=mark-packet new-packet-mark="D0_$x" passthrough=no }

I have left my own IP addresses but be sure to change them with your own. The new-packet-mark has very short and simple name to avoid any typos.


The script - queue

Make two main queues (download and upload) for the interface you wish to limit.

/queue tree add burst-limit=0 burst-threshold=0 burst-time=0s disabled=no limit-at=0 max-limit=768000 name=UL packet-mark="" parent=DSL priority=8 queue=default;
/queue tree add burst-limit=0 burst-threshold=0 burst-time=0s disabled=no limit-at=0 max-limit=16000000 name=DL packet-mark="" parent=LAN priority=8 queue=default;

Be sure to change the speeds to match your interface speed or lower if you wish. Setting them higher will not help anything.

Now make a queue for each user (IP address) For upload:

:for x from=1 to=254 do={/queue tree add burst-limit=0 burst-threshold=0 burst-time=0s disabled=no limit-at=128000 max-limit=768000 name="U0_$x" packet-mark="U0_$x" parent=UL priority=8 queue=default }

For download:

:for x from=1 to=254 do={/queue tree add burst-limit=0 burst-threshold=0 burst-time=0s disabled=no limit-at=256000 max-limit=16000000 name="D0_$x" packet-mark="D0_$x" parent=DL priority=8 queue=default }

I let every user to download or upload using maximum speeds if there is no one else but guarantee 256k if there are more than one user downloading. Be sure to change this to your own needs and take in account the number of users and their surfing habits.


The e-mail script

Now to loop through queues and find out who is using more bandwidth. (This part is based on someones question on the same subject on the forum [1] but that didn't work for me so here is my rewrite)

:global traf;
:global megsu "0";
:global megsd "0";
:global resulter " ";
:global logmsg;
:global datum [/system clock get date];
:global vrijeme [/system clock get time];
/queue tree
    :for i from=1 to=254 do={
            :set logmsg "";
            :set traf [get "D0_$i" bytes];
            :set megsd ($traf / 1000000)
            :set traf [get "U0_$i" bytes];
            :set megsu ($traf / 1000000)
            :if ($megsd > 0) do={
                :if ($megsd > 1000) do={ :set megsd ($megsd / 1000); :set megsd "$megsd Gb" } else={ :set megsd "$megsd Mb"}
                :set logmsg ("D0_$i: $megsd");
                :set resulter ("$resulter \n User: 10.0.3.$i Download: $megsd")
            }
            :if ($megsu > 0) do={
                :if ($megsu > 1000) do={ :set megsu ($megsu / 1000); :set megsu "$megsu Gb" } else={ :set megsu "$megsu Mb"}
                :set logmsg ("$logmsg U0_$i: $megsu");
                :if ($logmsg!="") do={:set resulter ("$resulter Upload: $megsu")} else={:set resulter ("$resulter \n User: 10.0.3.$i Upload: $megsu")}
            }
            :if ($logmsg!="") do={ :log info ($logmsg) }
        }
/tool e-mail send from=from@email_here_com to=to@email_here_com subject="Queue $datum $vrijeme" body="$resulter" server=mail_server_ip_address
/queue tree reset-counters-all

Notice that i check for download as well as upload. There is no particular reason for this. And be sure to reset all the counters after you send yourself that e-mail. You want accurate stats for each day which brings us to the schedule.

Since I am sure that all queues exist, so I don't have any error checking. If you create queues on the fly, be sure to check all of them. So do it this way:

:global traf;
:global megsu "0";
:global megsd "0";
:global resulter " ";
:global logmsg;
:global datum [/system clock get date];
:global vrijeme [/system clock get time];
/queue tree
    :for i from=1 to=254 do={
            :set logmsg "";
            :set megsd "0";
            :set megsu "0";
            :if ([/queue tree find name="D0_$i"]!="") do={:set traf [get [find name="D0_$i"] bytes]; :set megsd ($traf / 1000000);}
            :if ([/queue tree find name="U0_$i"]!="") do={:set traf [get [find name="U0_$i"] bytes]; :set megsu ($traf / 1000000);}
            :if ($megsd > 0) do={
                :if ($megsd > 1000) do={ :set megsd ($megsd / 1000); :set megsd "$megsd Gb" } else={ :set megsd "$megsd Mb"}
                :set logmsg ("D0_$i: $megsd");
                :set resulter ("$resulter \n User: 10.0.3.$i Download: $megsd")
            }
            :if ($megsu > 0) do={
                :if ($megsu > 1000) do={ :set megsu ($megsu / 1000); :set megsu "$megsu Gb" } else={ :set megsu "$megsu Mb"}
                :set logmsg ("$logmsg U0_$i: $megsu");
                :if ($logmsg!="") do={:set resulter ("$resulter Upload: $megsu")} else={:set resulter ("$resulter \n User: 10.0.3.$i Upload: $megsu")}
            }
            :if ($logmsg!="") do={ :log info ($logmsg) }
        }
/tool e-mail send from=from@email_here_com to=to@email_here_com subject="Queue $datum $vrijeme" body="$resulter" server=mail_server_ip_address
/queue tree reset-counters-all

The schedule

Make a schedule that runs every midnight.

add comment="" disabled=no interval=24:00:00 name=schedule1 on-event="your_script_name_here" start-date=may/15/2008 start-time=00:00:00