When the unreachable phenomenon occurs, the BGP route received by ROS-01 from ROS-02 is also unreachable. At this time, when the static route Check-gateway of ROS-01 is disabled, the static route and BGP return to normal.
It sounds like you're seeing what I'm seeing, then. I think the behavior might seem a little strange but I don't suspect it's a bug. I know a lot of things are different about the routing/packet handling subsystems of v7.x.x, so I'll test this next and see if I can confirm.
I'll make an attempt at explaining why I think this behavior is reasonable and the details mostly come down to how packet processing is implemented in most routers: the RIB, the FIB, and the adjacency table. The RIB is mostly [1] what's represented by
:ip route print in that it contains all routes that the router knows about from all sources, used or unused. Despite how it looks, the RIB is not directly used to make packet forwarding decisions. Instead, the RIB is cooked down through a variety of rules (active or inactive routes, best route selection, reachability of next-hops, recursive next-hops, policy routing, etc.) into a simplified set of tables: the FIB (containing only the active set of longest-prefix match information and a corresponding adjacency reference for each) and the adjacency table (basically physical ports and metadata about how to modify the packet). This is certainly an oversimplification and indeed some of these details are opaque or I am ignorant to re: RouterOS specifically. For example, the documentation says RouterOS does go further still by caching FIB lookups for identical flows. Mikrotik does have some level of information about this here [2].
What I think is happening here from looking at the behavior is that the
check-gateway=ping feature directly operates on the adjacency entry. Even though you might have any number of routes that all point to a single adjacency (in your case 10.10.10.2), the structure of the FIB does not know or care that these routes came from BGP or static routes or whatever, only what the longest-prefix match information is and a single reference to the common adjacency. You may hypothetically have hundreds of thousands of routes that all have the same next hop, and rather than make an identical and wasteful decision on each and every one, the FIB only contains many entries all referencing one adjacency. When the
check-gateway=ping function fails a ping test, it seems like it comes along in the
adjacency table and either purges or suppresses that entire adjacency.
I suspect this was simply an implementation choice. One option is to assume that when the operator wants to alter routing policy and invalidate a next-hop for being unreachable by ICMP echo that they intend for this to be a property of the
next-hop adjacency and not a property of the
particular route that you configure the
check-gateway=ping clause on. The other option is to assume the opposite: that the operator intends for this to only be a property of the route. The second option seems to have dubious practical benefit. If the operator decides that 10.10.10.2 is unreachable, why would they want any
other routes that rely on it to be installed in the FIB? Furthermore, you would need to separate all of the routes with
check-gateway=ping and those without into two piles when constructing the FIB and the adjacency table. And for what purpose?
If this is in fact what's happening, this seems to be the more reasonable of the two choices. For example ... do you have a specific use case for why you want those BGP routes to be reachable even though you are creating the circumstances to invalidate that static route? It's not obvious to me. Maybe what you're trying to accomplish can be accomplished some other way.
[1] The
:ip route print detail form of the command also is the only glimpse I know of for what actually happened in the FIB in v6.x.x, so it's not entirely pure. It's mostly just RIB information, though.
[2]
https://wiki.mikrotik.com/wiki/Manual:IP/Route