Error when trying to clear firewall connections

Hi folks

I’ve written a script to clear firewall connections. It works fine but occasionally it will error out with the following:

no such item (4)

I think this is due to the way RouterOS is processing the connection list. The script is as follows:

:local ConnectionList [/ ip firewall connection find]
:foreach Connection in=[$ConnectionList]
do={/ip firewall connection remove $Connection}

I think what is happening is that between storing the connections as an array and then removing them, if a connection closes, the ‘remove’ command runs against a connection which doesn’t exist, which results in the error.

I’ve tried adding an ‘on-error={’ condition to this, but I can’t get it to work, I always get syntax errors.

Can anyone tell me a way that I can either prevent this error from occurring, or handle the error gracefully?

Thanks

Try setting the TCP Established time to 5 minutes. If the socket is in use, I think it stays open?

You could also just turn off connection tracking to clear the connections, and then turn it back on.

/ip firewall connection tracking set enabled=no
/ip firewall connection tracking set enabled=yes (or auto)

-wade

Sorry, I’m not sure what the result of this would be? Could you explain a bit more?

Thanks, that would work to begin with, however long-term I am wanting the script to only clear certain connections (in this case, for VoIP phones) so I need to be able to pick which connections I clear.

This works:

# 2022.11.29 
# UDP only
local funDebug do={
    if ( true ) do={ log info ("    KILL_CONNECTIONS: " . $1) }
}
$funDebug ("start")
/ip firewall connection
:local arrConnections [find protocol=udp];
:local numErr 0;
:foreach conn in=$arrConnections do={
  :do {
    remove $conn
  } on-error={
    # $funDebug ("error on $conn")
    :set numErr ($numErr + 1)
  }
};
$funDebug ("count: " . [:len $arrConnections] . ", errors: .$numErr")
$funDebug ("finish")

It is convenient to test with torrent, because it creates a lot of connections.

Why do you try to do this in a loop? This should work just fine:

/ip/firewall/connection/remove [ find ];

eworm, please read the first post. It’s an old and well-known problem.

vklpt, please search in the forum. It’s an old and well-known problem, and already solved on better way.
http://forum.mikrotik.com/t/script-to-clean-firewall-connections-after-public-ip-changes/135275/5

I don’t see any advantage in a double search

Sure, there can be timing issues with a lot of connections in the table. But if just want to drop some SIP connections (that was the use case for original poster I think) this could still work as expected with the correct filtering:

/ip/firewall/connection/remove [ find where protocol=udp dst-address~":5060\$" ];

Use the loop if it does not.

So why don’t I use my own solution?

I don’t see any advantage in your own solution, especially from one who cannot read and understand,
and then the “if (true) do={” doesn’t make a good impression to leave pieces thrown there at random…
and then on-horror-resume-next never bodes well..

Admirable argumentation from the author of a better solution that does not even work properly (and shouldn't) lol:

better to provide arguments than to write at random

still paste this on winbox, and I do not give any error:

/ip fire conn
:foreach idc in=[find where timeout>60 and (!(dst-address~":8291\$"))] do={
    remove [find where .id=$idc]
}