Interface address sourced packets go thru default gateway on another interface

Bruce M. Simpson bms at FreeBSD.org
Fri Nov 16 03:10:54 PST 2007


Brian Hawk wrote:
> Then what would be the reason to bind a connection to a specific 
> source address? We do
> ping -S A.B.C.D x.y.z.t
> to make ping send packets to x.y.z.t over A.B.C.D's interface (and 
> source address) or
> telnet -s A.B.C.D x.y.z.t
>
> I believe binding an IP's source address to an interface address 
> (instead of INADDR_ANY) is to make packets go out from *that* 
> interface, not the default gw.

Nope, this has never been the case.

Binding a socket to an address does just that -- it does NOT bind a 
socket to an interface.

The source address selection during an accept() or bind() is chosen 
based on the address provided to the bind() call, or the address from 
which the SYN originated which your code is accept()-ing; the kernel 
will then choose the address 'nearest' to the node which sent the SYN 
for further communication, by doing a route lookup.

During ip_output() the actual interface pointer lookup will take place 
based on the destination address. Then and only then is the actual 
interface selected.

This is a set of behaviours which will have to change in netinet in 
order to support stuff like bind-to-interface, scoped addresses and the 
169.254.0.0/16 link-local block correctly -- we SHOULD be looking at the 
address to which the socket is bound before doing anything (compare with 
Linux's SO_BINDTODEVICE option; which causes layer pollution and I would 
suggest should NOT be implemented in the same way in FreeBSD).

As other contributors have suggested, if you really need source routing, 
use pf or similar for that. I believe ipf also supports route-to on the 
outbound.

cheers,
BMS


More information about the freebsd-net mailing list