Multi-homing, jails, and source address selection

Bjoern A. Zeeb bzeeb-lists at
Sat Mar 14 11:05:10 PDT 2009

On Thu, 12 Mar 2009, Stefan Bethke wrote:


> I'm having some trouble configuring a dual-homed jail host, running -current 
> from about 4 weeks ago.
> My machine has one external interface em0 connected to an /27 IPv4 network. 
> Additionally, I have a VPN interface tun0 provided by an OpenVPN instance 
> with a private /18 range.
> I'd like my jails to be dual-homed, with a public and a VPN address each. 
> Processes in the jail should pick the appropriate source address depending on 
> the destination address, so that the source address for a connection going to 
> a VPN address will be the jails' VPN address, and all other connections will 
> use the jails' public IP.
> I have a couple of questions that I can't seem to find answers to:
> How do I get the VPN addresses configured? tun0 won't accept them (since ptp 
> interfaces require a destination address).  If I use lo0, I seem to have 
> source address selection issues.  I've experimented with various setups, but 
> haven't found one that would work just right.  In the example below, if I 
> ping from foo to a VPN address, the source address is foo's public IP.  If I 
> run ping with -S10.0.63.3, the source address still is
> Is there any documentation on how source addresses are selected? I thought I 
> remembered that on unbound sockets the destination route would be used to 
> pick the first address of the outgoing interface as the source address; the 
> same address would be picked on connecting a socket.
> I'm currently running with this configuration in rc.conf:
> cloned_interfaces="tun0"
> ifconfig_em0=""
> ifconfig_tun0=""
> defaultrouter=""
> inetd_flags="-wW -a"
> static_routes="openvpn"
> route_openvpn=""
> jail_enable="YES"
> jail_set_hostname_allow="NO"
> jail_sysvipc_allow="YES"
> jail_devfs_enable="YES"
> jail_mount_enable="YES"
> jail_list="foo bar baz"
> jail_foo_rootdir="/jail/"
> jail_foo_hostname=""
> jail_foo_ip="em0|,lo0|"
> Any suggestions?

sys/netinet/in_pcb.c:in_pcbladdr() is your friend -

This is the case you are running into:
  * If the outgoing interface on the route found is not
  * a loopback interface, use the address from that interface.
  * In case of jails do those three steps:
  * 1. check if the interface address belongs to the jail. If so use it.
  * 2. check if we have any address on the outgoing interface
  *    belonging to this jail. If so use it.
  * 3. as a last resort return the 'default' jail address.

so you are hitting "3." .

I am not sure but I'd assume
 	ifconfig tun0 alias
would work, just not with the logic to create the IPs upon jail start
(and we will not accept patches to handle that;).

I'd also suggest to use telnet instead of ping to run tests as ping
imho has some private magic.


Bjoern A. Zeeb                      The greatest risk is not taking one.

More information about the freebsd-net mailing list