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