Problem with Simple script

Hi, can anyone spot what is wrong with this script, its for Router OS v6.2, and its just a sample script to test ip address 192.168.0.250 to 253 , if any of them are over 2mb in data i want to cut their bandwidth down. I just set it at 2mb as i been trying different things for hours so least i can easily test if i reach the 2mb and to cut it down.

And is there any way i can test the code from winbox, example to find out what is in the “traf” variable to see if the next part is being executed.

:local traf;
/queue simple
:for i from=250 to=253 do={
:if ([/queue simple find target=(“192.168.0.”.$i)] != “”) do={
:set traf [get [find target=(“192.168.0.”.$i)] total-bytes]
:if ($traf > 2097152) ) do = {
set [find target=(“192.168.0.”.$i)] max-limit= 32000/64000
}
}
}

Here are some comments:

  • The find commands return an array or list of items. It’s best if you stick to processing that as an array, hence the use the of the :len operator to test if we found anything.
  • The target is an Interface or a subnet, so for a single IP, it’s really a /32 subnet.
  • You can examine the value of traf using a log command.
  • If your simple queue is limiting on “Total” then you can use total-bytes, but if the queue has its limits on Target Upload and Target Download (which I think you do because you’re setting max-limit), you have to use the bytes statistic which has both send and receive so you have to split it first with the :pick and :find operators.
  • I wouldn’t set the max-limit using the two integers with the slash separator as you have it. The interpreter can parse that as two integers with a division and you end up with “max-limit=0.5” (this behavior has been version dependent in the past).

Putting all of that together:

:local traf
:local dntraf
:local uptraf
:local s
:local a
:for i from=250 to=253 do={
  :set s ("192.168.0.".$i."/32")
  :set a [/queue simple find where target=$s]
  :if ([:len $a] > 0) do={
    :set a [:pick $a 0 1]
    :set traf [get $a bytes]
    :log info $traf
    :set uptraf [:pick $traf 0 [:find $traf "/"]]
    :set dntraf [:pick $traf ([:find $traf "/"]+1) [:len $traf]]
    :if (($uptraf+$dntraf) > 2097152) do={
      :set $a max-limit="32000/64000"
    } else={
      :log info ("Can't find queue for ".$s)
    }
  }
}

Note that while the array $a may have more than one element, I’m only processing the first one (other queues with the same target further down the list wouldn’t matter anyway). Also, I stuck the search parameter in a variable so I could use it in the log again in the else case – you can simplify that out.

Why not a per connection limit? Instead of an script. Use the source IP as your identifier.

Sent from my Nexus 4 using Tapatalk

Hi thanks for those comments. JJCINAZ i did try your code and still it does not limit it. I made sure I had a computer with ip 192.168.0.253 connected to the rb750. This ip address has a simple que created on it limiting the user to 4m down and 1m up.I ran the speedtest and speeds are correct. Then I ran youtube on this computer to build up some data about 5mb, executed your script, hoping the bandwidth limit would kick in, ran speedtest again and no difference, still have 4m down and 1m up. So where am i going wrong, v6.2??

Sorry, left out a line:

:local traf
:local dntraf
:local uptraf
:local s
:local a
/queue simple
:for i from=250 to=253 do={
  :set s ("192.168.0.".$i."/32")
  :set a [/queue simple find where target=$s]
  :if ([:len $a] > 0) do={
    :set a [:pick $a 0 1]
    :set traf [get $a bytes]
    :log info $traf
    :set uptraf [:pick $traf 0 [:find $traf "/"]]
    :set dntraf [:pick $traf ([:find $traf "/"]+1) [:len $traf]]
    :if (($uptraf+$dntraf) > 2097152) do={
       set $a max-limit="32000/64000"
    } else={
      :log info ("Can't find queue for ".$s)
    }
  }
}

Also, here’s a more explicit version where the interactions with the simple queues are more evident:

:local traf
:local dntraf
:local uptraf
:local s
:local a
:for i from=250 to=253 do={
  :set s ("192.168.0.".$i."/32")
  :set a [/queue simple find where target=$s]
  :if ([:len $a] > 0) do={
    :set a [:pick $a 0 1]
    :set traf [/queue simple get $a bytes]
    :log info $traf
    :set uptraf [:pick $traf 0 [:find $traf "/"]]
    :set dntraf [:pick $traf ([:find $traf "/"]+1) [:len $traf]]
    :if (($uptraf+$dntraf) > 2097152) do={
       /queue simple set $a max-limit="32000/64000"
    } else={
      :log info ("Can't find queue for ".$s)
    }
  }
}