> On Aug 5, 2025, at 10:09 PM, Felix <fe...@ffetc.net> 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


Reply via email to