Re: Source address selection failure when using RFC5549-style (v4-via-v6) routes

Zhenlei Huang <[email protected]>
Newsgroups gmane.os.freebsd.devel.net
Message-ID <[email protected]>

> On Aug 5, 2025, at 10:09 PM, Felix <[email protected]> wrote:
> 
> I've been experimenting a bit with routing IPv4 via IPv6 next-hops, something that FreeBSD has supported since 13.1
> [https://reviews.freebsd.org/D30398].
> 
> My understanding (note: I'm not a professional network engineer) is that this is normally used with routing protocols like BGP (RFC5549, often called "extended nexthop") or Babel (RFC9229), where it's extremely convenient - the links between your routers only need link-local v6 addresses to forward both v4 and v6 traffic, reducing configuration and saving IP addresses. Of course, each router should have /one/ routable v4 and v6 address so that it can return ICMP messages and so on, which one would typically assign on the loopback interface.

Yes.

> 
> For experimentation, you can create these routes directly, without running one of these protocols, like so:
> 
> # route add -net 203.0.113.2/32 -inet6 fe80::2%bge2
> add net 203.0.113.2: gateway fe80::2%bge2
> 
> # netstat -r4n
> Routing tables
> 
> Internet:
> Destination        Gateway            Flags         Netif Expire
> ...
> 203.0.113.2        fe80::2%bge2       UGHS           bge2
> ...
> 
> What I've discovered: trying to /originate/ a connection from a machine with such a route doesn't seem to work properly. Any attempts to open a TCP connection (e.g. ssh) will fail with EHOSTUNREACH:
> 
> # truss ssh 203.0.113.2
> ...
> connect(3,{ AF_INET 203.0.113.2:22 },16)         ERR#65 'No route to host'
> ...
> ssh: connect to host 203.0.113.2 port 22: No route to host
> ...
> process exit, rval = 255
> 
> When choosing a source address for an outgoing connection, FreeBSD does a route lookup (which succeeds in this case), and as a comment in sys/netinet/in_pcb.c helpfully tells us:
> 
> 	/*
> 	 * If the outgoing interface on the route found is not
> 	 * a loopback interface, use the address from that interface.
> 	 */
> 
> Because the outgoing interface doesn't /have/ a v4 address, a consistency check at the end of the function returns EHOSTUNREACH.

This is a known limitation of current IPv4 over IPv6 nexthop. I have ever asked on #net mailing list about the IPv4 source selection but no good luck. So currently it is mandatory to have an IPv4 address assigned to the outgoing interface, if originate a connection from the host. Well certainly that restrictioni is not needed for forward packets.

You can apply Lexi's workaround to overcome the issue.

> 
> Linux also supports these v4-via-v6 routes, so I can compare how it behaves. Firstly, it will use the address specified in the `src` attribute of the route if there is one (FreeBSD, AFAIK, has no such notion). Otherwise, it follows some process to pick one of the machine's addresses to use as a source address, and will (if necessary, like in this scenario) pick an address from a different interface.
> 
> I'm not sure what the right thing for FreeBSD to do in this circumstance is. What do you think?

I think we should borrow some rules from IPv6 source address selection. I have not tried Linux, but I think use a global unicast address from loopback interface is acceptable, especially when the host is a router.

> 
> I also haven't tested whether this same issue affects the generation of ICMP responses (e.g. TTL expired, packet too big). If it does, that seems like much more of a concern for using FreeBSD on real routers.

True. For IPv4 when generating the ICMP responses, IPv4 source address selection is also involved.

> 
> Thanks,
> - Felix
> 

Best regards,
Zhenlei
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.