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
--- 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
 }
 
--- /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
 
_______________________________________________
[email protected] mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-rc
To unsubscribe, send any mail to "[email protected]"

Reply via email to