Proposal ipv6_addrs_common
Dirk Engling
erdgeist at erdgeist.org
Mon Feb 6 00:36:54 UTC 2012
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
-------------- next part --------------
--- 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
}
-------------- next part --------------
--- /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
More information about the freebsd-rc
mailing list