Community discussions

MikroTik App
 
User avatar
VictorS
just joined
Topic Author
Posts: 11
Joined: Sun Apr 14, 2024 4:41 pm

Garbage collect old routes and duplicate routes

Fri Jan 24, 2025 9:57 am

Dear Colleagues,

I have written a script to add host routes to the IPv4 routing table, please see the complete script below. The problem however is that on each invocation, the script creates duplicate entries in the routing table, and of course it does not delete old entries (which it created when the IP addresses were different). Can you please advise me some way to detect obsolete entries? It would be nice to use some timestamps on configuration entries, but I don't know of such a feature existing in RouterOS.

The script itself:
# extract addresses in the list
:local AddressList [/ip firewall address-list find comment~"api\\."];
:local ipAddress;
:foreach entry in=$AddressList do={
 :set ipAddress  ([/ip firewall address-list get $entry]->"address");
 :put ($ipAddress."/32");
 /ip/route/add comment=([/ip firewall address-list get $entry]->"comment") disabled=no distance=1 dst-address=($ipAddress."/32")  gateway=10.x.x.x routing-table=main;
};
Of course I could delete all the generated routes on each script invocation, like in
# delete all API routes
/ip/route/remove  [find comment~"api\\."];
But this will probably cause traffic disruptions if I run the script from cron.
 
User avatar
rextended
Forum Guru
Forum Guru
Posts: 12658
Joined: Tue Feb 25, 2014 12:49 pm
Location: Italy
Contact:

Re: Garbage collect old routes and duplicate routes

Fri Jan 24, 2025 3:38 pm

I won't write it down, but I'll give you an idea.

Scroll through the list of addresses.
For each of theroutes you find that are the same as the ones you need,
update the comment with a prefix and today's date (for example "$comment 2025/01/24 14:30")
add the routes that don't exist, always with the same comment "$comment 2025/01/24 14:30"

Finally, delete among all the routes that contain "api." those with a comment that not containing "2025/01/24 14:30"
/ip/route/remove [find where (comment~"api\\.") and !(comment~"2025/01/24 14:30")]
 
User avatar
VictorS
just joined
Topic Author
Posts: 11
Joined: Sun Apr 14, 2024 4:41 pm

Re: Garbage collect old routes and duplicate routes

Fri Jan 24, 2025 4:18 pm

Basically, this boils down to

1. At the start of the script, generate some unique string (e.g. :timestamp )
2. Add this string to the comments of all the routes generated within this iteration of the script
3. At the end of the script, delete all the routes which do not contain this unique string

Do I understand your idea correctly?
 
User avatar
rextended
Forum Guru
Forum Guru
Posts: 12658
Joined: Tue Feb 25, 2014 12:49 pm
Location: Italy
Contact:

Re: Garbage collect old routes and duplicate routes

Fri Jan 24, 2025 4:41 pm

Basically, yes, but for be more "nice" on the point 2: on foreach cycle at the same time you UPDATE the comment if the rule already exist AND add new rules with :timestamp.

This do not delete what already exist (and must be keeped) and do not (temporarly) duplicate rules.
 
User avatar
VictorS
just joined
Topic Author
Posts: 11
Joined: Sun Apr 14, 2024 4:41 pm

Re: Garbage collect old routes and duplicate routes

Fri Jan 24, 2025 4:48 pm

Why would I care to take into account what already exists when I can create a bunch of new routes with the current timestamp (even if they are duplicates of the older routes, it does not seem to cause any harm) and then delete everything with non-current timestamps? This looks much simpler, unless it is wrong for some reason.
 
User avatar
rextended
Forum Guru
Forum Guru
Posts: 12658
Joined: Tue Feb 25, 2014 12:49 pm
Location: Italy
Contact:

Re: Garbage collect old routes and duplicate routes

Fri Jan 24, 2025 4:54 pm

This produce same output at the end, but is just for progam in "nice" way (avoid duplicates, avoid deleting what must be rewrited, etc.).

Anyway, the important thing is the rest, which I think you understood from my suggestion.
 
User avatar
BartoszP
Forum Guru
Forum Guru
Posts: 3096
Joined: Mon Jun 16, 2014 1:13 pm
Location: Poland

Re: Garbage collect old routes and duplicate routes

Fri Jan 24, 2025 5:38 pm

Tip no. 1:

Use route marking. Make a mangle rule that mark packets from your list with routing mark and stay away from routing table where the only route rule for all that addresses (route mark) is needed. No matter when and how you update the list only members of it would get the needed routing with no hickups

Tip no. 2:
The list that you prepare should be timebased so when you add an entry to it then you should set timer for the entry for eg. 6 hours if you refresh that list every 6 hours. When you readd the entry during that period you just refresh/reset that timer, if not the entry just vanishes. No need to worry of any leftovers.

Tip no. 3:

Read that "The International Microtik Obsfucated Code Contest" :) :) for updating address lists: viewtopic.php?p=606832#p606832
 
User avatar
rextended
Forum Guru
Forum Guru
Posts: 12658
Joined: Tue Feb 25, 2014 12:49 pm
Location: Italy
Contact:

Re: Garbage collect old routes and duplicate routes

Fri Jan 24, 2025 6:17 pm

Tip n.1 for tip n.1: Use routing / rules. Each item has it's own tool.... when MikroTik finally add address-lists to routing rules........................
 
User avatar
BartoszP
Forum Guru
Forum Guru
Posts: 3096
Joined: Mon Jun 16, 2014 1:13 pm
Location: Poland

Re: Garbage collect old routes and duplicate routes

Fri Jan 24, 2025 9:41 pm

Tip 1 to tip 1 to tip 1:

Address list for marking routes in mangling
One route rule to route mangled packets.
 
User avatar
rextended
Forum Guru
Forum Guru
Posts: 12658
Joined: Tue Feb 25, 2014 12:49 pm
Location: Italy
Contact:

Re: Garbage collect old routes and duplicate routes

Fri Jan 24, 2025 11:42 pm

(when MikroTik have done) generic tip: do not use firewall to do routing job....
 
User avatar
BartoszP
Forum Guru
Forum Guru
Posts: 3096
Joined: Mon Jun 16, 2014 1:13 pm
Location: Poland

Re: Garbage collect old routes and duplicate routes

Sat Jan 25, 2025 12:34 am

You just killed "policy routing" idea :) https://help.mikrotik.com/docs/spaces/R ... cy+Routing
Policy routing is the method to steer traffic matching certain criteria to a certain gateway. .....
RouterOS gives you two options to choose from:
firewall mangle - it gives more control over the criteria to be used to steer traffic, for example, per connection or per packet balancing, etc. For more info on how to use mangle marking see Firewall Marking examples......
The problem IMHO is that mangling is in the Firewall menu even if it provides mostly nonfirewall services but that place suggest that mangle is firewall thing. For me the most firewall-like actions are the green ones.
  • change-dscp - change the Differentiated Services Code Point (DSCP) field value specified by the new-dscp parameter
  • change-mss - change the Maximum Segment Size field value of the packet to a value specified by the new-mss parameter
  • change-ttl - change the Time to Live field value of the packet to a value specified by the new-ttl parameter
  • clear-df - clear 'Do Not Fragment' Flag
  • fasttrack-connection - shows fasttrack counters, useful for statistics
  • mark-connection - place a mark specified by the new-connection-mark parameter on the entire connection that matches the rule
  • mark-packet - place a mark specified by the new-packet-mark parameter on a packet that matches the rule
  • mark-routing - place a mark specified by the new-routing-mark parameter on a packet. This kind of mark is used for policy routing purposes only. Do not apply any other routing marks besides "main" for the packets processed by FastTrack, since FastTrack can only work in the main routing table.
    route - forces packets to a specific gateway IP by ignoring normal routing decisions (prerouting chain only)
  • set-priority - set priority specified by the new-priority parameter on the packets sent out through a link that is capable of transporting priority (VLAN or WMM-enabled wireless interface). Read more
  • sniff-pc - send a packet to a remote RouterOS CALEA server.
  • sniff-tzsp - send a packet to a remote TZSP compatible system (such as Wireshark). Set remote target with sniff-target and sniff-target-port parameters (Wireshark recommends port 37008)
  • strip-ipv4-options - strip IPv4 option fields from IP header, the action does not actually remove IPv4 options but rather replaces all option octets with NOP, further matcher with ipv4-options=any will still match the packet.
 
User avatar
VictorS
just joined
Topic Author
Posts: 11
Joined: Sun Apr 14, 2024 4:41 pm

Re: Garbage collect old routes and duplicate routes

Sat Jan 25, 2025 12:06 pm

Basically, yes, but for be more "nice" on the point 2: on foreach cycle at the same time you UPDATE the comment if the rule already exist AND add new rules with :timestamp.

This do not delete what already exist (and must be keeped) and do not (temporarly) duplicate rules.
I agree that your proposal looks nicer, but as I am writing this script to solve a very small personal problem (changing IP addresses of load balancers), I prefer the solution to be quick and simple, and I am ready for it to be dirty. I only have to write a couple of scripts in RouterOS and will probably never need the language again for several years.
 
User avatar
VictorS
just joined
Topic Author
Posts: 11
Joined: Sun Apr 14, 2024 4:41 pm

Re: Garbage collect old routes and duplicate routes

Sat Jan 25, 2025 12:16 pm

Tip no. 1:

Use route marking. Make a mangle rule ...
Oh no. In fact, I tried to solve my problem first with address-lists + PBR (policy based routing). There are many examples of PBR for Mikrotik in the internet, using the firewall and multiple routing tables.

It worked but (!) TCP worked SO slowly that kubectl and Lens did not tolerate such response times and produced errors. I was never able to find the reason why packets going via PBR were so slow and had to revert to regular routing which works fast.

I even thought of using BGP to announce those dozen /32 routes to Mikrotik, but the solution with DNS -> routing seems simpler to implement though it requires scripting (and I am a newbie in RouterOS scripting).
 
MrYan
Member Candidate
Member Candidate
Posts: 174
Joined: Sat Feb 27, 2010 6:13 pm

Re: Garbage collect old routes and duplicate routes

Sat Jan 25, 2025 1:44 pm

Oh no. In fact, I tried to solve my problem first with address-lists + PBR (policy based routing). There are many examples of PBR for Mikrotik in the internet, using the firewall and multiple routing tables.

It worked but (!) TCP worked SO slowly that kubectl and Lens did not tolerate such response times and produced errors. I was never able to find the reason why packets going via PBR were so slow and had to revert to regular routing which works fast.
Chances are that you were fast-tracking the traffic subject to PBR. It will work very slowly because some packets will use the slow path and get through. From https://help.mikrotik.com/docs/spaces/R ... n+tracking:
Note that not all packets of the connection can be FastTracked, so it is likely to see some packets going through a slow path even though the connection is marked for FastTrack. This is the reason why fasttrack-connection is usually followed by an identical "action=accept" rule.
If using connection-mark then excluding these from the fasttrack rule should work:
chain=forward action=fasttrack-connection connection-state=established,related connection-mark=no-mark
 
User avatar
VictorS
just joined
Topic Author
Posts: 11
Joined: Sun Apr 14, 2024 4:41 pm

Re: Garbage collect old routes and duplicate routes

Sat Jan 25, 2025 1:53 pm


Tip no. 2:
The list that you prepare should be timebased so when you add an entry to it then you should set timer for the entry for eg. 6 hours if you refresh that list every 6 hours. When you readd the entry during that period you just refresh/reset that timer, if not the entry just vanishes. No need to worry of any leftovers.

Tip no. 3:

Read that "The International Microtik Obsfucated Code Contest" :) :) for updating address lists: viewtopic.php?p=606832#p606832
This brings about a question. How are address-lists resolved and refreshed? If I create an address-list from the name "api.mycluster.example" and it resolves into 3 dynamic address-lists with IP addresses, how do I make sure that these dynamic lists do not become stale and my code
:local AddressList [/ip firewall address-list find comment~"api\\."];
:foreach entry in=$AddressList do={
 :set ipAddress  ([/ip firewall address-list get $entry]->"address");
 ...
 
 
always receives the actual IP addresses?
 
User avatar
BartoszP
Forum Guru
Forum Guru
Posts: 3096
Joined: Mon Jun 16, 2014 1:13 pm
Location: Poland

Re: Garbage collect old routes and duplicate routes

Sat Jan 25, 2025 3:26 pm

As rextended suggested use comment for tagging your "dynamic" routes: viewtopic.php?p=1121406#p1121406
You have to have global variable holding the last used TAG. Add new/current routes with a new tag and delete all with old one.
If routes are doubled then only the one of them is active and even if active one is just removed the second takes over.
Do not kow if changeing the distance for the old ones to +1 could help as the first step to let the new entries get active immediately but it is just an idea.

The main question is where the "api*" list come from? Is it a list of PPoE interfaces or it is based on DHCP. If yes maybe you should consider using on/off scripts to activate/deactivate particular routes and netwatch script to clear the stale ones?
 
User avatar
VictorS
just joined
Topic Author
Posts: 11
Joined: Sun Apr 14, 2024 4:41 pm

Re: Garbage collect old routes and duplicate routes

Sat Jan 25, 2025 4:07 pm

The main question is where the "api*" list come from?
It comes from
/ip firewall address-list 
where DNS names like
api.mycluster.example
,
api.mycluster2.example
create several dynamic address lists with the
api.mycluster.example
or
api.mycluster2.example
in their comment. It happens automatically. Hence my question how these dynamic address lists are updated.
 
User avatar
BartoszP
Forum Guru
Forum Guru
Posts: 3096
Joined: Mon Jun 16, 2014 1:13 pm
Location: Poland

Re: Garbage collect old routes and duplicate routes

Sat Jan 25, 2025 4:31 pm

Seems that the TTL of the dynamic DNS based names is used to feed the list and when it expires the list is refreshed to the actual apiN.example.com
viewtopic.php?t=177324
 
User avatar
VictorS
just joined
Topic Author
Posts: 11
Joined: Sun Apr 14, 2024 4:41 pm

Re: Garbage collect old routes and duplicate routes

Sat Jan 25, 2025 4:42 pm

Seems that the TTL of the dynamic DNS based names is used to feed the list and when it expires the list is refreshed to the actual apiN.example.com
viewtopic.php?t=177324
This is good.
 
User avatar
BartoszP
Forum Guru
Forum Guru
Posts: 3096
Joined: Mon Jun 16, 2014 1:13 pm
Location: Poland

Re: Garbage collect old routes and duplicate routes

Sat Jan 25, 2025 5:10 pm

You can check it easily: make a list based on any noncrucial DNS name and then set local static DNS name with different IP and set the low test TTL for that. Then watch how and when the address list reacts to changes to static entry or disabling it.
 
User avatar
VictorS
just joined
Topic Author
Posts: 11
Joined: Sun Apr 14, 2024 4:41 pm

Re: Garbage collect old routes and duplicate routes

Mon Jan 27, 2025 4:43 am

You can check it easily: make a list based on any noncrucial DNS name and then set local static DNS name with different IP and set the low test TTL for that. Then watch how and when the address list reacts to changes to static entry or disabling it.
I have created a DNS name with 3 A RRs and TTL=300 in one of my DNS zones, and changing the RRs in DNS, I confirm that the dynamic address lists also change in Mikrotik.
 
User avatar
VictorS
just joined
Topic Author
Posts: 11
Joined: Sun Apr 14, 2024 4:41 pm

Re: Garbage collect old routes and duplicate routes

Mon Jan 27, 2025 5:47 am


/ip/route/remove [find where (comment~"api\\.") and !(comment~"2025/01/24 14:30")]
OK, the final script (quick and dirty but functional) would be

# extract addresses in the list
:local AddressList [/ip firewall address-list find comment~"api\\."];
:local ipAddress;
:local timeStamp [:timestamp]

:foreach entry in=$AddressList do={
 :set ipAddress  ([/ip firewall address-list get $entry]->"address");
 :put ($ipAddress."/32");
 /ip/route/add comment=([/ip firewall address-list get $entry]->"comment"."_$timeStamp") disabled=no distance=1 dst-address=($ipAddress."/32")  gateway=10.x.x.x routing-table=main;
};

# delete old API routes
/ip/route/remove [find where (comment~"api\\.") and !(comment~".*_$timeStamp")]