0887 371 498 support@itservice-bg.net
25.04.2022 · Самуил Арсов · MikroTik, Рутери

MikroTik: автоматични queues за DHCP клиентите

Скриптът по-долу създава автоматично simple queue за всеки клиент, който получи адрес от DHCP сървъра на MikroTik — без ръчно поддържане на списък с опашки. Поставя се в полето Lease Script на самия DHCP сървър: IP → DHCP Server → вашият сървър → Lease Script.

MikroTik DHCP сървър — полето Lease Script

MikroTik — автоматично създадени simple queues за DHCP клиентите

:local queueName "Client-$leaseActMAC";

:local ipAdd "$leaseActIP/32";

:if ([:len [/queue simple find name=$queueName]] = 0) do={
:log info "No Queue";
        /queue simple add name=$queueName target=($ipAdd) limit-at=10M/10M max-limit=10M/10M comment=[/ip dhcp-server lease get [find where active-mac-address=$leaseActMAC && active-address=$leaseActIP] host-name];
    } else={
:log info "exists";
:local ada [/queue simple get [find name=$queueName] target];
        :log info "existing $ada";
        :if ($ada = $ipAdd) do={
            :log info "IP same $ada";
        } else={
            /queue simple set target=($ipAdd) [find name=$queueName];
        }
}

Какво прави

При нов lease се създава опашка Client-<MAC> с лимит 10M/10M и коментар — името на хоста. Ако опашката вече съществува, но клиентът е получил друг адрес, target се обновява автоматично. Лимитът 10M/10M се сменя според вашите планове.

Променливите, с които разполага скриптът

RouterOS подава на Lease Script следните променливи — те са ключът, ако решите да го променяте:

$leaseActIP        адресът, който клиентът получава
$leaseActMAC       MAC адресът на клиента
$leaseServerName   името на DHCP сървъра
$leaseBound        1 при заемане, 0 при освобождаване

⚠️ Скриптът се пуска и при освобождаване

Това е нещото, което лесно се пропуска: Lease Script се изпълнява и когато lease-ът изтича, не само когато се дава. Тогава $leaseBound е 0, а $leaseActIP може да е празен — и опашката се обновява с безсмислен target. Затова в реална конфигурация първият ред трябва да е проверка:

:if ($leaseBound = 1) do={
    # тук идва създаването на опашката
} else={
    # по избор: премахване на опашката при освобождаване
    /queue simple remove [find name="Client-$leaseActMAC"]
}

Почистване на старите опашки

След няколко месеца списъкът се пълни с опашки на устройства, които отдавна не се появяват. Ръчно почистване на всичко, създадено от скрипта:

/queue simple remove [find name~"^Client-"]

Броят им се проверява така:

/queue simple print count-only where name~"^Client-"

Кога това е грешният подход

Една опашка на клиент е разбираемо и удобно за преглед, но при няколкостотин клиента става тежко за процесора — всеки пакет минава през целия списък. При такъв мащаб правилният инструмент е PCQ: една queue tree с pcq-classifier=dst-address, която разделя канала поравно между активните адреси, без отделен запис за всеки.

Ориентир от практиката: до няколкостотин клиента simple queues вършат работа; над това PCQ е задължително, ако не искате рутерът да опре в процесора, преди да опре в канала.