What is the reason IPv4 prefixes over IPv6 BGP peer could not work?

Hi,

Just to start, I have one BGP peer to which I can only talk via IPv6 but I need to announce both IPv6 and IPv4 prefixes over it.

Sureley enough, only the IPv6 prefix is announced, although I ticked both “ip” and “ipv6” in the address families.

The only thing I could find about it is this post http://forum.mikrotik.com/t/ipv4-and-ipv6-on-a-single-bgp-peer/114017/1 which offers neither an explanation nor a solution.

I just can’t find a mistake and I tried any conceivable option but the IPv4 prefix (1.2.3.0/24) just does’t show up:

/routing bgp adv print       
PEER     PREFIX               NEXTHOP          AS-PATH                                                         ORIGIN     LOCAL-PREF
bgptun... 2a0e:affe:cafe::/46  2a09:affe:cafe:...                                                                 igp

Below is my BGP config:

/routing bgp instance
set default as=xxxxxx client-to-client-reflection=no router-id=aa.bb.cc.dd
/routing bgp network
add network=1.2.3.0/24 synchronize=no
add network=2a0e:affe:cafe::/46 synchronize=no
/routing bgp peer
add address-families=ip,ipv6 in-filter=tnl-in multihop=yes name=bgptun out-filter=tnl-out \
    remote-address=2a09:affe:cafe:180::1 remote-as=yyyyy ttl=default update-source=2a09:cafe:affe:180::2
/routing filter
add action=accept address-family=ip chain=tnl-out prefix=1.2.3.0/24
add action=accept address-family=ipv6 chain=tnl-out prefix=2a0e:affe:cafe::/46
add action=reject chain=tnl-out
add action=discard chain=tnl-in

I had the lab open and figured I’d take a crack at this.

I get unexpected behavior also, although in a slightly different way. Whether I use synchronize=no or synchronize=yes plus a static tie-down route, the 1.2.3.0/24 address does show up in /routing bgp advertisements for me. All is not well, though, as it shows up with a next hop of 0.0.0.0. This is even with /routing bgp peer set nexthop-choice=force-self configured. It just ignores it.

Because RouterOS doesn’t to my knowledge actually have a way to show you the RIB-IN for a peer, I decided to just modify your otherwise trivial routing filters to just log the prefixes and accept them. When the peer comes up, log messages on the sender capture that both the IPv4 and IPv6 prefixes trigger the tnl-out match and get sent to the peer. On the other side, though, only the IPv6 prefix triggers the tnl-in match and get processed and installed into the table.

Upon further inspection, a packet capture of the BGP TCP session reveals that the UPDATE for the 1.2.3.0/24 NLRI does actually get advertised, including the NEXT_HOP of 0.0.0.0. Whether or not an all zeroes NEXT_HOP field has defined behavior in the RFCs is a level of esoterica that I wasn’t able to figure out, but it might make sense that RouterOS would simply discard such an UPDATE as malformed and it would never hit the RIB-IN and consequently never the filters to be logged.

For reference, this is on 6.49.2 stable (two CHRs). What version did you test this on?

Either way, I’m at a bit of a loss and hopefully someone from support notices this or you can start a case and point them here.

Here are the two configs for reference:

[admin@[LAB]routerA] > exp
# dec/15/2021 11:48:52 by RouterOS 6.49.2
# software id =
#
#
#
/interface bridge
add name=loopback0 protocol-mode=none
/interface wireless security-profiles
set [ find default=yes ] supplicant-identity=MikroTik
/routing bgp instance
set default as=64512 client-to-client-reflection=no router-id=1.1.1.1
/ip dhcp-client
add disabled=no interface=ether1
/ipv6 address
add address=2a09:affe:cafe:180::1/128 advertise=no interface=loopback0
/ipv6 route
add distance=1 dst-address=2a09:affe:cafe:180::2/128 gateway=fe80::5200:ff:fe0a:0%ether1
/routing bgp network
add network=1.2.3.0/24 synchronize=no
add network=2a0e:affe:cafc::/46 synchronize=no
/routing bgp peer
add address-families=ip,ipv6 in-filter=tnl-in name=routerB nexthop-choice=force-self out-filter=tnl-out remote-address=\
    2a09:affe:cafe:180::2
/routing filter
add action=log chain=tnl-in
add action=accept chain=tnl-in
add action=log chain=tnl-out
add action=accept chain=tnl-out
/system identity
set name="[LAB]routerA"

============================================================

[admin@[LAB]routerB] > exp
# dec/15/2021 11:48:55 by RouterOS 6.49.2
# software id =
#
#
#
/interface bridge
add name=loopback0 protocol-mode=none
/interface wireless security-profiles
set [ find default=yes ] supplicant-identity=MikroTik
/routing bgp instance
set default as=64512 client-to-client-reflection=no router-id=2.2.2.2
/ip dhcp-client
add disabled=no interface=ether1
/ipv6 address
add address=2a09:affe:cafe:180::2/128 advertise=no interface=loopback0
/ipv6 route
add distance=1 dst-address=2a09:affe:cafe:180::1/128 gateway=fe80::5200:ff:fe09:0%ether1
/routing bgp network
add network=1.2.3.0/24 synchronize=no
add network=2a0e:affe:cafc::/46 synchronize=no
/routing bgp peer
add address-families=ip,ipv6 in-filter=tnl-in name=routerB nexthop-choice=force-self out-filter=tnl-out remote-address=\
    2a09:affe:cafe:180::1
/routing filter
add action=log chain=tnl-in
add action=accept chain=tnl-in
add action=log chain=tnl-out
add action=accept chain=tnl-out
/system identity
set name="[LAB]routerB"

Update:

Redistributing static routes produces a similar result where expected behavior occurs with IPv6 routes but not with IPv4 routes. The one eligible tie-down static for 1.2.3.0/24 makes it through the out filter but not the in filter on the other side. The packet capture witnesses it go out with a 0.0.0.0 nexthop again.

For laughs I gave it a shot in v7.1stable. The BGP configuration is a little bit foreign to me still. The good news is that if you redistribute static, both v4 and v6 prefixes get advertised correctly and received correctly. I’m having trouble originating anything through the new routing bgp connection set output.network= method, though. Even if it works, I’m not sure how that’s going to work in this case because ip firewall address-list and ipv6 firewall address-list are different. I’m not sure if it lets you specify multiple. Specifying one though, it doesn’t appear to advertise the prefix even though the tie-down route is present. Mysterious, but I’m less confident that it’s not a configuration issue than I would be with v6.

I was doing this pretty late at night and think I was a bit sleep deprived. Thinking about it with a clearer head in the morning, of course there’s no IPv4 NEXT_HOP because there’s no configured IPv4 address to use.

Does your configuration have at least one IPv4 address configured to use as transport?

edit: Yep, that was it. Also, if you use nexthop-choice=force-self you do also need to make sure to have an installed route to the next hop. I’m learning a lot about Mikrotik’s BGP implementation in terms of how frustrating it is to not be able to examine the RIB-IN directly :slight_smile:

eduplant, did you get this working in the context of the purported support for RFC5549? I have afi4 over an IPv6 peering, but routes don’t go active. I can manipulate the gw / gw-interface using route filters, but only static IPv4 routes with IPv6 nexthops will go active. Any pointers? Thanks.

RFC8950 - Advertising IPv4 Network Layer Reachability Information (NLRI) with an IPv6 Next Hop

As of today 2025-03-13 in 7.18.2 it is not possible to route IPv4 over an IPv6 BGP connection.
Routes will be displayed on each other router, but is unreachable because of lack of routing via inet6.
Screenshot 2025-03-13 223011.jpeg
In Linux you could do that via

$ ip route default via inet6 fe80::21b:21ff:febb:6934 dev wlp0s20f3 src 169.265.0.30

To be clear, routing ipv4 over ipv6 do work.

[admin@CCR2004_2XS_111] /ip/route> add dst-address=1.2.3.4 gateway=fe80::de2c:6eff:fec5:a7ff%sfp-sfpplus1
[admin@CCR2004_2XS_111] /ip/route> print 
...
1  As  1.2.3.4/32          fe80::de2c:6eff:fec5:a7ff%sfp-sfpplus1         1

Currently only feature that is not implemented is RFC8950, that allows to advertise ipv6 nexthops for IPv4 NLRIs