BGP ignores local pref

In my MikroTik lab (6.43.7), BGP local pref seems to be ignored. Presented with two paths to destination 192.168.99.11/32 via two alternative BGP next hops (192.168.99.1 & 192.168.99.2), the router choses the next hop with a worse local pref of 50 (192.168.99.2), instead of chosing the next hop with a better local pref of 150 (192.168.99.1):

/ip route print detail where routing-mark=VRF1 dst-address=192.168.99.11/32
Flags: X - disabled, A - active, D - dynamic, C - connect, S - static, r - rip, b - bgp, o - ospf, m - mme, B - blackhole, U - unreachable, P - prohibit 
 0 ADb  dst-address=192.168.99.11/32 gateway=192.168.99.2 gateway-status=192.168.99.2 recursive via 192.168.98.33 ether1 distance=200 scope=40 target-scope=30 routing-mark=VRF1 bgp-as-path="65000" 
        bgp-local-pref=50 bgp-med=0 bgp-origin=incomplete bgp-ext-communities="RT:65010:0,RT:65010:2" 

 1  Db  dst-address=192.168.99.11/32 gateway=192.168.99.1 gateway-status=192.168.99.1 recursive via 192.168.98.33 ether1 distance=200 scope=40 target-scope=30 routing-mark=VRF1 bgp-as-path="65000" 
        bgp-local-pref=150 bgp-med=0 bgp-origin=incomplete bgp-ext-communities="RT:65010:0,RT:65010:2"

This behaviour is puzzling for me since I can’t see any difference between the two routes which would make next hop 192.168.99.2 more attractive.

When disabling peer 192.168.99.2 (pref 50), the route via 192.168.99.1 (pref 150) becomes active

/routing bgp peer disable numbers=2
/ip route print detail where routing-mark=VRF1 dst-address=192.168.99.11/32
Flags: X - disabled, A - active, D - dynamic, C - connect, S - static, r - rip, b - bgp, o - ospf, m - mme, B - blackhole, U - unreachable, P - prohibit 
 0 ADb  dst-address=192.168.99.11/32 gateway=192.168.99.1 gateway-status=192.168.99.1 recursive via 192.168.98.33 ether1 distance=200 scope=40 target-scope=30 routing-mark=VRF1 bgp-as-path="65000" 
        bgp-local-pref=150 bgp-med=0 bgp-origin=incomplete bgp-ext-communities="RT:65010:0,RT:65010:2"

When enabling peer 192.168.99.2 (pref 50) again, the router switches back to the lower local pref next hop 192.168.99.2:

/routing bgp peer enable numbers=2
/ip route print detail where routing-mark=VRF1 dst-address=192.168.99.11/32
Flags: X - disabled, A - active, D - dynamic, C - connect, S - static, r - rip, b - bgp, o - ospf, m - mme, B - blackhole, U - unreachable, P - prohibit 
 0 ADb  dst-address=192.168.99.11/32 gateway=192.168.99.2 gateway-status=192.168.99.2 recursive via 192.168.98.33 ether1 distance=200 scope=40 target-scope=30 routing-mark=VRF1 bgp-as-path="65000" 
        bgp-local-pref=50 bgp-med=0 bgp-origin=incomplete bgp-ext-communities="RT:65010:0,RT:65010:2" 

 1  Db  dst-address=192.168.99.11/32 gateway=192.168.99.1 gateway-status=192.168.99.1 recursive via 192.168.98.33 ether1 distance=200 scope=40 target-scope=30 routing-mark=VRF1 bgp-as-path="65000" 
        bgp-local-pref=150 bgp-med=0 bgp-origin=incomplete bgp-ext-communities="RT:65010:0,RT:65010:2"

Even in the vpnv4 tables I cannot spot anything which would explain the behaviour that a route with lower local pref is prefered over a similar route with higher local pref:

/routing bgp vpnv4-route print detail where dst-address=192.168.99.11/32
Flags: L - label-present 
 0 L route-distinguisher=192.168.99.1:0 dst-address=192.168.99.11/32 gateway=192.168.99.1 interface=ether1 in-label=10029 out-label=10029 bgp-as-path="65000" bgp-local-pref=150 bgp-med=0 bgp-origin=incomplete 
     bgp-ext-communities="RT:65010:0,RT:65010:2" 

 1 L route-distinguisher=192.168.99.2:0 dst-address=192.168.99.11/32 gateway=192.168.99.2 interface=ether1 in-label=20025 out-label=20025 bgp-as-path="65000" bgp-local-pref=50 bgp-med=0 bgp-origin=incomplete 
     bgp-ext-communities="RT:65010:0,RT:65010:2"

Very complete detailed explanation of the problem, can’t thank you enough for that. These routes are being learned from the same BGP instance correct?

There is only a single (default) BGP instance running on the device. iBGP is fully meshed, the routes are learned by different iBGP peers, one peer (192.168.99.1) advertises with local preference 125, the other peer (192.168.99.2) advertises with local preference 75. Which route is selected as active seems to be random.

The issue does btw NOT occur with address family ip (main routing table). In the main routing table, BGP local pref is working as expected. Only vpnv4 is affected by the phenomenon.

vpnv4 example, showing a single route (scroll down to #9) with worse local preference getting selected:

### OK ###
 7 ADb  dst-address=217.10.64.0/20 gateway=192.168.99.1 gateway-status=192.168.99.1 recursive via 192.168.98.49 ether1 distance=200 scope=40 target-scope=30 routing-mark=VRF2 bgp-local-pref=125 
        bgp-origin=incomplete bgp-ext-communities="RT:65010:20" 
        
### OK ###
 8  Db  dst-address=217.10.64.0/20 gateway=192.168.99.2 gateway-status=192.168.99.2 recursive via 192.168.98.49 ether1 distance=200 scope=40 target-scope=30 routing-mark=VRF2 bgp-local-pref=75 
        bgp-origin=incomplete bgp-ext-communities="RT:65010:20"

### Active although lower preference than next route! ####
 9 ADb  dst-address=217.116.112.0/20 gateway=192.168.99.2 gateway-status=192.168.99.2 recursive via 192.168.98.49 ether1 distance=200 scope=40 target-scope=30 routing-mark=VRF2 bgp-local-pref=75 
        bgp-origin=incomplete bgp-ext-communities="RT:65010:20"

### Inactive although higher prerefence than route before! ###
10  Db  dst-address=217.116.112.0/20 gateway=192.168.99.1 gateway-status=192.168.99.1 recursive via 192.168.98.49 ether1 distance=200 scope=40 target-scope=30 routing-mark=VRF2 bgp-local-pref=125 
        bgp-origin=incomplete bgp-ext-communities="RT:65010:20"

I wonder if they just flipped the rule or something in the code, very odd. I wonder if this exist on the other families in the same way (ie ipv6 unicast or l2vpn) or just the vpnv4…in any event this seems like it needs a bug report filed

Does both VPNv4 routes have unique RD? As far as I have seen it is happening when there is misconfiguration with route distinguishers.