From owner-svn-src-all@FreeBSD.ORG Sat Feb 7 14:04:35 2009 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 7690E106564A; Sat, 7 Feb 2009 14:04:35 +0000 (UTC) (envelope-from bz@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 626F88FC0C; Sat, 7 Feb 2009 14:04:35 +0000 (UTC) (envelope-from bz@FreeBSD.org) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.3/8.14.3) with ESMTP id n17E4ZUH094021; Sat, 7 Feb 2009 14:04:35 GMT (envelope-from bz@svn.freebsd.org) Received: (from bz@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id n17E4ZHo094018; Sat, 7 Feb 2009 14:04:35 GMT (envelope-from bz@svn.freebsd.org) Message-Id: <200902071404.n17E4ZHo094018@svn.freebsd.org> From: "Bjoern A. Zeeb" Date: Sat, 7 Feb 2009 14:04:35 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-7@freebsd.org X-SVN-Group: stable-7 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r188287 - in stable/7: etc etc/defaults etc/periodic/weekly etc/rc.d share/man/man5 X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 07 Feb 2009 14:04:36 -0000 Author: bz Date: Sat Feb 7 14:04:35 2009 New Revision: 188287 URL: http://svn.freebsd.org/changeset/base/188287 Log: MFC: r187708 Update jail startup script for multi-IPv4/v6/no-IP jails. Note: this is only really necessary because of the ifconfig logic to add/remove the jail IPs upon start/stop. Consensus among simon and I is that the logic should really be factored out from the startup script and put into a proper management solution. - We now support starting of no-IP jails. - Implement jail__ip options to support both address familes with regard to ifconfig logic. - Implement _multi support suffix to the jail__ip option to configure additional addresses to avoid overlong, unreadbale jail__ip lines with lots of addresses. Modified: stable/7/etc/ (props changed) stable/7/etc/defaults/rc.conf stable/7/etc/periodic/weekly/ (props changed) stable/7/etc/rc.d/jail stable/7/share/man/man5/ (props changed) stable/7/share/man/man5/rc.conf.5 Modified: stable/7/etc/defaults/rc.conf ============================================================================== --- stable/7/etc/defaults/rc.conf Sat Feb 7 13:55:12 2009 (r188286) +++ stable/7/etc/defaults/rc.conf Sat Feb 7 14:04:35 2009 (r188287) @@ -615,14 +615,16 @@ jail_sysvipc_allow="NO" # Allow SystemV # each jail, specified in jail_list, with the following variables. # NOTES: # - replace 'example' with the jail's name. -# - except rootdir, hostname and ip, all of the following variables may be made -# global jail variables if you don't specify a jail name (ie. jail_interface). +# - except rootdir, hostname, ip and the _multi addresses, +# all of the following variables may be made global jail variables +# if you don't specify a jail name (ie. jail_interface, jail_devfs_ruleset). # #jail_example_rootdir="/usr/jail/default" # Jail's root directory #jail_example_hostname="default.domain.com" # Jail's hostname -#jail_example_ip="192.0.2.10" # Jail's IP number -#jail_example_interface="" # Interface to create the IP alias on -#jail_example_fib="0" # routing table for setfib(1) +#jail_example_interface="" # Jail's interface variable to create IP aliases on +#jail_example_fib="0" # Routing table for setfib(1) +#jail_example_ip="192.0.2.10,2001:db8::17" # Jail's primary IPv4 and IPv6 address +#jail_example_ip_multi0="2001:db8::10" # and another IPv6 address #jail_example_exec_start="/bin/sh /etc/rc" # command to execute in jail for starting #jail_example_exec_afterstart0="/bin/sh command" # command to execute after the one for # starting the jail. More than one can be Modified: stable/7/etc/rc.d/jail ============================================================================== --- stable/7/etc/rc.d/jail Sat Feb 7 13:55:12 2009 (r188286) +++ stable/7/etc/rc.d/jail Sat Feb 7 14:04:35 2009 (r188287) @@ -93,6 +93,7 @@ init_variables() debug "$_j mount enable: $_mount" debug "$_j hostname: $_hostname" debug "$_j ip: $_ip" + jail_show_addresses ${_j} debug "$_j interface: $_interface" debug "$_j fib: $_fib" debug "$_j root: $_rootdir" @@ -126,10 +127,6 @@ init_variables() if [ -z "${_rootdir}" ]; then err 3 "$name: No root directory has been defined for ${_j}" fi - if [ -z "${_ip}" ]; then - err 3 "$name: No IP address has been defined for ${_j}" - fi - } # set_sysctl rc_knob mib msg @@ -275,6 +272,208 @@ jail_mount_fstab() mount -a -F "${_fstab}" } +# jail_show_addresses jail +# Debug print the input for the given _multi aliases +# for a jail for init_variables(). +# +jail_show_addresses() +{ + local _j _type alias + _j="$1" + alias=0 + + if [ -z "${_j}" ]; then + warn "jail_show_addresses: you must specify a jail" + return + fi + + while : ; do + eval _addr=\"\$jail_${_j}_ip_multi${alias}\" + if [ -n "${_addr}" ]; then + debug "${_j} ip_multi${alias}: $_addr" + alias=$((${alias} + 1)) + else + break + fi + done +} + +# jail_extract_address argument +# The second argument is the string from one of the _ip +# or the _multi variables. In case of a comma separated list +# only one argument must be passed in at a time. +# The function alters the _type, _iface, _addr and _mask variables. +# +jail_extract_address() +{ + local _i + _i=$1 + + if [ -z "${_i}" ]; then + warn "jail_extract_address: called without input" + return + fi + + # Check if we have an interface prefix given and split into + # iFace and rest. + case "${_i}" in + *\|*) # ifN|.. prefix there + _iface=${_i%%|*} + _r=${_i##*|} + ;; + *) _iface="" + _r=${_i} + ;; + esac + + # In case the IP has no interface given, check if we have a global one. + _iface=${_iface:-${_interface}} + + # Set address, cut off any prefix/netmask/prefixlen. + _addr=${_r} + _addr=${_addr%%[/ ]*} + + # Theoretically we can return here if interface is not set, + # as we only care about the _mask if we call ifconfig. + # This is not done because we may want to santize IP addresses + # based on _type later, and optionally change the type as well. + + # Extract the prefix/netmask/prefixlen part by cutting off the address. + _mask=${_r} + _mask=`expr "${_mask}" : "${_addr}\(.*\)"` + + # Identify type {inet,inet6}. + case "${_addr}" in + *\.*\.*\.*) _type="inet" ;; + *:*) _type="inet6" ;; + *) warn "jail_extract_address: type not identified" + ;; + esac + + # Handle the special /netmask instead of /prefix or + # "netmask xxx" case for legacy IP. + # We do NOT support shortend class-full netmasks. + if [ "${_type}" = "inet" ]; then + case "${_mask}" in + /*\.*\.*\.*) _mask=" netmask ${_mask#/}" ;; + *) ;; + esac + + # In case _mask is still not set use /32. + _mask=${_mask:-/32} + + elif [ "${_type}" = "inet6" ]; then + # In case _maske is not set for IPv6, use /128. + _mask=${_mask:-/128} + fi +} + +# jail_handle_ips_option {add,del} input +# Handle a single argument imput which can be a comma separated +# list of addresses (theoretically with an option interface and +# prefix/netmask/prefixlen). +# +jail_handle_ips_option() +{ + local _x _action _type _i + _action=$1 + _x=$2 + + if [ -z "${_x}" ]; then + # No IP given. This can happen for the primary address + # of each address family. + return + fi + + # Loop, in case we find a comma separated list, we need to handle + # each argument on its own. + while [ ${#_x} -gt 0 ]; do + case "${_x}" in + *,*) # Extract the first argument and strip it off the list. + _i=`expr "${_x}" : '^\([^,]*\)'` + _x=`expr "${_x}" : "^[^,]*,\(.*\)"` + ;; + *) _i=${_x} + _x="" + ;; + esac + + _type="" + _iface="" + _addr="" + _mask="" + jail_extract_address "${_i}" + + # make sure we got an address. + case "${_addr}" in + "") continue ;; + *) ;; + esac + + # Append address to list of addresses for the jail command. + case "${_addrl}" in + "") _addrl="${_addr}" ;; + *) _addrl="${_addrl},${_addr}" ;; + esac + + # Configure interface alias if requested by a given interface + # and if we could correctly parse everything. + case "${_iface}" in + "") continue ;; + esac + case "${_type}" in + inet) ;; + inet6) ;; + *) warn "Could not determine address family. Not going" \ + "to ${_action} address '${_addr}' for ${_jail}." + continue + ;; + esac + case "${_action}" in + add) ifconfig ${_iface} ${_type} ${_addr}${_mask} alias + ;; + del) # When removing the IP, ignore the _mask. + ifconfig ${_iface} ${_type} ${_addr} -alias + ;; + esac + done +} + +# jail_ips {add,del} +# Extract the comma separated list of addresses and return them +# for the jail command. +# Handle more than one address via the _multi option as well. +# If an interface is given also add/remove an alias for the +# address with an optional netmask. +# +jail_ips() +{ + local _action + _action=$1 + + case "${_action}" in + add) ;; + del) ;; + *) warn "jail_ips: invalid action '${_action}'" + return + ;; + esac + + # Handle addresses. + jail_handle_ips_option ${_action} "${_ip}" + # Handle jail_xxx_ip_multi + alias=0 + while : ; do + eval _x=\"\$jail_${_jail}_ip_multi${alias}\" + case "${_x}" in + "") break ;; + *) jail_handle_ips_option ${_action} "${_x}" + alias=$((${alias} + 1)) + ;; + esac + done +} + jail_start() { echo -n 'Configuring jails:' @@ -296,9 +495,8 @@ jail_start() echo -n " [${_hostname} already running (/var/run/jail_${_jail}.id exists)]" continue; fi - if [ -n "${_interface}" ]; then - ifconfig ${_interface} alias ${_ip} netmask 255.255.255.255 - fi + _addrl="" + jail_ips "add" if [ -n "${_fib}" ]; then _setfib="setfib -F '${_fib}'" else @@ -358,7 +556,7 @@ jail_start() fi _tmp_jail=${_tmp_dir}/jail.$$ eval ${_setfib} jail ${_flags} -i ${_rootdir} ${_hostname} \ - ${_ip} ${_exec_start} > ${_tmp_jail} 2>&1 + \"${_addrl}\" ${_exec_start} > ${_tmp_jail} 2>&1 if [ "$?" -eq 0 ] ; then _jail_id=$(head -1 ${_tmp_jail}) @@ -379,9 +577,7 @@ jail_start() echo ${_jail_id} > /var/run/jail_${_jail}.id else jail_umount_fs - if [ -n "${_interface}" ]; then - ifconfig ${_interface} -alias ${_ip} - fi + jail_ips "del" echo " cannot start jail \"${_jail}\": " tail +2 ${_tmp_jail} fi @@ -410,9 +606,7 @@ jail_stop() jail_umount_fs echo -n " $_hostname" fi - if [ -n "${_interface}" ]; then - ifconfig ${_interface} -alias ${_ip} - fi + jail_ips "del" rm /var/run/jail_${_jail}.id else echo " cannot stop jail ${_jail}. No jail id in /var/run" Modified: stable/7/share/man/man5/rc.conf.5 ============================================================================== --- stable/7/share/man/man5/rc.conf.5 Sat Feb 7 13:55:12 2009 (r188286) +++ stable/7/share/man/man5/rc.conf.5 Sat Feb 7 14:04:35 2009 (r188287) @@ -24,7 +24,7 @@ .\" .\" $FreeBSD$ .\" -.Dd January 9, 2009 +.Dd January 25, 2009 .Dt RC.CONF 5 .Os .Sh NAME @@ -3398,8 +3398,38 @@ Set to the fully qualified domain name ( .It Va jail_ Ns Ao Ar jname Ac Ns Va _ip .Pq Vt str Unset by default. -Set to the IP address assigned to jail -.Va jname . +Set to the (primary) IPv4 and/or IPv6 address(es) assigned to the jail. +The argument can be a sole address or a comma separated list of addresses. +Additionally each address can be prefixed by the name of an interface +followed by a pipe to overwrite +.Va jail_ Ns Ao Ar jname Ac Ns Va _interface +or +.Va jail_interface +and/or suffixed by a netmask, prefixlen or prefix. +In case no netmask, prefixlen or prefix is given, +.Sq /32 +will be used for IPv4 and +.Sq /128 +will be used for an IPv6 address. +If no address is given for the jail then the jail will be started with +no networking support. +.It Va jail_ Ns Ao Ar jname Ac Ns Va _ip_multi Ns Aq Ar n +.Pq Vt str +Unset by default. +Set additional IPv4 and/or IPv6 address(es) assigned to the jail. +The sequence starts with +.Dq Li _multi0 +and the numbers have to be strictly ascending. +These entries follow the same syntax as their primary +.Va jail_ Ns Ao Ar jname Ac Ns Va _ip +entry. +The order of the entries can be important as the first address for +each address family found will be the primary address of the jail. +See +.Va ip-addresses +option in +.Xr jail 8 +for more details. .It Va jail_ Ns Ao Ar jname Ac Ns Va _flags .Pq Vt str Set to