Script to keep a NAT rule at top

Hello every one
I need a script to automatically check and keep a action=masquerade chain=srcnat rule at the top of the others because there is a action=src-nat chain=srcnat rule that is being dynamically generated that sits at the top (#=0), But I want to always have the action=masquerade chain=srcnat rule at the top (#=0). I tried to move it manually but after each time that action=src-nat chain=srcnat rule regenerates it’s sit at the top position again, so that’s why the script should check or try to move the masquerade rule to the top very frequently.
I will appreciate any help

Wrong approach?

What regenerate the NAT rule?

Simply update the rule instead to delete and recreate…

IPsec IKEV2 mode-config
Screenshot 2021-10-28 221402.jpg

What is the dynamic Rule 0.

IPsec IKEV2, mode-config cause it’s use a src-address-list from add address list so that’s why when tunnel is established it will put that dynamic nat rule. which I want it to be at position 1 instead of 0, so that’s why I need a script to move the not delete or recreate just move this one down in the list to 1 from 0 or move that masquerade one up in the list to 0 from 1.

Add a comment to the NAT masquerade rule that be moved on top… like “ONTOP”

Schedule this:

/ip firewall nat
:if ( ([find]->0) != ([find where comment="ONTOP"]->0) ) do={
    move [find where comment="ONTOP"] destination=*0
}

If “ONTOP” not exist, or NAT is empty, this script do not give error.

Traduced:
If on the IP / Firewall / NAT the .id of first item of all rules is not the same .id of the rule that have “ONTOP” as comment,
move the rule that have “ONTOP” as comment on first place.

EDIT:
The script is not meant to move multiple rules, but:
if multiple rules have ONTOP as a comment, after the script they are brought to the front in the reverse order in which they appear within the rule order.
For example if the rules are:

/ip firewall nat
add action=log chain=srcnat log-prefix=77
add action=log chain=srcnat comment=ONTOP log-prefix=11
add action=log chain=srcnat log-prefix=22
add action=log chain=srcnat comment=ONTOP log-prefix=55
add action=log chain=srcnat log-prefix=6
add action=log chain=srcnat comment=ONTOP log-prefix=4
add action=log chain=srcnat log-prefix=99
add action=log chain=srcnat comment=ONTOP log-prefix=158

after the script the order is:

/ip firewall nat
add action=log chain=srcnat comment=ONTOP log-prefix=158
add action=log chain=srcnat comment=ONTOP log-prefix=4
add action=log chain=srcnat comment=ONTOP log-prefix=55
add action=log chain=srcnat comment=ONTOP log-prefix=11
add action=log chain=srcnat log-prefix=77
add action=log chain=srcnat log-prefix=22
add action=log chain=srcnat log-prefix=6
add action=log chain=srcnat log-prefix=99

If is needed to move an ordered block of rules on top,
assign comment like ONTOP1, ONTOP2 … ONTOP10, ONTOP11, etc.
On script are checked only first 100 “ONTOP”, but if more is needed ( ??? !!! ) can be used an higher number
If some number is deleted or forgetted, no problems or errors.

/ip firewall nat
:for x from=100 to=0 step=-1 do={
    :if ( ([find]->0) != ([find where comment="ONTOP$x"]->0) ) do={
        move [find where comment="ONTOP$x"] destination=*0
    }
}

and from this:

/ip firewall nat
add action=log chain=srcnat log-prefix=77
add action=log chain=srcnat comment=ONTOP2 log-prefix=11
add action=log chain=srcnat log-prefix=22
add action=log chain=srcnat comment=ONTOP3 log-prefix=55
add action=log chain=srcnat log-prefix=6
add action=log chain=srcnat comment=ONTOP55 log-prefix=4
add action=log chain=srcnat log-prefix=99
add action=log chain=srcnat comment=ONTOP9 log-prefix=158

can be obtained this:

/ip firewall nat
add action=log chain=srcnat comment=ONTOP2 log-prefix=11
add action=log chain=srcnat comment=ONTOP3 log-prefix=55
add action=log chain=srcnat comment=ONTOP9 log-prefix=158
add action=log chain=srcnat comment=ONTOP55 log-prefix=4
add action=log chain=srcnat log-prefix=77
add action=log chain=srcnat log-prefix=22
add action=log chain=srcnat log-prefix=6
add action=log chain=srcnat log-prefix=99

Thanks it worked.

EDIT:
Added the missing description of what happen if multiple rules have ONTOP as comment on 1st case,
and another script with the ability to sort multiple rules at time.

It was working untill the SA rekey happened and after that instead of move the nat rule up it’s move it down at the last position (13) and no matter how many time it’s trying it’s gonna be the same. untill I reboot the router

up!

Add /ip firewall nat print without-paging at the start of the script you have. This will trigger the NAT lines to have number and I don’t mean only those you see in Winbox.

thanks @msatter


/ip firewall nat

# msatter hint
print without-paging

:for x from=100 to=0 step=-1 do={
    :if ( ([find]->0) != ([find where comment="ONTOP$x"]->0) ) do={
        move [find where comment="ONTOP$x"] destination=*0
    }
}

Thanks @rextended @msatter