From owner-freebsd-rc@FreeBSD.ORG Mon Feb 6 00:36:54 2012 Return-Path: Delivered-To: freebsd-rc@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 8661A106564A for ; Mon, 6 Feb 2012 00:36:54 +0000 (UTC) (envelope-from erdgeist@erdgeist.org) Received: from elektropost.org (elektropost.org [217.13.206.130]) by mx1.freebsd.org (Postfix) with ESMTP id 8D2018FC0A for ; Mon, 6 Feb 2012 00:36:52 +0000 (UTC) Received: (qmail 67813 invoked from network); 6 Feb 2012 00:40:33 -0000 Received: from elektropost.org (HELO elektropost.org) (erdgeist@erdgeist.org) by elektropost.org with CAMELLIA256-SHA encrypted SMTP; 6 Feb 2012 00:40:33 -0000 Message-ID: <4F2F209F.90309@erdgeist.org> Date: Mon, 06 Feb 2012 01:36:47 +0100 From: Dirk Engling User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.7; rv:9.0) Gecko/20111222 Thunderbird/9.0.1 MIME-Version: 1.0 To: freebsd-rc@freebsd.org References: <4F28B9D7.4010602@erdgeist.org> In-Reply-To: <4F28B9D7.4010602@erdgeist.org> X-Enigmail-Version: 1.3.5 Content-Type: multipart/mixed; boundary="------------000303090400080803030706" Subject: Re: Proposal ipv6_addrs_common X-BeenThere: freebsd-rc@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "Discussion related to /etc/rc.d design and implementation." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 06 Feb 2012 00:36:54 -0000 This is a multi-part message in MIME format. --------------000303090400080803030706 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 7bit On 01.02.12 05:04, Dirk Engling wrote: > The attached network6.subr is a shell script demonstrating the > ipv6_addrs_common function inside, for playing around one can use some > of the values the supplied get_if_var dummy function returns. Following up my shell script I patched my /etc/network.subr to properly work with the ipv6_addrs_IF variables while also removing some bugs in the interface configuration code. ipv4_addrs_common also has been patched to handle ranges in all octets. The patch at http://erdgeist.org/arts/software/network.subr_9.0.diff has been tested on my FreeBSD 9.0, fixing some bugs introduced in the rewrite of ifalias_up/ifalias_down for 9.0, as well. I also have back ported the code to work under FreeBSD 8.2, the patch against my 8.2-RELEASE's /etc/network.subr can be found here: http://erdgeist.org/arts/software/network.subr_8.2.diff Regards, erdgeist --------------000303090400080803030706 Content-Type: text/plain; x-mac-type="0"; x-mac-creator="0"; name="network.subr_8.2.diff" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="network.subr_8.2.diff" --- FreeBSD_8.2/network.subr 2012-01-21 12:52:45.000000000 +0000 +++ network.subr 2012-01-21 12:54:06.000000000 +0000 @@ -45,6 +45,7 @@ ifscript_up ${ifn} && cfg=0 ifconfig_up ${ifn} && cfg=0 ipv4_up ${ifn} && cfg=0 + ipv6_up ${ifn} && cfg=0 ipx_up ${ifn} && cfg=0 childif_create ${ifn} @@ -64,6 +65,7 @@ [ -z "$ifn" ] && return 1 ipx_down ${ifn} && cfg=0 + ipv6_down ${ifn} && cfg=0 ipv4_down ${ifn} && cfg=0 ifconfig_down ${ifn} && cfg=0 ifscript_down ${ifn} && cfg=0 @@ -307,6 +309,32 @@ ifconfig -n $1 > /dev/null 2>&1 } +# ipv6_up if +# add IPv6 addresses to the interface $if +ipv6_up() +{ + local _ret _if + _ret=1 + _if=$1 + ipv6if ${_if} || return 1 + + ipv6_addrs_common ${_if} alias && _ret=0 + return _ret +} + +# ifv6_down if +# remove IPv6 addresses from the interface $if +ifp6_down() +{ + local _ret _if + _ret=1 + _if=$1 + ipv6if ${_if} || return 1 + + ipv6_addrs_common ${_if} -alias && _ret=0 + return _ret +} + # ipv4_up if # add IPv4 addresses to the interface $if ipv4_up() @@ -326,6 +354,9 @@ ifexists ${_if} || return 1 + ifalias_down ${_if} && _ret=0 + ipv4_addrs_common ${_if} -alias && _ret=0 + inetList="`ifconfig ${_if} | grep 'inet ' | tr "\n" "$_ifs"`" oldifs="$IFS" @@ -343,49 +374,150 @@ done IFS="$oldifs" - ifalias_down ${_if} && _ret=0 - ipv4_addrs_common ${_if} -alias && _ret=0 - return $_ret } # ipv4_addrs_common if action -# Evaluate the ifconfig_if_ipv4 arguments for interface $if -# and use $action to add or remove IPv4 addresses from $if. +# Evaluate the ipv4_addrs_IF arguments for interface $if and +# use $action to add or remove IPv4 addresses from $if. ipv4_addrs_common() -{ +{ + local _ret _if _action _cidr _cidr_addr + local _ipaddr _netmask _ipleft _ipright _iplow _iphigh _ret=1 _if=$1 _action=$2 - + # get ipv4-addresses - cidr_addr=`get_if_var $_if ipv4_addrs_IF` - - for _cidr in ${cidr_addr}; do - _ipaddr=${_cidr%%/*} - _netmask="/"${_cidr##*/} - _range=${_ipaddr##*.} - _ipnet=${_ipaddr%.*} - _iplow=${_range%-*} - _iphigh=${_range#*-} - - # clear netmask when removing aliases - if [ "${_action}" = "-alias" ]; then - _netmask="" - fi - - _ipcount=${_iplow} - while [ "${_ipcount}" -le "${_iphigh}" ]; do - eval "ifconfig ${_if} ${_action} ${_ipnet}.${_ipcount}${_netmask}" - _ipcount=$((${_ipcount}+1)) - _ret=0 + _cidr_addr=`get_if_var $_if ipv4_addrs_IF` + + for _cidr in ${_cidr_addr}; do + _ipaddr="${_cidr%%/*}" + + if [ "${_ipaddr}" = "${_cidr}" -o "$_action" = "-alias" ]; then + unset _netmask + else + _netmask="/"${_cidr##*/} + fi + + _ipleft=${_ipaddr%-*} + _ipright=${_ipaddr#*-} - # only the first ipaddr in a subnet need the real netmask - if [ "${_action}" != "-alias" ]; then - _netmask="/32" + _iplow=${_ipleft##*.} + _iphigh=${_ipright%%.*} + _ipleft=${_ipleft%.*} + _ipright=${_ipright#*.} + + if [ "${_iphigh}" = "${_ipright}" ]; then + unset _ipright + else + _ipright=.$_ipright + fi + + if [ -n "${_iplow}" -a -n "${_iphigh}" ]; then + while [ ${_iplow} -le ${_iphigh} ]; do + ifconfig ${_if} ${_ipleft}.${_iplow}${_ipright}${_netmask} \ + ${_action} && _ret=0 + _iplow=$(( ${_iplow} + 1 )) + + # only the first ipaddr in a subnet need the real netmask + if [ "${_action}" != "-alias" ]; then + _netmask="/32" + fi + done + else + # no range or parse error, just pass to ifconfig + ifconfig ${_if} ${_ipaddr}${_netmask} ${_action} && _ret=0 + fi + done + + return $_ret +} + +# ipv6_addrs_common if action +# Evaluate the ipv6_addrs_IF arguments for interface $if and +# use $action to add or remove IPv6 addresses from $if. +ipv6_addrs_common() +{ + local _ret _if _action _cidr _cidr_addr + local _ipaddr _netmask _ipleft _ipright _iplow _iphigh + local _ipv6part _ipv4part + _ret=1 + _if=$1 + _action=$2 + + # get ipv6-addresses + _cidr_addr=`get_if_var $_if ipv6_addrs_IF` + + for _cidr in ${_cidr_addr}; do + _ipaddr="${_cidr%%/*}" + + if [ "${_ipaddr}" = "${_cidr}" -o "$_action" = "-alias" ]; then + unset _netmask + else + _netmask="/"${_cidr##*/} + fi + + # Handle v6 mapped v4 addresses below + if [ "${_ipaddr%:*.*.*.*}" = "${_ipaddr}" ]; then + _ipleft=${_ipaddr%-*} + _ipright=${_ipaddr#*-} + _iplow=${_ipleft##*:} + _iphigh=${_ipright%%:*} + _ipleft=${_ipleft%:*} + _ipright=${_ipright#*:} + + if [ "${_iphigh}" = "${_ipright}" ]; then + unset _ipright + else + _ipright=:$_ipright fi - done + + if [ -n "${_iplow}" -a -n "${_iphigh}" ]; then + while [ $(( 0x$_iplow )) -le $(( 0x$_iphigh )) ]; do + ifconfig ${_if} inet6 ${_ipleft}:${_iplow}${_ipright}\ +${_netmask} ${_action} && _ret=0 + + # Advance counter - in hex + _iplow=`printf %04x $(( 0x$_iplow + 1 ))` + done + else + # no range or parse error, just pass to ifconfig + ifconfig ${_if} inet6 ${_ipaddr}${_netmask} ${_action} && _ret=0 + fi + else + # v6 mapped v4 range + _ipv6part=${_ipaddr%:*} + _ipv4part=${_ipaddr##*:} + _ipleft=${_ipv4part%-*} + _ipright=${_ipv4part#*-} + + _iplow=${_ipleft##*.} + _iphigh=${_ipright%%.*} + _ipleft=${_ipv6part}:${_ipleft%.*} + _ipright=${_ipright#*.} + + if [ "${_iphigh}" = "${_ipright}" ]; then + unset _ipright + else + _ipright=.$_ipright + fi + + if [ -n "${_iplow}" -a -n "${_iphigh}" ]; then + while [ ${_iplow} -le ${_iphigh} ]; do + ifconfig ${_if} inet6 ${_ipleft}.${_iplow}${_ipright}\ +${_netmask} ${_action} && _ret=0 + + # Advance counter - in dec + _iplow=$(( ${_iplow} + 1 )) + done + else + # no range or parse error, just pass to ifconfig + ifconfig ${_if} inet6 ${_ipaddr}${_netmask} ${_action} && _ret=0 + fi + fi done + return $_ret } --------------000303090400080803030706 Content-Type: text/plain; x-mac-type="0"; x-mac-creator="0"; name="network.subr_9.0.diff" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="network.subr_9.0.diff" --- /usr/share/examples/etc/network.subr 2011-12-04 10:11:10.000000000 +0100 +++ network.subr 2012-01-30 11:49:39.000000000 +0100 @@ -444,6 +444,12 @@ return 0 fi + # True if ipv6_addrs_IF is defined. + _tmpargs=`get_if_var $_if ipv6_addrs_IF` + if [ -n "${_tmpargs}" ]; then + return 0 + fi + # backward compatibility: True if $ipv6_ifconfig_IF is defined. _tmpargs=`get_if_var $_if ipv6_ifconfig_IF` if [ -n "${_tmpargs}" ]; then @@ -538,7 +544,6 @@ fi fi ifalias_up ${_if} inet && _ret=0 - ipv4_addrs_common ${_if} alias && _ret=0 return $_ret } @@ -575,6 +580,10 @@ _ifs="^" _ret=1 + # remove all ip addresses configured by network.subr + ifalias_down ${_if} inet && _ret=0 + + # remove the rest inetList="`ifconfig ${_if} | grep 'inet ' | tr "\n" "$_ifs"`" oldifs="$IFS" @@ -586,15 +595,12 @@ _inet=`expr "$_inet" : '.*\(inet \([0-9]\{1,3\}\.\)\{3\}[0-9]\{1,3\}\).*'` IFS="$oldifs" - ifconfig ${_if} ${_inet} delete + ifconfig ${_if} ${_inet} delete && _ret=0 IFS="$_ifs" _ret=0 done IFS="$oldifs" - ifalias_down ${_if} inet && _ret=0 - ipv4_addrs_common ${_if} -alias && _ret=0 - return $_ret } @@ -636,43 +642,144 @@ } # ipv4_addrs_common if action -# Evaluate the ifconfig_if_ipv4 arguments for interface $if and +# Evaluate the ipv4_addrs_IF arguments for interface $if and # use $action to add or remove IPv4 addresses from $if. ipv4_addrs_common() { local _ret _if _action _cidr _cidr_addr - local _ipaddr _netmask _range _ipnet _iplow _iphigh _ipcount + local _ipaddr _netmask _ipleft _ipright _iplow _iphigh _ret=1 _if=$1 _action=$2 # get ipv4-addresses - cidr_addr=`get_if_var $_if ipv4_addrs_IF` + _cidr_addr=`get_if_var $_if ipv4_addrs_IF` + + for _cidr in ${_cidr_addr}; do + _ipaddr="${_cidr%%/*}" + + if [ "${_ipaddr}" = "${_cidr}" -o "$_action" = "-alias" ]; then + unset _netmask + else + _netmask="/"${_cidr##*/} + fi + + _ipleft=${_ipaddr%-*} + _ipright=${_ipaddr#*-} - for _cidr in ${cidr_addr}; do - _ipaddr=${_cidr%%/*} - _netmask="/"${_cidr##*/} - _range=${_ipaddr##*.} - _ipnet=${_ipaddr%.*} - _iplow=${_range%-*} - _iphigh=${_range#*-} - - # clear netmask when removing aliases - if [ "${_action}" = "-alias" ]; then - _netmask="" - fi - - _ipcount=${_iplow} - while [ "${_ipcount}" -le "${_iphigh}" ]; do - eval "ifconfig ${_if} ${_action} ${_ipnet}.${_ipcount}${_netmask}" - _ipcount=$((${_ipcount}+1)) - _ret=0 - - # only the first ipaddr in a subnet need the real netmask - if [ "${_action}" != "-alias" ]; then - _netmask="/32" + _iplow=${_ipleft##*.} + _iphigh=${_ipright%%.*} + _ipleft=${_ipleft%.*} + _ipright=${_ipright#*.} + + if [ "${_iphigh}" = "${_ipright}" ]; then + unset _ipright + else + _ipright=.$_ipright + fi + + if [ -n "${_iplow}" -a -n "${_iphigh}" ]; then + while [ ${_iplow} -le ${_iphigh} ]; do + ifconfig ${_if} ${_ipleft}.${_iplow}${_ipright}${_netmask} \ + ${_action} && _ret=0 + _iplow=$(( ${_iplow} + 1 )) + + # only the first ipaddr in a subnet need the real netmask + if [ "${_action}" != "-alias" ]; then + _netmask="/32" + fi + done + else + # no range or parse error, just pass to ifconfig + ifconfig ${_if} ${_ipaddr}${_netmask} ${_action} && _ret=0 + fi + done + + return $_ret +} + +# ipv6_addrs_common if action +# Evaluate the ipv6_addrs_IF arguments for interface $if and +# use $action to add or remove IPv6 addresses from $if. +ipv6_addrs_common() +{ + local _ret _if _action _cidr _cidr_addr + local _ipaddr _netmask _ipleft _ipright _iplow _iphigh + local _ipv6part _ipv4part + _ret=1 + _if=$1 + _action=$2 + + # get ipv6-addresses + _cidr_addr=`get_if_var $_if ipv6_addrs_IF` + + for _cidr in ${_cidr_addr}; do + _ipaddr="${_cidr%%/*}" + + if [ "${_ipaddr}" = "${_cidr}" -o "$_action" = "-alias" ]; then + unset _netmask + else + _netmask="/"${_cidr##*/} + fi + + # Handle v6 mapped v4 addresses below + if [ "${_ipaddr%:*.*.*.*}" = "${_ipaddr}" ]; then + _ipleft=${_ipaddr%-*} + _ipright=${_ipaddr#*-} + _iplow=${_ipleft##*:} + _iphigh=${_ipright%%:*} + _ipleft=${_ipleft%:*} + _ipright=${_ipright#*:} + + if [ "${_iphigh}" = "${_ipright}" ]; then + unset _ipright + else + _ipright=:$_ipright fi - done + + if [ -n "${_iplow}" -a -n "${_iphigh}" ]; then + while [ $(( 0x$_iplow )) -le $(( 0x$_iphigh )) ]; do + ifconfig ${_if} inet6 ${_ipleft}:${_iplow}${_ipright}\ +${_netmask} ${_action} && _ret=0 + + # Advance counter - in hex + _iplow=`printf %04x $(( 0x$_iplow + 1 ))` + done + else + # no range or parse error, just pass to ifconfig + ifconfig ${_if} inet6 ${_ipaddr}${_netmask} ${_action} && _ret=0 + fi + else + # v6 mapped v4 range + _ipv6part=${_ipaddr%:*} + _ipv4part=${_ipaddr##*:} + _ipleft=${_ipv4part%-*} + _ipright=${_ipv4part#*-} + + _iplow=${_ipleft##*.} + _iphigh=${_ipright%%.*} + _ipleft=${_ipv6part}:${_ipleft%.*} + _ipright=${_ipright#*.} + + if [ "${_iphigh}" = "${_ipright}" ]; then + unset _ipright + else + _ipright=.$_ipright + fi + + if [ -n "${_iplow}" -a -n "${_iphigh}" ]; then + while [ ${_iplow} -le ${_iphigh} ]; do + ifconfig ${_if} inet6 ${_ipleft}.${_iplow}${_ipright}\ +${_netmask} ${_action} && _ret=0 + + # Advance counter - in dec + _iplow=$(( ${_iplow} + 1 )) + done + else + # no range or parse error, just pass to ifconfig + ifconfig ${_if} inet6 ${_ipaddr}${_netmask} ${_action} && _ret=0 + fi + fi done return $_ret @@ -685,15 +792,18 @@ # ifalias_up() { - local _ret + local _ret _if _ret=1 + _if=$1 case "$2" in inet) - _ret=`ifalias_ipv4_up "$1"` + ifalias_ipv4_up ${_if} && _ret=0 + ipv4_addrs_common ${_if} alias && _ret=0 ;; inet6) - _ret=`ifalias_ipv6_up "$1"` + ifalias_ipv6_up ${_if} && _ret=0 + ipv6_addrs_common ${_if} alias && _ret=0 ;; esac @@ -776,15 +886,18 @@ # ifalias_down() { - local _ret + local _ret _if _ret=1 + _if=$1 case "$2" in inet) - _ret=`ifalias_ipv4_down "$1"` + ifalias_ipv4_down ${_if} && _ret=0 + ipv4_addrs_common ${_if} -alias && _ret=0 ;; inet6) - _ret=`ifalias_ipv6_down "$1"` + ifalias_ipv6_down ${_if} && _ret=0 + ipv6_addrs_common ${_if} -alias && _ret=0 ;; esac --------------000303090400080803030706--